blob: a4f98dd8fd0e2c46e55723f5da1bc327d9da68c1 [file] [log] [blame]
Jiri Simsa78b646f2014-10-08 10:23:05 -07001package app
2
3import (
Jiri Simsa78b646f2014-10-08 10:23:05 -07004 "fmt"
5 "reflect"
6 "testing"
7
Jiri Simsa22b87ac2014-12-25 20:59:13 -08008 "v.io/core/veyron2"
Matt Rosencrantz306d9902015-01-10 17:46:07 -08009 "v.io/core/veyron2/context"
Jiri Simsa22b87ac2014-12-25 20:59:13 -080010 "v.io/core/veyron2/ipc"
11 "v.io/core/veyron2/naming"
12 "v.io/core/veyron2/options"
13 "v.io/core/veyron2/rt"
14 "v.io/core/veyron2/security"
15 "v.io/core/veyron2/vdl"
16 "v.io/core/veyron2/vdl/vdlroot/src/signature"
17 "v.io/core/veyron2/verror2"
Jiri Simsa11277162014-12-25 15:50:27 -080018 "v.io/wspr/veyron/services/wsprd/lib"
19 "v.io/wspr/veyron/services/wsprd/lib/testwriter"
Jiri Simsa78b646f2014-10-08 10:23:05 -070020
Bogdan Caprita38773f32015-01-08 13:47:57 -080021 "v.io/core/veyron/lib/testutil"
Jiri Simsa22b87ac2014-12-25 20:59:13 -080022 tsecurity "v.io/core/veyron/lib/testutil/security"
23 "v.io/core/veyron/profiles"
24 "v.io/core/veyron/runtimes/google/ipc/stream/proxy"
25 vsecurity "v.io/core/veyron/security"
26 mounttable "v.io/core/veyron/services/mounttable/lib"
Jiri Simsa78b646f2014-10-08 10:23:05 -070027)
28
Ankure7889242014-10-20 18:37:29 -070029var (
30 testPrincipalBlessing = "test"
31 testPrincipal = newPrincipal(testPrincipalBlessing)
Matt Rosencrantz306d9902015-01-10 17:46:07 -080032 gctx *context.T
Ankure7889242014-10-20 18:37:29 -070033)
34
Matt Rosencrantz2ffef742014-12-04 09:51:40 -080035func init() {
36 var err error
Matt Rosencrantz306d9902015-01-10 17:46:07 -080037 r, err := rt.New()
38 if err != nil {
Matt Rosencrantz2ffef742014-12-04 09:51:40 -080039 panic(err)
40 }
Matt Rosencrantz306d9902015-01-10 17:46:07 -080041 gctx = r.NewContext()
Matt Rosencrantz2ffef742014-12-04 09:51:40 -080042}
43
Ankure7889242014-10-20 18:37:29 -070044// newBlessedPrincipal returns a new principal that has a blessing from the
45// provided runtime's principal which is set on its BlessingStore such
46// that it is revealed to all clients and servers.
Matt Rosencrantz306d9902015-01-10 17:46:07 -080047func newBlessedPrincipal(ctx *context.T) security.Principal {
Ankure7889242014-10-20 18:37:29 -070048 p, err := vsecurity.NewPrincipal()
49 if err != nil {
50 panic(err)
51 }
Matt Rosencrantz306d9902015-01-10 17:46:07 -080052
53 principal := veyron2.GetPrincipal(ctx)
54 b, err := principal.Bless(p.PublicKey(), principal.BlessingStore().Default(), "delegate", security.UnconstrainedUse())
Ankure7889242014-10-20 18:37:29 -070055 if err != nil {
56 panic(err)
57 }
58 tsecurity.SetDefaultBlessings(p, b)
59 return p
60}
61
62// newPrincipal returns a new principal that has a self-blessing with
63// the provided extension 'selfBlessing' which is set on its BlessingStore
64// such that it is revealed to all clients and servers.
65func newPrincipal(selfBlessing string) security.Principal {
66 p, err := vsecurity.NewPrincipal()
67 if err != nil {
68 panic(err)
69 }
70 b, err := p.BlessSelf(selfBlessing)
71 if err != nil {
72 panic(err)
73 }
74 tsecurity.SetDefaultBlessings(p, b)
75 return p
76}
Jiri Simsa78b646f2014-10-08 10:23:05 -070077
78type simpleAdder struct{}
79
Benjamin Prosnitza2ac3b32014-12-12 11:40:31 -080080func (s simpleAdder) Add(_ ipc.ServerContext, a, b int32) (int32, error) {
Jiri Simsa78b646f2014-10-08 10:23:05 -070081 return a + b, nil
82}
83
Benjamin Prosnitza2ac3b32014-12-12 11:40:31 -080084func (s simpleAdder) Divide(_ ipc.ServerContext, a, b int32) (int32, error) {
Jiri Simsa78b646f2014-10-08 10:23:05 -070085 if b == 0 {
Mike Burrowsb6689c22014-10-08 11:14:15 -070086 return 0, verror2.Make(verror2.BadArg, nil, "div 0")
Jiri Simsa78b646f2014-10-08 10:23:05 -070087 }
88 return a / b, nil
89}
90
91func (s simpleAdder) StreamingAdd(call ipc.ServerCall) (int32, error) {
92 total := int32(0)
93 var value int32
94 for err := call.Recv(&value); err == nil; err = call.Recv(&value) {
95 total += value
96 call.Send(total)
97 }
98 return total, nil
99}
100
Todd Wang72ef57b2015-01-08 10:23:21 -0800101var simpleAddrSig = signature.Interface{
102 Doc: "The empty interface contains methods not attached to any interface.",
103 Methods: []signature.Method{
104 {
105 Name: "Add",
106 InArgs: []signature.Arg{{Type: vdl.Int32Type}, {Type: vdl.Int32Type}},
Benjamin Prosnitz518af1e2015-01-20 14:20:10 -0800107 OutArgs: []signature.Arg{{Type: vdl.Int32Type}},
Todd Wang72ef57b2015-01-08 10:23:21 -0800108 },
109 {
110 Name: "Divide",
111 InArgs: []signature.Arg{{Type: vdl.Int32Type}, {Type: vdl.Int32Type}},
Benjamin Prosnitz518af1e2015-01-20 14:20:10 -0800112 OutArgs: []signature.Arg{{Type: vdl.Int32Type}},
Todd Wang72ef57b2015-01-08 10:23:21 -0800113 },
114 {
115 Name: "StreamingAdd",
Benjamin Prosnitz518af1e2015-01-20 14:20:10 -0800116 OutArgs: []signature.Arg{{Type: vdl.Int32Type}},
Todd Wang72ef57b2015-01-08 10:23:21 -0800117 InStream: &signature.Arg{Type: vdl.AnyType},
118 OutStream: &signature.Arg{Type: vdl.AnyType},
Jiri Simsa78b646f2014-10-08 10:23:05 -0700119 },
Benjamin Prosnitza2ac3b32014-12-12 11:40:31 -0800120 },
Jiri Simsa78b646f2014-10-08 10:23:05 -0700121}
122
123func startAnyServer(servesMT bool, dispatcher ipc.Dispatcher) (ipc.Server, naming.Endpoint, error) {
124 // Create a new server instance.
Matt Rosencrantz306d9902015-01-10 17:46:07 -0800125 s, err := veyron2.NewServer(gctx, options.ServesMountTable(servesMT))
Jiri Simsa78b646f2014-10-08 10:23:05 -0700126 if err != nil {
127 return nil, nil, err
128 }
129
Cosmos Nicolaoud48178c2014-12-15 22:51:52 -0800130 endpoints, err := s.Listen(profiles.LocalListenSpec)
Jiri Simsa78b646f2014-10-08 10:23:05 -0700131 if err != nil {
132 return nil, nil, err
133 }
134
Cosmos Nicolaou4619b1f2014-11-05 07:23:13 -0800135 if err := s.ServeDispatcher("", dispatcher); err != nil {
Jiri Simsa78b646f2014-10-08 10:23:05 -0700136 return nil, nil, err
137 }
Cosmos Nicolaoud48178c2014-12-15 22:51:52 -0800138 return s, endpoints[0], nil
Jiri Simsa78b646f2014-10-08 10:23:05 -0700139}
140
141func startAdderServer() (ipc.Server, naming.Endpoint, error) {
Bogdan Caprita38773f32015-01-08 13:47:57 -0800142 return startAnyServer(false, testutil.LeafDispatcher(simpleAdder{}, nil))
Jiri Simsa78b646f2014-10-08 10:23:05 -0700143}
144
145func startProxy() (*proxy.Proxy, error) {
146 rid, err := naming.NewRoutingID()
147 if err != nil {
148 return nil, err
149 }
150 return proxy.New(rid, nil, "tcp", "127.0.0.1:0", "")
151}
152
153func startMountTableServer() (ipc.Server, naming.Endpoint, error) {
154 mt, err := mounttable.NewMountTable("")
155 if err != nil {
156 return nil, nil, err
157 }
158 return startAnyServer(true, mt)
159}
160
Jiri Simsa78b646f2014-10-08 10:23:05 -0700161func TestGetGoServerSignature(t *testing.T) {
162 s, endpoint, err := startAdderServer()
163 if err != nil {
164 t.Errorf("unable to start server: %v", err)
165 t.Fail()
166 return
167 }
168 defer s.Stop()
Cosmos Nicolaou408de0f2014-10-24 13:32:29 -0700169 spec := profiles.LocalListenSpec
Jiri Simsa78b646f2014-10-08 10:23:05 -0700170 spec.Proxy = "mockVeyronProxyEP"
Matt Rosencrantz306d9902015-01-10 17:46:07 -0800171 controller, err := NewController(nil, nil, &spec, nil, options.RuntimePrincipal{newBlessedPrincipal(gctx)})
Jiri Simsa78b646f2014-10-08 10:23:05 -0700172
173 if err != nil {
Ankure7889242014-10-20 18:37:29 -0700174 t.Fatalf("Failed to create controller: %v", err)
Jiri Simsa78b646f2014-10-08 10:23:05 -0700175 }
Matt Rosencrantz306d9902015-01-10 17:46:07 -0800176 sig, err := controller.getSignature(gctx, "/"+endpoint.String())
Jiri Simsa78b646f2014-10-08 10:23:05 -0700177 if err != nil {
Ankure7889242014-10-20 18:37:29 -0700178 t.Fatalf("Failed to get signature: %v", err)
Jiri Simsa78b646f2014-10-08 10:23:05 -0700179 }
Todd Wang72ef57b2015-01-08 10:23:21 -0800180 if got, want := len(sig), 2; got != want {
181 t.Fatalf("got signature %#v len %d, want %d", sig, got, want)
182 }
183 if got, want := sig[0], simpleAddrSig; !reflect.DeepEqual(got, want) {
184 t.Errorf("got sig[0] %#v, want: %#v", got, want)
185 }
186 if got, want := sig[1].Name, "__Reserved"; got != want {
187 t.Errorf("got sig[1].Name %#v, want: %#v", got, want)
Jiri Simsa78b646f2014-10-08 10:23:05 -0700188 }
189}
190
191type goServerTestCase struct {
Benjamin Prosnitza2ac3b32014-12-12 11:40:31 -0800192 method string
193 inArgs []interface{}
194 numOutArgs int32
195 streamingInputs []interface{}
196 expectedStream []lib.Response
197 expectedError error
Jiri Simsa78b646f2014-10-08 10:23:05 -0700198}
199
200func runGoServerTestCase(t *testing.T, test goServerTestCase) {
201 s, endpoint, err := startAdderServer()
202 if err != nil {
203 t.Errorf("unable to start server: %v", err)
204 t.Fail()
205 return
206 }
207 defer s.Stop()
Cosmos Nicolaou408de0f2014-10-24 13:32:29 -0700208
209 spec := profiles.LocalListenSpec
Jiri Simsa78b646f2014-10-08 10:23:05 -0700210 spec.Proxy = "mockVeyronProxyEP"
Matt Rosencrantz306d9902015-01-10 17:46:07 -0800211 controller, err := NewController(nil, nil, &spec, nil, options.RuntimePrincipal{newBlessedPrincipal(gctx)})
Jiri Simsa78b646f2014-10-08 10:23:05 -0700212
213 if err != nil {
214 t.Errorf("unable to create controller: %v", err)
215 t.Fail()
216 return
217 }
Jiri Simsa78b646f2014-10-08 10:23:05 -0700218 writer := testwriter.Writer{}
219 var stream *outstandingStream
220 if len(test.streamingInputs) > 0 {
221 stream = newStream()
Matt Rosencrantz4aabe572014-10-22 09:25:50 -0700222 controller.outstandingRequests[0] = &outstandingRequest{
223 stream: stream,
224 }
Jiri Simsa78b646f2014-10-08 10:23:05 -0700225 go func() {
226 for _, value := range test.streamingInputs {
Benjamin Prosnitza2ac3b32014-12-12 11:40:31 -0800227 controller.SendOnStream(0, lib.VomEncodeOrDie(value), &writer)
Jiri Simsa78b646f2014-10-08 10:23:05 -0700228 }
229 controller.CloseStream(0)
230 }()
231 }
232
Benjamin Prosnitza2ac3b32014-12-12 11:40:31 -0800233 request := VeyronRPC{
Jiri Simsa78b646f2014-10-08 10:23:05 -0700234 Name: "/" + endpoint.String(),
235 Method: test.method,
236 InArgs: test.inArgs,
237 NumOutArgs: test.numOutArgs,
238 IsStreaming: stream != nil,
239 }
Matt Rosencrantz306d9902015-01-10 17:46:07 -0800240 controller.sendVeyronRequest(gctx, 0, &request, &writer, stream)
Jiri Simsa78b646f2014-10-08 10:23:05 -0700241
Matt Rosencrantz4aabe572014-10-22 09:25:50 -0700242 if err := testwriter.CheckResponses(&writer, test.expectedStream, test.expectedError); err != nil {
243 t.Error(err)
244 }
Jiri Simsa78b646f2014-10-08 10:23:05 -0700245}
246
247func TestCallingGoServer(t *testing.T) {
248 runGoServerTestCase(t, goServerTestCase{
249 method: "Add",
Benjamin Prosnitza2ac3b32014-12-12 11:40:31 -0800250 inArgs: []interface{}{2, 3},
Benjamin Prosnitz518af1e2015-01-20 14:20:10 -0800251 numOutArgs: 1,
Benjamin Prosnitza2ac3b32014-12-12 11:40:31 -0800252 expectedStream: []lib.Response{
253 lib.Response{
254 Message: lib.VomEncodeOrDie([]interface{}{int32(5)}),
Jiri Simsa78b646f2014-10-08 10:23:05 -0700255 Type: lib.ResponseFinal,
256 },
257 },
258 })
259}
260
261func TestCallingGoServerWithError(t *testing.T) {
262 runGoServerTestCase(t, goServerTestCase{
263 method: "Divide",
Benjamin Prosnitza2ac3b32014-12-12 11:40:31 -0800264 inArgs: []interface{}{1, 0},
Benjamin Prosnitz518af1e2015-01-20 14:20:10 -0800265 numOutArgs: 1,
Mike Burrowsb6689c22014-10-08 11:14:15 -0700266 expectedError: verror2.Make(verror2.BadArg, nil, "div 0"),
Jiri Simsa78b646f2014-10-08 10:23:05 -0700267 })
268}
269
270func TestCallingGoWithStreaming(t *testing.T) {
271 runGoServerTestCase(t, goServerTestCase{
Benjamin Prosnitza2ac3b32014-12-12 11:40:31 -0800272 method: "StreamingAdd",
273 streamingInputs: []interface{}{1, 2, 3, 4},
Benjamin Prosnitz518af1e2015-01-20 14:20:10 -0800274 numOutArgs: 1,
Benjamin Prosnitza2ac3b32014-12-12 11:40:31 -0800275 expectedStream: []lib.Response{
276 lib.Response{
277 Message: lib.VomEncodeOrDie(int32(1)),
Jiri Simsa78b646f2014-10-08 10:23:05 -0700278 Type: lib.ResponseStream,
279 },
Benjamin Prosnitza2ac3b32014-12-12 11:40:31 -0800280 lib.Response{
281 Message: lib.VomEncodeOrDie(int32(3)),
Jiri Simsa78b646f2014-10-08 10:23:05 -0700282 Type: lib.ResponseStream,
283 },
Benjamin Prosnitza2ac3b32014-12-12 11:40:31 -0800284 lib.Response{
285 Message: lib.VomEncodeOrDie(int32(6)),
Jiri Simsa78b646f2014-10-08 10:23:05 -0700286 Type: lib.ResponseStream,
287 },
Benjamin Prosnitza2ac3b32014-12-12 11:40:31 -0800288 lib.Response{
289 Message: lib.VomEncodeOrDie(int32(10)),
Jiri Simsa78b646f2014-10-08 10:23:05 -0700290 Type: lib.ResponseStream,
291 },
Benjamin Prosnitza2ac3b32014-12-12 11:40:31 -0800292 lib.Response{
Jiri Simsa78b646f2014-10-08 10:23:05 -0700293 Message: nil,
294 Type: lib.ResponseStreamClose,
295 },
Benjamin Prosnitza2ac3b32014-12-12 11:40:31 -0800296 lib.Response{
297 Message: lib.VomEncodeOrDie([]interface{}{int32(10)}),
Jiri Simsa78b646f2014-10-08 10:23:05 -0700298 Type: lib.ResponseFinal,
299 },
300 },
301 })
302}
303
304type runningTest struct {
305 controller *Controller
306 writer *testwriter.Writer
307 mounttableServer ipc.Server
308 proxyServer *proxy.Proxy
309}
310
311func serveServer() (*runningTest, error) {
312 mounttableServer, endpoint, err := startMountTableServer()
313
314 if err != nil {
315 return nil, fmt.Errorf("unable to start mounttable: %v", err)
316 }
317
318 proxyServer, err := startProxy()
319
320 if err != nil {
321 return nil, fmt.Errorf("unable to start proxy: %v", err)
322 }
323
324 proxyEndpoint := proxyServer.Endpoint().String()
325
326 writer := testwriter.Writer{}
327
Benjamin Prosnitz86d52282014-12-19 15:48:38 -0800328 writerCreator := func(int32) lib.ClientWriter {
Jiri Simsa78b646f2014-10-08 10:23:05 -0700329 return &writer
330 }
Cosmos Nicolaou408de0f2014-10-24 13:32:29 -0700331 spec := profiles.LocalListenSpec
Jiri Simsa78b646f2014-10-08 10:23:05 -0700332 spec.Proxy = "/" + proxyEndpoint
Shyam Jayaraman2a42ebe2014-11-19 08:54:45 -0800333 controller, err := NewController(writerCreator, nil, &spec, nil, options.RuntimePrincipal{testPrincipal})
Jiri Simsa78b646f2014-10-08 10:23:05 -0700334
335 if err != nil {
336 return nil, err
337 }
Matt Rosencrantzc90eb7b2015-01-09 08:32:01 -0800338 veyron2.GetNamespace(controller.Context()).SetRoots("/" + endpoint.String())
Jiri Simsa78b646f2014-10-08 10:23:05 -0700339
340 controller.serve(serveRequest{
341 Name: "adder",
342 }, &writer)
343
344 return &runningTest{
345 controller, &writer, mounttableServer, proxyServer,
346 }, nil
347}
348
349func TestJavascriptServeServer(t *testing.T) {
350 rt, err := serveServer()
351 defer rt.mounttableServer.Stop()
352 defer rt.proxyServer.Shutdown()
353 defer rt.controller.Cleanup()
354 if err != nil {
355 t.Fatalf("could not serve server %v", err)
356 }
357
358 if len(rt.writer.Stream) != 1 {
359 t.Errorf("expected only one response, got %d", len(rt.writer.Stream))
360 return
361 }
362
363 resp := rt.writer.Stream[0]
364
365 if resp.Type != lib.ResponseFinal {
366 t.Errorf("unknown stream message Got: %v, expected: serve response", resp)
367 return
368 }
Jiri Simsa78b646f2014-10-08 10:23:05 -0700369}
370
371func TestJavascriptStopServer(t *testing.T) {
372 rt, err := serveServer()
373 defer rt.mounttableServer.Stop()
374 defer rt.proxyServer.Shutdown()
375 defer rt.controller.Cleanup()
376
377 if err != nil {
378 t.Errorf("could not serve server %v", err)
379 return
380 }
381
382 // ensure there is only one server and then stop the server
383 if len(rt.controller.servers) != 1 {
384 t.Errorf("expected only one server but got: %d", len(rt.controller.servers))
385 return
386 }
387 for serverId := range rt.controller.servers {
388 rt.controller.removeServer(serverId)
389 }
390
391 // ensure there is no more servers now
392 if len(rt.controller.servers) != 0 {
393 t.Errorf("expected no server after stopping the only one but got: %d", len(rt.controller.servers))
394 return
395 }
396
397 return
398}
399
400// A test case to simulate a Javascript server talking to the App. All the
401// responses from Javascript are mocked and sent back through the method calls.
402// All messages from the client are sent using a go client.
403type jsServerTestCase struct {
404 method string
405 inArgs []interface{}
406 // The set of streaming inputs from the client to the server.
407 // This is passed to the client, which then passes it to the app.
408 clientStream []interface{}
409 // The set of JSON streaming messages sent from Javascript to the
410 // app.
Benjamin Prosnitza2ac3b32014-12-12 11:40:31 -0800411 serverStream []interface{}
Jiri Simsa78b646f2014-10-08 10:23:05 -0700412 // The final response sent by the Javascript server to the
413 // app.
414 finalResponse interface{}
415 // The final error sent by the Javascript server to the app.
Mike Burrowsb6689c22014-10-08 11:14:15 -0700416 err verror2.E
Jiri Simsa78b646f2014-10-08 10:23:05 -0700417
418 // Whether or not the Javascript server has an authorizer or not.
419 // If it does have an authorizer, then authError is sent back from the server
420 // to the app.
421 hasAuthorizer bool
Mike Burrowsb6689c22014-10-08 11:14:15 -0700422 authError verror2.E
Jiri Simsa78b646f2014-10-08 10:23:05 -0700423}
424
Jiri Simsa78b646f2014-10-08 10:23:05 -0700425func runJsServerTestCase(t *testing.T, test jsServerTestCase) {
426 rt, err := serveServer()
427 defer rt.mounttableServer.Stop()
428 defer rt.proxyServer.Shutdown()
429 defer rt.controller.Cleanup()
430
431 if err != nil {
432 t.Errorf("could not serve server %v", err)
433 }
434
435 if len(rt.writer.Stream) != 1 {
436 t.Errorf("expected only on response, got %d", len(rt.writer.Stream))
437 return
438 }
439
440 resp := rt.writer.Stream[0]
441
442 if resp.Type != lib.ResponseFinal {
443 t.Errorf("unknown stream message Got: %v, expected: serve response", resp)
444 return
445 }
446
Jiri Simsa78b646f2014-10-08 10:23:05 -0700447 rt.writer.Stream = nil
448
Shyam Jayaramane56df9a2014-11-20 17:38:54 -0800449 vomClientStream := []string{}
450 for _, m := range test.clientStream {
Benjamin Prosnitza2ac3b32014-12-12 11:40:31 -0800451 vomClientStream = append(vomClientStream, lib.VomEncodeOrDie(m))
Shyam Jayaramane56df9a2014-11-20 17:38:54 -0800452 }
453 mock := &mockJSServer{
454 controller: rt.controller,
455 t: t,
456 method: test.method,
Todd Wang72ef57b2015-01-08 10:23:21 -0800457 serviceSignature: []signature.Interface{simpleAddrSig},
Shyam Jayaramane56df9a2014-11-20 17:38:54 -0800458 expectedClientStream: vomClientStream,
459 serverStream: test.serverStream,
460 hasAuthorizer: test.hasAuthorizer,
461 authError: test.authError,
Shyam Jayaraman907219d2014-11-26 12:14:37 -0800462 inArgs: test.inArgs,
Shyam Jayaramane56df9a2014-11-20 17:38:54 -0800463 finalResponse: test.finalResponse,
464 finalError: test.err,
465 }
466 // Let's replace the test writer with the mockJSServer
Benjamin Prosnitz86d52282014-12-19 15:48:38 -0800467 rt.controller.writerCreator = func(int32) lib.ClientWriter {
Shyam Jayaramane56df9a2014-11-20 17:38:54 -0800468 return mock
469 }
470
Matt Rosencrantzc90eb7b2015-01-09 08:32:01 -0800471 // Get the client that is relevant to the controller so it talks
472 // to the right mounttable.
473 client := veyron2.GetClient(rt.controller.Context())
Jiri Simsa78b646f2014-10-08 10:23:05 -0700474
475 if err != nil {
476 t.Errorf("unable to create client: %v", err)
477 }
478
Matt Rosencrantzc90eb7b2015-01-09 08:32:01 -0800479 call, err := client.StartCall(rt.controller.Context(), "adder/adder", test.method, test.inArgs)
Jiri Simsa78b646f2014-10-08 10:23:05 -0700480 if err != nil {
481 t.Errorf("failed to start call: %v", err)
482 }
483
Jiri Simsa78b646f2014-10-08 10:23:05 -0700484 for _, msg := range test.clientStream {
Jiri Simsa78b646f2014-10-08 10:23:05 -0700485 if err := call.Send(msg); err != nil {
486 t.Errorf("unexpected error while sending %v: %v", msg, err)
487 }
488 }
Shyam Jayaramane56df9a2014-11-20 17:38:54 -0800489 if err := call.CloseSend(); err != nil {
490 t.Errorf("unexpected error on close: %v", err)
Jiri Simsa78b646f2014-10-08 10:23:05 -0700491 }
492
Benjamin Prosnitza2ac3b32014-12-12 11:40:31 -0800493 expectedStream := test.serverStream
Jiri Simsa78b646f2014-10-08 10:23:05 -0700494 for {
495 var data interface{}
496 if err := call.Recv(&data); err != nil {
497 break
498 }
499 if len(expectedStream) == 0 {
500 t.Errorf("unexpected stream value: %v", data)
501 continue
502 }
503 if !reflect.DeepEqual(data, expectedStream[0]) {
504 t.Errorf("unexpected stream value: got %v, expected %v", data, expectedStream[0])
505 }
506 expectedStream = expectedStream[1:]
507 }
Shyam Jayaramane56df9a2014-11-20 17:38:54 -0800508
Jiri Simsa78b646f2014-10-08 10:23:05 -0700509 var result interface{}
510 var err2 error
511
Shyam Jayaramane56df9a2014-11-20 17:38:54 -0800512 err = call.Finish(&result, &err2)
513 if (err == nil && test.authError != nil) || (err != nil && test.authError == nil) {
Benjamin Prosnitza2ac3b32014-12-12 11:40:31 -0800514 t.Errorf("unexpected err: %v, %v", err, test.authError)
Jiri Simsa78b646f2014-10-08 10:23:05 -0700515 }
516
Shyam Jayaramane56df9a2014-11-20 17:38:54 -0800517 if err != nil {
518 return
519 }
Jiri Simsa78b646f2014-10-08 10:23:05 -0700520 if !reflect.DeepEqual(result, test.finalResponse) {
521 t.Errorf("unexected final response: got %v, expected %v", result, test.finalResponse)
522 }
523
524 // If err2 is nil and test.err is nil reflect.DeepEqual will return false because the
525 // types are different. Because of this, we only use reflect.DeepEqual if one of
526 // the values is non-nil. If both values are nil, then we consider them equal.
Mike Burrowsb6689c22014-10-08 11:14:15 -0700527 if (err2 != nil || test.err != nil) && !verror2.Equal(err2, test.err) {
528 t.Errorf("unexpected error: got %#v, expected %#v", err2, test.err)
Jiri Simsa78b646f2014-10-08 10:23:05 -0700529 }
Jiri Simsa78b646f2014-10-08 10:23:05 -0700530}
531
532func TestSimpleJSServer(t *testing.T) {
533 runJsServerTestCase(t, jsServerTestCase{
534 method: "Add",
Benjamin Prosnitza2ac3b32014-12-12 11:40:31 -0800535 inArgs: []interface{}{int32(1), int32(2)},
536 finalResponse: int32(3),
Jiri Simsa78b646f2014-10-08 10:23:05 -0700537 })
538}
539
540func TestJSServerWithAuthorizer(t *testing.T) {
541 runJsServerTestCase(t, jsServerTestCase{
542 method: "Add",
Benjamin Prosnitza2ac3b32014-12-12 11:40:31 -0800543 inArgs: []interface{}{int32(1), int32(2)},
544 finalResponse: int32(3),
Jiri Simsa78b646f2014-10-08 10:23:05 -0700545 hasAuthorizer: true,
546 })
547}
548
549func TestJSServerWithError(t *testing.T) {
Mike Burrowsb6689c22014-10-08 11:14:15 -0700550 err := verror2.Make(verror2.Internal, nil)
Jiri Simsa78b646f2014-10-08 10:23:05 -0700551 runJsServerTestCase(t, jsServerTestCase{
552 method: "Add",
Benjamin Prosnitza2ac3b32014-12-12 11:40:31 -0800553 inArgs: []interface{}{int32(1), int32(2)},
554 finalResponse: int32(3),
Mike Burrowsb6689c22014-10-08 11:14:15 -0700555 err: err,
Jiri Simsa78b646f2014-10-08 10:23:05 -0700556 })
557}
558
559func TestJSServerWithAuthorizerAndAuthError(t *testing.T) {
Mike Burrowsb6689c22014-10-08 11:14:15 -0700560 err := verror2.Make(verror2.Internal, nil)
Jiri Simsa78b646f2014-10-08 10:23:05 -0700561 runJsServerTestCase(t, jsServerTestCase{
562 method: "Add",
Benjamin Prosnitza2ac3b32014-12-12 11:40:31 -0800563 inArgs: []interface{}{int32(1), int32(2)},
564 finalResponse: int32(3),
Jiri Simsa78b646f2014-10-08 10:23:05 -0700565 hasAuthorizer: true,
Mike Burrowsb6689c22014-10-08 11:14:15 -0700566 authError: err,
Jiri Simsa78b646f2014-10-08 10:23:05 -0700567 })
568}
569func TestJSServerWihStreamingInputs(t *testing.T) {
570 runJsServerTestCase(t, jsServerTestCase{
571 method: "StreamingAdd",
Benjamin Prosnitza2ac3b32014-12-12 11:40:31 -0800572 clientStream: []interface{}{int32(3), int32(4)},
573 finalResponse: int32(10),
Jiri Simsa78b646f2014-10-08 10:23:05 -0700574 })
575}
576
577func TestJSServerWihStreamingOutputs(t *testing.T) {
578 runJsServerTestCase(t, jsServerTestCase{
Benjamin Prosnitza2ac3b32014-12-12 11:40:31 -0800579 method: "StreamingAdd",
580 serverStream: []interface{}{int32(3), int32(4)},
581 finalResponse: int32(10),
Jiri Simsa78b646f2014-10-08 10:23:05 -0700582 })
583}
584
585func TestJSServerWihStreamingInputsAndOutputs(t *testing.T) {
586 runJsServerTestCase(t, jsServerTestCase{
Benjamin Prosnitza2ac3b32014-12-12 11:40:31 -0800587 method: "StreamingAdd",
588 clientStream: []interface{}{int32(1), int32(2)},
589 serverStream: []interface{}{int32(3), int32(4)},
590 finalResponse: int32(10),
Jiri Simsa78b646f2014-10-08 10:23:05 -0700591 })
592}