go.dedis.ch/onet/v3@v3.2.11-0.20210930124529-e36530bca7ef/processor_test.go (about) 1 package onet 2 3 import ( 4 "bytes" 5 "encoding/base64" 6 "encoding/json" 7 "fmt" 8 "io" 9 "io/ioutil" 10 "net/http" 11 "reflect" 12 "strconv" 13 "sync" 14 "testing" 15 16 "github.com/stretchr/testify/require" 17 "go.dedis.ch/kyber/v3" 18 "go.dedis.ch/kyber/v3/group/edwards25519" 19 "go.dedis.ch/kyber/v3/pairing/bn256" 20 "go.dedis.ch/kyber/v3/sign/bls" 21 "go.dedis.ch/kyber/v3/util/key" 22 "go.dedis.ch/kyber/v3/util/random" 23 "go.dedis.ch/onet/v3/log" 24 "go.dedis.ch/onet/v3/network" 25 "go.dedis.ch/protobuf" 26 "golang.org/x/xerrors" 27 ) 28 29 const testServiceName = "testService" 30 31 func init() { 32 RegisterNewService(testServiceName, newTestService) 33 ServiceFactory.ServiceID(testServiceName) 34 network.RegisterMessages(&testMsg{}, &testPanicMsg{}) 35 } 36 37 func TestProcessor_AddMessage(t *testing.T) { 38 h1 := NewLocalServer(tSuite, 2000) 39 defer h1.Close() 40 p := NewServiceProcessor(&Context{server: h1}) 41 require.Nil(t, p.RegisterHandler(procMsg)) 42 if len(p.handlers) != 1 { 43 require.Fail(t, "Should have registered one function") 44 } 45 mt := network.MessageType(&testMsg{}) 46 if mt.Equal(network.ErrorType) { 47 require.Fail(t, "Didn't register message-type correctly") 48 } 49 var wrongFunctions = []interface{}{ 50 procMsgWrong1, 51 procMsgWrong2, 52 procMsgWrong3, 53 procMsgWrong4, 54 procMsgWrong5, 55 procMsgWrong6, 56 } 57 for _, f := range wrongFunctions { 58 fsig := reflect.TypeOf(f).String() 59 log.Lvl2("Checking function", fsig) 60 require.Error(t, p.RegisterHandler(f), 61 "Could register wrong function: "+fsig) 62 } 63 } 64 65 func TestProcessor_RegisterMessages(t *testing.T) { 66 h1 := NewLocalServer(tSuite, 2000) 67 defer h1.Close() 68 p := NewServiceProcessor(&Context{server: h1}) 69 require.Nil(t, p.RegisterHandlers(procMsg, procMsg2, procMsg3, procMsg4)) 70 require.Error(t, p.RegisterHandlers(procMsg3, procMsgWrong1)) 71 } 72 73 func TestProcessor_RegisterStreamingMessage(t *testing.T) { 74 h1 := NewLocalServer(tSuite, 2000) 75 defer h1.Close() 76 p := NewServiceProcessor(&Context{server: h1}) 77 78 // correct registration 79 f1 := func(m *testMsg) (chan network.Message, chan bool, error) { 80 return make(chan network.Message), make(chan bool), nil 81 } 82 f2 := func(m *testMsg) (chan *testMsg, chan bool, error) { 83 return make(chan *testMsg), make(chan bool), nil 84 } 85 require.Nil(t, p.RegisterStreamingHandlers(f1, f2)) 86 87 // wrong registrations 88 require.Error(t, p.RegisterStreamingHandler( 89 func(m int) (chan network.Message, chan bool, error) { 90 return nil, nil, nil 91 }), "input must be a pointer to struct") 92 require.Error(t, p.RegisterStreamingHandler( 93 func(m testMsg) (chan network.Message, chan bool, error) { 94 return nil, nil, nil 95 }), "input must be a pointer to struct") 96 require.Error(t, p.RegisterStreamingHandler( 97 func(m *testMsg) (chan int, chan bool, error) { 98 return nil, nil, nil 99 }), "first return must be a pointer or interface") 100 require.Error(t, p.RegisterStreamingHandler( 101 func(m *testMsg) (chan testMsg, chan bool, error) { 102 return nil, nil, nil 103 }), "first return must be a pointer or interface") 104 require.Error(t, p.RegisterStreamingHandler( 105 func(m *testMsg) (chan testMsg, error) { 106 return nil, nil 107 }), "must have three return values") 108 require.Error(t, p.RegisterStreamingHandler( 109 func(m *testMsg) (chan testMsg, chan int, error) { 110 return nil, nil, nil 111 }), "second return must be a boolean channel") 112 require.Error(t, p.RegisterStreamingHandler( 113 func(m *testMsg) (chan testMsg, []int, error) { 114 return nil, nil, nil 115 }), "second return must be a boolean channel") 116 require.Error(t, p.RegisterStreamingHandler( 117 func(m *testMsg) (chan testMsg, chan int, []byte) { 118 return nil, nil, nil 119 }), "must return an error") 120 } 121 122 func TestServiceProcessor_ProcessClientRequest(t *testing.T) { 123 h1 := NewLocalServer(tSuite, 2000) 124 defer h1.Close() 125 p := NewServiceProcessor(&Context{server: h1}) 126 require.Nil(t, p.RegisterHandlers(procMsg, procMsg2)) 127 128 buf, err := protobuf.Encode(&testMsg{11}) 129 require.Nil(t, err) 130 rep, repChan, err := p.ProcessClientRequest(nil, "testMsg", buf) 131 require.Nil(t, repChan) 132 require.NoError(t, err) 133 val := &testMsg{} 134 require.Nil(t, protobuf.Decode(rep, val)) 135 if val.I != 11 { 136 require.Fail(t, "Value got lost - should be 11") 137 } 138 139 buf, err = protobuf.Encode(&testMsg{42}) 140 require.Nil(t, err) 141 _, _, err = p.ProcessClientRequest(nil, "testMsg", buf) 142 require.NotNil(t, err) 143 144 buf, err = protobuf.Encode(&testMsg2{42}) 145 require.Nil(t, err) 146 _, _, err = p.ProcessClientRequest(nil, "testMsg2", buf) 147 require.NotNil(t, err) 148 149 // Test non-existing endpoint 150 buf, err = protobuf.Encode(&testMsg2{42}) 151 require.Nil(t, err) 152 lvl := log.DebugVisible() 153 log.SetDebugVisible(0) 154 log.OutputToBuf() 155 _, _, err = p.ProcessClientRequest(nil, "testMsgNotAvailable", buf) 156 log.OutputToOs() 157 log.SetDebugVisible(lvl) 158 require.NotNil(t, err) 159 require.NotEqual(t, "", log.GetStdErr()) 160 } 161 162 func TestServiceProcessor_ProcessClientRequest_Streaming_Simple(t *testing.T) { 163 h1 := NewLocalServer(tSuite, 2000) 164 defer h1.Close() 165 166 p := NewServiceProcessor(&Context{server: h1}) 167 h := func(m *testMsg) (chan network.Message, chan bool, error) { 168 outChan := make(chan network.Message) 169 closeChan := make(chan bool) 170 go func() { 171 for i := 0; i < int(m.I); i++ { 172 outChan <- m 173 } 174 <-closeChan 175 close(outChan) 176 }() 177 return outChan, closeChan, nil 178 } 179 require.Nil(t, p.RegisterStreamingHandler(h)) 180 181 n := 5 182 buf, err := protobuf.Encode(&testMsg{int64(n)}) 183 require.NoError(t, err) 184 rep, _, err := p.ProcessClientRequest(nil, "testMsg", buf) 185 // Using ProcessClientRequest with a streaming request should yield an error 186 require.Nil(t, rep) 187 require.Error(t, err) 188 189 inputChan := make(chan []byte, 1) 190 inputChan <- buf 191 outChan, err := p.ProcessClientStreamRequest(nil, "testMsg", inputChan) 192 193 require.NoError(t, err) 194 195 for i := 0; i < n; i++ { 196 buf := <-outChan 197 val := &testMsg{} 198 require.Nil(t, protobuf.Decode(buf, val)) 199 require.Equal(t, val.I, int64(n)) 200 } 201 close(inputChan) 202 } 203 204 func TestServiceProcessor_ProcessClientRequest_Streaming_Multiple(t *testing.T) { 205 h1 := NewLocalServer(tSuite, 2000) 206 207 // order matters: last-in first-out 208 defer log.AfterTest(t) // check for leaking go routines 209 defer h1.Close() 210 211 p := NewServiceProcessor(&Context{server: h1}) 212 h := func(m *testMsg) (chan network.Message, chan bool, error) { 213 outChan := make(chan network.Message) 214 closeChan := make(chan bool) 215 go func() { 216 for i := 0; i < int(m.I); i++ { 217 outChan <- m 218 } 219 <-closeChan 220 close(outChan) 221 }() 222 return outChan, closeChan, nil 223 } 224 require.Nil(t, p.RegisterStreamingHandler(h)) 225 226 n := 5 227 buf, err := protobuf.Encode(&testMsg{int64(n)}) 228 require.NoError(t, err) 229 230 // Send 3 requests 231 inputChan := make(chan []byte, 3) 232 outChan, err := p.ProcessClientStreamRequest(nil, "testMsg", inputChan) 233 require.NoError(t, err) 234 235 inputChan <- buf 236 inputChan <- buf 237 inputChan <- buf 238 239 for k := 0; k < 3; k++ { 240 for i := 0; i < n; i++ { 241 buf := <-outChan 242 val := &testMsg{} 243 require.Nil(t, protobuf.Decode(buf, val)) 244 require.Equal(t, val.I, int64(n)) 245 } 246 } 247 248 close(inputChan) 249 } 250 251 func TestServiceProcessor_ProcessClientStreamRequest(t *testing.T) { 252 h1 := NewLocalServer(tSuite, 2000) 253 defer h1.Close() 254 255 p := NewServiceProcessor(&Context{server: h1}) 256 // The function need to use the same outChan and closeChan if a request is 257 // coming from the same client that expects the same outChan to be used. 258 serviceStruct := struct { 259 once sync.Once 260 outChan chan network.Message 261 closeChan chan bool 262 }{ 263 outChan: make(chan network.Message, 10), 264 closeChan: make(chan bool), 265 } 266 267 h := func(m *testMsg) (chan network.Message, chan bool, error) { 268 go func() { 269 for i := 0; i < int(m.I); i++ { 270 serviceStruct.outChan <- m 271 } 272 <-serviceStruct.closeChan 273 serviceStruct.once.Do(func() { 274 close(serviceStruct.outChan) 275 }) 276 }() 277 return serviceStruct.outChan, serviceStruct.closeChan, nil 278 } 279 require.Nil(t, p.RegisterStreamingHandler(h)) 280 281 // Sending a first message from the client to the service. 282 n := 5 283 clientInputs := make(chan []byte, 10) 284 buf, err := protobuf.Encode(&testMsg{int64(n)}) 285 require.NoError(t, err) 286 clientInputs <- buf 287 outVals, err := p.ProcessClientStreamRequest(nil, "testMsg", clientInputs) 288 require.NoError(t, err) 289 290 for i := 0; i < n; i++ { 291 buf := <-outVals 292 val := &testMsg{} 293 require.Nil(t, protobuf.Decode(buf, val)) 294 require.Equal(t, val.I, int64(n)) 295 } 296 297 // Sending an additional message from the client to the service using the 298 // same channel. 299 n = 2 300 buf, err = protobuf.Encode(&testMsg{int64(n)}) 301 require.NoError(t, err) 302 clientInputs <- buf 303 304 for i := 0; i < n; i++ { 305 buf := <-outVals 306 val := &testMsg{} 307 require.Nil(t, protobuf.Decode(buf, val)) 308 require.Equal(t, val.I, int64(n)) 309 } 310 311 close(clientInputs) 312 } 313 314 // If the caller closes early the client input chans then the 315 // ProcessClientStreamRequest should not try to decode an empty buffer 316 func TestServiceProcessor_ProcessClientStreamRequest_close_early(t *testing.T) { 317 h1 := NewLocalServer(tSuite, 2000) 318 defer h1.Close() 319 320 p := NewServiceProcessor(&Context{server: h1}) 321 // The function need to use the same outChan and closeChan if a request is 322 // coming from the same client that expects the same outChan to be used. 323 serviceStruct := struct { 324 once sync.Once 325 outChan chan network.Message 326 closeChan chan bool 327 }{ 328 outChan: make(chan network.Message, 10), 329 closeChan: make(chan bool), 330 } 331 332 h := func(m *testMsg) (chan network.Message, chan bool, error) { 333 go func() { 334 for i := 0; i < int(m.I); i++ { 335 serviceStruct.outChan <- m 336 } 337 <-serviceStruct.closeChan 338 serviceStruct.once.Do(func() { 339 close(serviceStruct.outChan) 340 }) 341 }() 342 return serviceStruct.outChan, serviceStruct.closeChan, nil 343 } 344 require.Nil(t, p.RegisterStreamingHandler(h)) 345 346 // Sending a first message from the client to the service. 347 clientInputs := make(chan []byte, 10) 348 // early close by the caller 349 close(clientInputs) 350 _, err := p.ProcessClientStreamRequest(nil, "testMsg", clientInputs) 351 require.NoError(t, err) 352 } 353 354 func TestProcessor_ProcessClientRequest(t *testing.T) { 355 local := NewTCPTest(tSuite) 356 357 // generate 1 host 358 h := local.GenServers(1)[0] 359 defer local.CloseAll() 360 361 client := local.NewClient(testServiceName) 362 msg := &testMsg{} 363 err := client.SendProtobuf(h.ServerIdentity, &testMsg{12}, msg) 364 require.Nil(t, err) 365 if msg == nil { 366 require.Fail(t, "Msg should not be nil") 367 } 368 if msg.I != 12 { 369 require.Fail(t, "Didn't send 12") 370 } 371 } 372 373 // Test that the panic will be recovered and announced without crashing the server. 374 func TestProcessor_PanicClientRequest(t *testing.T) { 375 local := NewTCPTest(tSuite) 376 377 h := local.GenServers(1)[0] 378 defer local.CloseAll() 379 380 client := local.NewClient(testServiceName) 381 err := client.SendProtobuf(h.ServerIdentity, &testPanicMsg{}, struct{}{}) 382 require.Error(t, err) 383 require.Contains(t, err.Error(), "deadbeef") 384 } 385 386 type testMsg struct { 387 I int64 388 } 389 390 type testMsg2 testMsg 391 type testMsg3 testMsg 392 type testMsg4 testMsg 393 type testMsg5 testMsg 394 type testPanicMsg struct{} 395 396 func procMsg(msg *testMsg) (network.Message, error) { 397 // Return an error for testing 398 if msg.I == 42 { 399 return nil, xerrors.New("42 is NOT the answer") 400 } 401 return msg, nil 402 } 403 404 func procMsg2(msg *testMsg2) (network.Message, error) { 405 // Return an error for testing 406 if msg.I == 42 { 407 return nil, xerrors.New("42 is NOT the answer") 408 } 409 return nil, nil 410 } 411 412 func procMsg3(msg *testMsg3) (network.Message, error) { 413 return nil, nil 414 } 415 416 func procMsg4(msg *testMsg4) (*testMsg4, error) { 417 return msg, nil 418 } 419 420 func procMsgWrong1() (network.Message, error) { 421 return nil, nil 422 } 423 424 func procMsgWrong2(msg testMsg2) (network.Message, error) { 425 return msg, nil 426 } 427 428 func procMsgWrong3(msg *testMsg3) error { 429 return nil 430 } 431 432 func procMsgWrong4(msg *testMsg) (*network.Message, error) { 433 return nil, nil 434 } 435 436 func procMsgWrong5(msg *testMsg) (int, error) { 437 return 10, nil 438 } 439 440 func procMsgWrong6(msg *testMsg) (testMsg, error) { 441 return *msg, nil 442 } 443 444 type testService struct { 445 *ServiceProcessor 446 Msg interface{} 447 } 448 449 func newTestService(c *Context) (Service, error) { 450 ts := &testService{ 451 ServiceProcessor: NewServiceProcessor(c), 452 } 453 if err := ts.RegisterHandlers(ts.ProcessMsg, ts.ProcessMsgPanic); err != nil { 454 panic(err.Error()) 455 } 456 457 if err := ts.RegisterRESTHandler(procRestMsgGET1, testServiceName, "GET", 3, 3); err != nil { 458 panic(err.Error()) 459 } 460 if err := ts.RegisterRESTHandler(procRestMsgGET2, testServiceName, "GET", 3, 3); err != nil { 461 panic(err.Error()) 462 } 463 if err := ts.RegisterRESTHandler(procRestMsgGET3, testServiceName, "GET", 3, 3); err != nil { 464 panic(err.Error()) 465 } 466 if err := ts.RegisterRESTHandler(procRestMsgPOSTString, testServiceName, "POST", 3, 3); err != nil { 467 panic(err.Error()) 468 } 469 if err := ts.RegisterRESTHandler(procRestMsgPOSTPoint, testServiceName, "POST", 3, 3); err != nil { 470 panic(err.Error()) 471 } 472 return ts, nil 473 } 474 475 func (ts *testService) NewProtocol(tn *TreeNodeInstance, conf *GenericConfig) (ProtocolInstance, error) { 476 return nil, nil 477 } 478 479 func (ts *testService) ProcessMsg(msg *testMsg) (network.Message, error) { 480 ts.Msg = msg 481 return msg, nil 482 } 483 484 func (ts *testService) ProcessMsgPanic(msg *testPanicMsg) (network.Message, error) { 485 panic("deadbeef") 486 } 487 488 func TestProcessor_REST_Registration(t *testing.T) { 489 h1 := NewLocalServer(tSuite, 2000) 490 defer h1.Close() 491 p := NewServiceProcessor(&Context{server: h1}) 492 require.NoError(t, p.RegisterRESTHandler(procRestMsgGET1, "dummyService", "GET", 3, 3)) 493 require.NoError(t, p.RegisterRESTHandler(procRestMsgGET2, "dummyService", "GET", 3, 3)) 494 require.NoError(t, p.RegisterRESTHandler(procRestMsgGET3, "dummyService", "GET", 3, 3)) 495 496 require.NoError(t, p.RegisterRESTHandler(procRestMsgPOSTString, "dummyService", "POST", 3, 3)) 497 require.NoError(t, p.RegisterRESTHandler(procRestMsgPOSTPoint, "dummyService", "POST", 3, 3)) 498 require.NoError(t, p.RegisterRESTHandler(procMsg, "dummyService", "POST", 3, 3)) 499 require.NoError(t, p.RegisterRESTHandler(procMsg2, "dummyService", "POST", 3, 3)) 500 require.NoError(t, p.RegisterRESTHandler(procMsg3, "dummyService", "POST", 3, 3)) 501 require.NoError(t, p.RegisterRESTHandler(procMsg4, "dummyService", "POST", 3, 3)) 502 503 require.Error(t, p.RegisterRESTHandler(procRestMsgGET3, "dummyService", "GET", 3, 2)) 504 require.Error(t, p.RegisterRESTHandler(procRestMsgGET3, "dummyService", "GET", 1, 2)) 505 require.Error(t, p.RegisterRESTHandler(procRestMsgGETWrong1, "dummyService", "GET", 3, 3)) 506 require.Error(t, p.RegisterRESTHandler(procRestMsgGETWrong2, "dummyService", "GET", 3, 3)) 507 require.Error(t, p.RegisterRESTHandler(procRestMsgGETWrong3, "dummyService", "GET", 3, 3)) 508 require.Error(t, p.RegisterRESTHandler(procRestMsgGET1, "dummyService", "XXX", 3, 3)) 509 510 require.Error(t, p.RegisterRESTHandler(procMsgWrong1, "dummyService", "POST", 3, 3)) 511 require.Error(t, p.RegisterRESTHandler(procMsgWrong2, "dummyService", "POST", 3, 3)) 512 require.Error(t, p.RegisterRESTHandler(procMsgWrong3, "dummyService", "POST", 3, 3)) 513 require.Error(t, p.RegisterRESTHandler(procMsgWrong4, "dummyService", "POST", 3, 3)) 514 require.Error(t, p.RegisterRESTHandler(procMsgWrong5, "dummyService", "POST", 3, 3)) 515 require.Error(t, p.RegisterRESTHandler(procMsgWrong6, "dummyService", "POST", 3, 3)) 516 } 517 518 type bnPoint struct { 519 P kyber.Point 520 } 521 522 type bnPointWrapper struct { 523 P []byte 524 } 525 526 func (p bnPoint) MarshalJSON() ([]byte, error) { 527 buf, err := p.P.MarshalBinary() 528 if err != nil { 529 return nil, err 530 } 531 return []byte(fmt.Sprintf(`{"P": "%s"}`, base64.StdEncoding.EncodeToString(buf))), nil 532 } 533 534 func (p *bnPoint) UnmarshalJSON(b []byte) error { 535 wrapper := bnPointWrapper{} 536 if err := json.Unmarshal(b, &wrapper); err != nil { 537 return err 538 } 539 suite := bn256.NewSuite() 540 g2 := suite.G2().Point() 541 if err := g2.UnmarshalBinary(wrapper.P); err != nil { 542 return err 543 } 544 p.P = g2 545 return nil 546 } 547 548 type edPoint struct { 549 P kyber.Point 550 } 551 552 type edPointWrapper struct { 553 P []byte 554 } 555 556 func (p edPoint) MarshalJSON() ([]byte, error) { 557 buf, err := p.P.MarshalBinary() 558 if err != nil { 559 return nil, err 560 } 561 return []byte(fmt.Sprintf(`{"P": "%s"}`, base64.StdEncoding.EncodeToString(buf))), nil 562 } 563 564 func (p *edPoint) UnmarshalJSON(b []byte) error { 565 wrapper := edPointWrapper{} 566 if err := json.Unmarshal(b, &wrapper); err != nil { 567 return err 568 } 569 suite := edwards25519.NewBlakeSHA256Ed25519() 570 point := suite.Point() 571 if err := point.UnmarshalBinary(wrapper.P); err != nil { 572 return err 573 } 574 p.P = point 575 return nil 576 } 577 578 type twoPoints struct { 579 PointEd edPoint 580 PointBn bnPoint 581 } 582 583 func TestMarshalJSON_bn(t *testing.T) { 584 suite := bn256.NewSuite() 585 _, pk := bls.NewKeyPair(suite, random.New()) 586 p := bnPoint{pk} 587 buf, err := json.Marshal(&p) 588 require.NoError(t, err) 589 590 p2 := bnPoint{} 591 err = json.Unmarshal(buf, &p2) 592 require.NoError(t, err) 593 594 require.True(t, p2.P.Equal(pk)) 595 } 596 597 func TestMarshalJSON_ed(t *testing.T) { 598 suite := edwards25519.NewBlakeSHA256Ed25519() 599 pk := key.NewKeyPair(suite).Public 600 601 p := edPoint{pk} 602 buf, err := json.Marshal(&p) 603 require.NoError(t, err) 604 605 p2 := edPoint{} 606 err = json.Unmarshal(buf, &p2) 607 require.NoError(t, err) 608 609 require.True(t, p2.P.Equal(pk)) 610 } 611 612 func TestMarshalJSON_twoPoints(t *testing.T) { 613 pkEd := key.NewKeyPair(edwards25519.NewBlakeSHA256Ed25519()).Public 614 _, pkBn := bls.NewKeyPair(bn256.NewSuite(), random.New()) 615 616 pTwo := twoPoints{edPoint{pkEd}, bnPoint{pkBn}} 617 buf, err := json.Marshal(&pTwo) 618 require.NoError(t, err) 619 620 pTwo2 := twoPoints{} 621 err = json.Unmarshal(buf, &pTwo2) 622 require.NoError(t, err) 623 624 require.True(t, pTwo2.PointEd.P.Equal(pkEd)) 625 require.True(t, pTwo2.PointBn.P.Equal(pkBn)) 626 } 627 628 func TestProcessor_REST_Handler(t *testing.T) { 629 log.AddUserUninterestingGoroutine("created by net/http.(*Transport).dialConn") 630 631 local := NewTCPTest(tSuite) 632 633 // generate 1 host 634 h := local.GenServers(1)[0] 635 defer local.CloseAll() 636 637 c := http.Client{} 638 port, err := strconv.Atoi(h.ServerIdentity.Address.Port()) 639 require.NoError(t, err) 640 addr := "http://" + h.ServerIdentity.Address.Host() + ":" + strconv.Itoa(port+1) 641 642 // get with empty "body" 643 resp, err := c.Get(addr + "/v3/testService/restMsgGET1") 644 require.NoError(t, err) 645 require.Equal(t, resp.StatusCode, http.StatusOK) 646 msg := testMsg{} 647 require.NoError(t, json.NewDecoder(resp.Body).Decode(&msg)) 648 require.Equal(t, int64(42), msg.I) 649 650 // get by an integer 651 resp, err = c.Get(addr + "/v3/testService/restMsgGET2/99") 652 require.NoError(t, err) 653 require.Equal(t, resp.StatusCode, http.StatusOK) 654 msg = testMsg{} 655 require.NoError(t, json.NewDecoder(resp.Body).Decode(&msg)) 656 require.Equal(t, int64(99), msg.I) 657 658 // get by byte slice, e.g., skipchain ID 659 resp, err = c.Get(addr + "/v3/testService/restMsgGET3/deadbeef") 660 require.NoError(t, err) 661 require.Equal(t, resp.StatusCode, http.StatusOK) 662 msg = testMsg{} 663 require.NoError(t, json.NewDecoder(resp.Body).Decode(&msg)) 664 require.Equal(t, int64(0xde), msg.I) 665 666 // wrong url 667 // NOTE: the error code is 400 because the websocket upgrade failed 668 // usually it should be http.StatusNotFound 669 resp, err = c.Get(addr + "/v3/testService/doesnotexist") 670 require.NoError(t, err) 671 require.Equal(t, resp.StatusCode, http.StatusBadRequest) 672 673 // wrong url (extra slash) 674 resp, err = c.Get(addr + "/v3/testService/restMsgGET3/deadbeef/") 675 require.NoError(t, err) 676 require.Equal(t, resp.StatusCode, http.StatusNotFound) 677 checkJSONMsg(t, resp.Body, "invalid path") 678 679 // wrong encoding of integer 680 resp, err = c.Get(addr + "/v3/testService/restMsgGET2/one") 681 require.NoError(t, err) 682 require.Equal(t, resp.StatusCode, http.StatusNotFound) 683 checkJSONMsg(t, resp.Body, "invalid path") 684 685 // wrong encoding of byte slice (must be hex) 686 resp, err = c.Get(addr + "/v3/testService/restMsgGET3/zzzz") 687 require.NoError(t, err) 688 require.Equal(t, resp.StatusCode, http.StatusNotFound) 689 checkJSONMsg(t, resp.Body, "invalid path") 690 691 // good post request 692 resp, err = c.Post(addr+"/v3/testService/restMsgPOSTString", "application/json", bytes.NewReader([]byte(`{"S": "42"}`))) 693 require.NoError(t, err) 694 require.Equal(t, resp.StatusCode, http.StatusOK) 695 require.NoError(t, json.NewDecoder(resp.Body).Decode(&testMsg{})) 696 697 // wrong content type 698 resp, err = c.Post(addr+"/v3/testService/restMsgPOSTString", "application/text", bytes.NewReader([]byte(`{"S": "42"}`))) 699 require.NoError(t, err) 700 require.Equal(t, resp.StatusCode, http.StatusBadRequest) 701 checkJSONMsg(t, resp.Body, "content type needs to be application/json") 702 703 // wrong value in body 704 resp, err = c.Post(addr+"/v3/testService/restMsgPOSTString", "application/json", bytes.NewReader([]byte(`{"S": "43"}`))) 705 require.NoError(t, err) 706 require.Equal(t, resp.StatusCode, http.StatusBadRequest) 707 checkJSONMsg(t, resp.Body, "processing error") 708 709 // wrong field name 710 resp, err = c.Post(addr+"/v3/testService/restMsgPOSTString", "application/json", bytes.NewReader([]byte(`{"T": "42"}`))) 711 require.NoError(t, err) 712 require.Equal(t, resp.StatusCode, http.StatusBadRequest) 713 checkJSONMsg(t, resp.Body, "processing error") 714 715 // wrong method 716 resp, err = c.Get(addr + "/v3/testService/restMsgPOSTString") 717 require.NoError(t, err) 718 require.Equal(t, resp.StatusCode, http.StatusMethodNotAllowed) 719 checkJSONMsg(t, resp.Body, "unsupported method") 720 721 // test sending points 722 _, pk := bls.NewKeyPair(bn256.NewSuite(), random.New()) 723 buf, err := json.Marshal(&restMsgPOSTPoint{bnPoint{pk}}) 724 require.NoError(t, err) 725 resp, err = c.Post(addr+"/v3/testService/restMsgPOSTPoint", "application/json", bytes.NewReader(buf)) 726 require.NoError(t, err) 727 require.Equal(t, resp.StatusCode, http.StatusOK) 728 respPoint := restMsgPOSTPoint{} 729 require.NoError(t, json.NewDecoder(resp.Body).Decode(&respPoint)) 730 require.True(t, respPoint.bnPoint.P.Equal(pk)) 731 } 732 733 func checkJSONMsg(t *testing.T, r io.Reader, contains string) { 734 s, err := ioutil.ReadAll(r) 735 require.NoError(t, err) 736 type msg struct { 737 Message string `json:"message"` 738 } 739 var m msg 740 require.NoError(t, json.Unmarshal(s, &m)) 741 require.NotEmpty(t, m.Message) 742 require.Contains(t, m.Message, contains) 743 } 744 745 func procRestMsgGET1(s *restMsgGET1) (*testMsg, error) { 746 return &testMsg{42}, nil 747 } 748 749 func procRestMsgGET2(s *restMsgGET2) (*testMsg, error) { 750 return &testMsg{int64(s.X)}, nil 751 } 752 753 func procRestMsgGET3(s *restMsgGET3) (*testMsg, error) { 754 return &testMsg{int64(s.Xs[0])}, nil 755 } 756 757 func procRestMsgGETWrong1(s *restMsgGETWrong1) (*testMsg, error) { 758 return &testMsg{}, nil 759 } 760 761 func procRestMsgGETWrong2(s *restMsgGETWrong2) (*testMsg, error) { 762 return &testMsg{}, nil 763 } 764 765 func procRestMsgGETWrong3(s *restMsgGETWrong3) (*testMsg, error) { 766 return &testMsg{}, nil 767 } 768 769 func procRestMsgPOSTString(s *restMsgPOSTString) (*testMsg, error) { 770 if s.S != "42" { 771 return nil, xerrors.New("not the right answer") 772 } 773 return &testMsg{}, nil 774 } 775 776 func procRestMsgPOSTPoint(s *restMsgPOSTPoint) (*restMsgPOSTPoint, error) { 777 return &restMsgPOSTPoint{s.bnPoint}, nil 778 } 779 780 type restMsgGET1 struct { 781 } 782 783 type restMsgGET2 struct { 784 X int 785 } 786 787 type restMsgGET3 struct { 788 Xs []byte 789 } 790 791 type restMsgGETWrong1 struct { 792 X float64 793 } 794 795 type restMsgGETWrong2 struct { 796 X float64 797 Y float64 798 } 799 800 type restMsgGETWrong3 struct { 801 Xs []int 802 } 803 804 type restMsgPOSTString struct { 805 S string 806 } 807 808 type restMsgPOSTPoint struct { 809 bnPoint 810 }