// TestRouting verifies a registered endpoint receives messages destined for it, and that responses are sent // appropriately func (suite *serverSuite) TestRouting() { srv := suite.server srv.AddEndpoints(Endpoint{ Name: "dummy", Request: new(testproto.DummyRequest), Response: new(testproto.DummyResponse), Handler: func(req mercury.Request) (mercury.Response, error) { request := req.Body().(*testproto.DummyRequest) rsp := req.Response(&testproto.DummyResponse{ Pong: request.Ping, }) rsp.SetHeader("X-Ping-Pong", request.Ping) return rsp, nil }}) req := mercury.NewRequest() req.SetService(testServiceName) req.SetEndpoint("dummy") req.SetBody(&testproto.DummyRequest{ Ping: "routing"}) suite.Assert().NoError(tmsg.JSONMarshaler().MarshalBody(req)) rsp, err := suite.trans.Send(req, time.Second) suite.Require().NoError(err) suite.Require().NotNil(rsp) suite.Require().NoError(tmsg.JSONUnmarshaler(new(testproto.DummyResponse)).UnmarshalPayload(rsp)) suite.Require().NotNil(rsp.Body()) suite.Require().IsType(new(testproto.DummyResponse), rsp.Body()) response := rsp.Body().(*testproto.DummyResponse) suite.Assert().Equal("routing", response.Pong) suite.Assert().Equal("routing", rsp.Headers()["X-Ping-Pong"]) }
// TestRoutingParallel sends a bunch of requests in parallel to different endpoints and checks that the responses match // correctly. 200 workers, 100 requests each. func (suite *serverSuite) TestRoutingParallel() { if testing.Short() { suite.T().Skip("Skipping TestRoutingParallel in short mode") } names := [...]string{"1", "2", "3"} srv := suite.server srv.AddEndpoints( Endpoint{ Name: names[0], Request: new(testproto.DummyRequest), Response: new(testproto.DummyResponse), Handler: func(req mercury.Request) (mercury.Response, error) { return req.Response(&testproto.DummyResponse{Pong: names[0]}), nil }}, Endpoint{ Name: names[1], Request: new(testproto.DummyRequest), Response: new(testproto.DummyResponse), Handler: func(req mercury.Request) (mercury.Response, error) { return req.Response(&testproto.DummyResponse{Pong: names[1]}), nil }}, Endpoint{ Name: names[2], Request: new(testproto.DummyRequest), Response: new(testproto.DummyResponse), Handler: func(req mercury.Request) (mercury.Response, error) { return req.Response(&testproto.DummyResponse{Pong: names[2]}), nil }}) workers := 200 wg := sync.WaitGroup{} wg.Add(workers) unmarshaler := tmsg.JSONUnmarshaler(new(testproto.DummyResponse)) work := func(i int) { defer wg.Done() rng := rand.New(rand.NewSource(time.Now().UnixNano())) ep := names[rng.Int()%len(names)] for i := 0; i < 100; i++ { req := mercury.NewRequest() req.SetService(testServiceName) req.SetEndpoint(ep) req.SetBody(&testproto.DummyRequest{}) suite.Assert().NoError(tmsg.JSONMarshaler().MarshalBody(req)) rsp, err := suite.trans.Send(req, time.Second) suite.Require().NoError(err) suite.Require().NotNil(rsp) suite.Require().NoError(unmarshaler.UnmarshalPayload(rsp)) response := rsp.Body().(*testproto.DummyResponse) suite.Assert().Equal(ep, response.Pong) } } for i := 0; i < workers; i++ { go work(i) } wg.Wait() }
// TestEndpointNotFound tests that a Bad Request error is correctly returned on receiving an event for an unknown // endpoing func (suite *serverSuite) TestEndpointNotFound() { req := mercury.NewRequest() req.SetService(testServiceName) req.SetEndpoint("dummy") req.SetBody(&testproto.DummyRequest{ Ping: "routing"}) suite.Assert().NoError(tmsg.JSONMarshaler().MarshalBody(req)) rsp_, err := suite.trans.Send(req, time.Second) rsp := mercury.FromTyphonResponse(rsp_) suite.Require().NoError(err) suite.Require().NotNil(rsp) suite.Assert().True(rsp.IsError()) suite.Assert().NoError(tmsg.JSONUnmarshaler(new(pe.Error)).UnmarshalPayload(rsp)) suite.Assert().IsType(new(pe.Error), rsp.Body()) terr := terrors.Unmarshal(rsp.Body().(*pe.Error)) suite.Assert().Equal(terrors.ErrBadRequest+".endpoint_not_found", terr.Code) suite.Assert().Contains(terr.Error(), "Endpoint not found") }