1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
// Copyright (C) MongoDB, Inc. 2014-present.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
package mongoreplay
import (
"bytes"
"net"
"sync"
"time"
mgo "github.com/10gen/llmgo"
)
// SessionStub mocks an MongoSession by implementing the AcquireSocketPrivate
// method. It allows for tests to pass around a struct with stubbed fields that
// can then be read later for testing.
type SessionStub struct {
startup sync.Once
mgo.MongoSession
connection ConnStub
socket *mgo.MongoSocket
}
// ConnStub mocks the connection used by an mgo session. It implements the
// net.Conn interface so that it may be used as a connection for testing in
// llmgo It contains a write buffer and a read buffer. It writes into the write
// buffer, and reads from the read buffer so that its ends may be given in
// reverse to another function. (i.e., another function can write to its read
// buffer and it will receive this as incoming data)
type ConnStub struct {
closed bool
readBuffer *bytes.Buffer
writeBuffer *bytes.Buffer
}
func (conn *ConnStub) Read(b []byte) (n int, err error) {
return conn.readBuffer.Read(b)
}
func (conn *ConnStub) Write(b []byte) (n int, err error) {
return conn.writeBuffer.Write(b)
}
// Close doesn't actually do anything, and is here to implement net.Conn.
func (conn *ConnStub) Close() error {
return nil
}
// LocalAddr doesn't actually do anything, and is here to implement net.Conn.
func (conn *ConnStub) LocalAddr() net.Addr {
return nil
}
// RemoteAddr doesn't actually do anything, and is here to implement net.Conn.
func (conn *ConnStub) RemoteAddr() net.Addr {
return nil
}
// SetDeadline doesn't actually do anything, and is here to implement net.Conn.
func (conn *ConnStub) SetDeadline(t time.Time) error {
return nil
}
// SetReadDeadline doesn't actually do anything, and is here to implement net.Conn.
func (conn *ConnStub) SetReadDeadline(t time.Time) error {
return nil
}
// SetWriteDeadline doesn't actually do anything, and is here to implement net.Conn.
func (conn *ConnStub) SetWriteDeadline(t time.Time) error {
return nil
}
// newTwoSidedConn makes two ConnStub's which use the same buffers but in
// opposite roles. The read end of one buffer is handed to the other connection
// as the write end and vice versa
func newTwoSidedConn() (conn1 ConnStub, conn2 ConnStub) {
buffer1 := &bytes.Buffer{}
buffer2 := &bytes.Buffer{}
conn1 = ConnStub{false, buffer1, buffer2}
conn2 = ConnStub{false, buffer2, buffer1}
return conn1, conn2
}
// AcquireSocketPrivate is an implementation of MongoSession's function that
// allows for the a stubbed connection to the passed to the other operations of
// llmgo for testing
func (session *SessionStub) AcquireSocketPrivate(slaveOk bool) (*mgo.MongoSocket, error) {
session.startup.Do(func() {
session.socket = mgo.NewDumbSocket(&session.connection)
})
return session.socket, nil
}
|