-
Notifications
You must be signed in to change notification settings - Fork 122
/
engine_test.go
146 lines (124 loc) · 3.24 KB
/
engine_test.go
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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package ib
import (
"errors"
"flag"
"os"
"reflect"
"testing"
"time"
)
var (
gwURL = flag.String("gw", "", "Gateway URL")
noEngineReuse = flag.Bool("no-engine-reuse", false, "Don't keep reusing the engine; each test case gets its own engine.")
)
func getGatewayURL() string {
if *gwURL != "" {
return *gwURL
}
if url := os.Getenv("GATEWAY_URL"); url != "" {
return url
}
return "localhost:4002"
}
func (e *Engine) expect(t *testing.T, seconds int, ch chan Reply, expected []IncomingMessageID) (Reply, error) {
for {
select {
case <-time.After(time.Duration(seconds) * time.Second):
return nil, errors.New("Timeout waiting")
case v := <-ch:
if v.code() == 0 {
t.Fatalf("don't know message '%v'", v)
}
for _, code := range expected {
if v.code() == code {
return v, nil
}
}
// wrong message received
t.Logf("received message '%v' of type '%v'\n",
v, reflect.ValueOf(v).Type())
}
}
}
// private variable for mantaining engine reuse in test
// use TestEngine instead of this
var testEngine *Engine
// Engine for test reuse.
//
// Unless the test runner is passed the -no-engine-reuse flag, this will keep
// reusing the same engine.
func NewTestEngine(t *testing.T) *Engine {
if testEngine == nil {
opts := EngineOptions{Gateway: getGatewayURL()}
if os.Getenv("CI") != "" || os.Getenv("IB_ENGINE_DUMP") != "" {
opts.DumpConversation = true
}
engine, err := NewEngine(opts)
if err != nil {
t.Fatalf("cannot connect engine: %s", err)
}
if *noEngineReuse {
t.Log("created new engine, no reuse")
return engine
}
t.Log("created engine for reuse")
testEngine = engine
return engine
}
if testEngine.State() != EngineReady {
t.Fatalf("engine %s not ready (did a prior test Stop() rather than ConditionalStop() ?)", testEngine.ConnectionInfo())
}
t.Logf("reusing engine %s; state: %v", testEngine.ConnectionInfo(), testEngine.State())
return testEngine
}
// ConditionalStop will actually do a stop only if the flag -no-engine-reuse is active
func (e *Engine) ConditionalStop(t *testing.T) {
if *noEngineReuse {
t.Log("no engine reuse, stopping engine")
e.Stop()
t.Logf("engine state: %d", e.State())
}
}
func TestConnect(t *testing.T) {
opts := EngineOptions{Gateway: getGatewayURL()}
if os.Getenv("CI") != "" || os.Getenv("IB_ENGINE_DUMP") != "" {
opts.DumpConversation = true
}
engine, err := NewEngine(opts)
if err != nil {
t.Fatalf("cannot connect engine: %s", err)
}
defer engine.Stop()
if engine.State() != EngineReady {
t.Fatalf("engine is not ready")
}
if engine.serverTime.IsZero() {
t.Fatalf("server time not provided")
}
var states = make(chan EngineState)
engine.SubscribeState(states)
// stop the engine in 100 ms
go func() {
time.Sleep(100 * time.Millisecond)
engine.Stop()
}()
newState := <-states
if newState != EngineExitNormal {
t.Fatalf("engine state change error")
}
err = engine.FatalError()
if err != nil {
t.Fatalf("engine reported an error: %v", err)
}
}
func logreply(t *testing.T, reply Reply, err error) {
if reply == nil {
t.Logf("received reply nil")
} else {
t.Logf("received reply '%v' of type %v", reply, reflect.ValueOf(reply).Type())
}
if err != nil {
t.Logf(" (error: '%v')", err)
}
t.Logf("\n")
}