15
15
package jsonrpc_test
16
16
17
17
import (
18
+ "encoding/json"
18
19
"fmt"
20
+ "io"
19
21
"testing"
20
22
21
23
"github.com/digitalocean/go-openvswitch/ovsdb/internal/jsonrpc"
22
24
"github.com/google/go-cmp/cmp"
23
25
)
24
26
25
- func TestConnExecuteBadSequence (t * testing.T ) {
26
- req := jsonrpc.Request {
27
- ID : 10 ,
28
- Method : "test" ,
29
- }
30
-
31
- c , done := jsonrpc .TestConn (t , func (_ jsonrpc.Request ) jsonrpc.Response {
32
- return jsonrpc.Response {
33
- // Bad sequence.
34
- ID : 1 ,
35
- }
36
- })
27
+ func TestConnSendNoRequestID (t * testing.T ) {
28
+ c , _ , done := jsonrpc .TestConn (t , nil )
37
29
defer done ()
38
30
39
- if err := c .Execute ( req , nil ); err == nil {
31
+ if err := c .Send (jsonrpc. Request {} ); err == nil {
40
32
t .Fatal ("expected an error, but none occurred" )
41
33
}
42
34
}
43
35
44
- func TestConnExecuteError (t * testing.T ) {
36
+ func TestConnReceiveEOF (t * testing.T ) {
37
+ c := jsonrpc .NewConn (& eofReadWriteCloser {}, nil )
38
+
39
+ // Conn should not mask io.EOF.
40
+ _ , err := c .Receive ()
41
+ if err != io .EOF {
42
+ t .Fatalf ("unexpected error: %v" , err )
43
+ }
44
+ }
45
+
46
+ func TestConnSendReceiveError (t * testing.T ) {
45
47
// TODO(mdlayher): what does this actually look like?
46
48
type rpcError struct {
47
49
Details string
48
50
}
49
51
50
- c , done := jsonrpc .TestConn (t , func (_ jsonrpc.Request ) jsonrpc.Response {
52
+ c , _ , done := jsonrpc .TestConn (t , func (_ jsonrpc.Request ) jsonrpc.Response {
51
53
return jsonrpc.Response {
52
- ID : 10 ,
54
+ ID : intPtr ( 10 ) ,
53
55
Error : rpcError {
54
56
Details : "some error" ,
55
57
},
56
58
}
57
59
})
58
60
defer done ()
59
61
60
- if err := c .Execute (jsonrpc.Request {ID : 10 }, nil ); err == nil {
62
+ if err := c .Send (jsonrpc.Request {ID : 10 }); err != nil {
63
+ t .Fatalf ("failed to send request: %v" , err )
64
+ }
65
+
66
+ res , err := c .Receive ()
67
+ if err != nil {
68
+ t .Fatalf ("failed to receive response: %v" , err )
69
+ }
70
+
71
+ if err := res .Err (); err == nil {
61
72
t .Fatal ("expected an error, but none occurred" )
62
73
}
63
74
}
64
75
65
- func TestConnExecuteOK (t * testing.T ) {
76
+ func TestConnSendReceiveOK (t * testing.T ) {
66
77
req := jsonrpc.Request {
67
78
Method : "hello" ,
68
79
Params : []interface {}{"world" },
80
+ ID : 1 ,
69
81
}
70
82
71
83
type message struct {
@@ -76,30 +88,128 @@ func TestConnExecuteOK(t *testing.T) {
76
88
Message : "hello world" ,
77
89
}
78
90
79
- c , done := jsonrpc .TestConn (t , func (got jsonrpc.Request ) jsonrpc.Response {
80
- req .ID = 1
81
-
91
+ c , _ , done := jsonrpc .TestConn (t , func (got jsonrpc.Request ) jsonrpc.Response {
82
92
if diff := cmp .Diff (req , got ); diff != "" {
83
93
panicf ("unexpected request (-want +got):\n %s" , diff )
84
94
}
85
95
86
96
return jsonrpc.Response {
87
- ID : 1 ,
88
- Result : want ,
97
+ ID : intPtr ( 1 ) ,
98
+ Result : mustMarshalJSON ( t , want ) ,
89
99
}
90
100
})
91
101
defer done ()
92
102
103
+ if err := c .Send (req ); err != nil {
104
+ t .Fatalf ("failed to send request: %v" , err )
105
+ }
106
+
107
+ res , err := c .Receive ()
108
+ if err != nil {
109
+ t .Fatalf ("failed to receive response: %v" , err )
110
+ }
111
+
112
+ if err := res .Err (); err != nil {
113
+ t .Fatalf ("request failed: %v" , err )
114
+ }
115
+
93
116
var out message
94
- if err := c . Execute ( req , & out ); err != nil {
95
- t .Fatalf ("failed to execute : %v" , err )
117
+ if err := json . Unmarshal ( res . Result , & out ); err != nil {
118
+ t .Fatalf ("failed to unmarshal JSON : %v" , err )
96
119
}
97
120
98
121
if diff := cmp .Diff (want , out ); diff != "" {
99
122
t .Fatalf ("unexpected response (-want +got):\n %s" , diff )
100
123
}
101
124
}
102
125
126
+ func TestConnSendReceiveNotificationsOK (t * testing.T ) {
127
+ const id = 10
128
+
129
+ req := jsonrpc.Request {
130
+ ID : id ,
131
+ Method : "monitor" ,
132
+ Params : []interface {}{"Open_vSwitch" },
133
+ }
134
+
135
+ res := jsonrpc.Response {
136
+ ID : intPtr (id ),
137
+ Result : mustMarshalJSON (t , "some bytes" ),
138
+ }
139
+
140
+ c , notifC , done := jsonrpc .TestConn (t , func (got jsonrpc.Request ) jsonrpc.Response {
141
+ if diff := cmp .Diff (req , got ); diff != "" {
142
+ panicf ("unexpected request (-want +got):\n %s" , diff )
143
+ }
144
+
145
+ return res
146
+ })
147
+ defer done ()
148
+
149
+ note := & jsonrpc.Response {
150
+ Method : "notify" ,
151
+ }
152
+ notifC <- note
153
+ notifC <- note
154
+
155
+ if err := c .Send (req ); err != nil {
156
+ t .Fatalf ("failed to send request: %v" , err )
157
+ }
158
+
159
+ var responses , notes int
160
+ for i := 0 ; i < 3 ; i ++ {
161
+ res , err := c .Receive ()
162
+ if err != nil {
163
+ t .Fatalf ("failed to receive response: %v" , err )
164
+ }
165
+
166
+ if res .ID != nil {
167
+ responses ++
168
+ if diff := cmp .Diff (req .ID , * res .ID ); diff != "" {
169
+ t .Fatalf ("unexpected response request ID (-want +got):\n %s" , diff )
170
+ }
171
+
172
+ continue
173
+ }
174
+
175
+ notes ++
176
+ if diff := cmp .Diff (note .Method , res .Method ); diff != "" {
177
+ t .Fatalf ("unexpected notification method (-want +got):\n %s" , diff )
178
+ }
179
+ }
180
+
181
+ if diff := cmp .Diff (1 , responses ); diff != "" {
182
+ t .Fatalf ("unexpected number of responses (-want +got):\n %s" , diff )
183
+ }
184
+
185
+ if diff := cmp .Diff (2 , notes ); diff != "" {
186
+ t .Fatalf ("unexpected number of notifications (-want +got):\n %s" , diff )
187
+ }
188
+ }
189
+
190
+ func mustMarshalJSON (t * testing.T , v interface {}) []byte {
191
+ t .Helper ()
192
+
193
+ b , err := json .Marshal (v )
194
+ if err != nil {
195
+ t .Fatalf ("failed to marshal JSON: %v" , err )
196
+ }
197
+
198
+ return b
199
+ }
200
+
201
+ func intPtr (i int ) * int {
202
+ return & i
203
+ }
204
+
103
205
func panicf (format string , a ... interface {}) {
104
206
panic (fmt .Sprintf (format , a ... ))
105
207
}
208
+
209
+ type eofReadWriteCloser struct {
210
+ io.ReadWriteCloser
211
+ }
212
+
213
+ func (rwc * eofReadWriteCloser ) Read (b []byte ) (int , error ) {
214
+ return 0 , io .EOF
215
+ }
0 commit comments