Example #1
0
func (suite *clientSuite) SetupSuite() {
	trans := suite.TransF()
	select {
	case <-trans.Ready():
	case <-time.After(2 * time.Second):
		panic("transport not ready")
	}
	suite.trans = trans

	// Add a listener that responds blindly to all messages
	inboundChan := make(chan tmsg.Request, 10)
	trans.Listen(testServiceName, inboundChan)
	go func() {
		for {
			select {
			case _req := <-inboundChan:
				req := mercury.FromTyphonRequest(_req)
				switch req.Endpoint() {
				case "timeout":
					continue

				case "invalid-payload":
					// Wrong proto here
					rsp := req.Response(nil)
					rsp.SetPayload([]byte("†HÎß ßHøܬ∂ÑT ∑ø®K"))
					suite.Require().NoError(trans.Respond(req, rsp))

				case "error":
					err := terrors.BadRequest("", "foo bar", nil)
					rsp := req.Response(terrors.Marshal(err))
					rsp.SetHeaders(req.Headers())
					rsp.SetIsError(true)
					suite.Require().NoError(trans.Respond(req, rsp))

				case "bulls--t":
					rsp := req.Response(map[string]string{})
					rsp.SetHeaders(req.Headers())
					rsp.SetHeader(marshaling.ContentTypeHeader, "application/bulls--t")
					suite.Require().NoError(trans.Respond(req, rsp))

				default:
					rsp := req.Response(&testproto.DummyResponse{
						Pong: "Pong"})
					rsp.SetHeaders(req.Headers())
					suite.Require().NoError(tmsg.JSONMarshaler().MarshalBody(rsp))
					suite.Require().NoError(trans.Respond(req, rsp))
				}

			case <-trans.Tomb().Dying():
				return
			}
		}
	}()
}
Example #2
0
func (suite *errorSetSuite) TestMultiErrorPriority() {
	br := terrors.BadRequest("missing_param", "foo bar", nil)
	is := terrors.InternalService("something_broke", "hello world", nil)
	suite.Assert().True(higherPriority(is.Code, br.Code))
	se := terrors.New("something_else", "baz", nil)
	suite.Assert().True(higherPriority(is.Code, se.Code))
	suite.Assert().True(higherPriority(br.Code, se.Code))

	es := ErrorSet{se, is, br}
	suite.Assert().Equal(is.Code, es.Combined().(*terrors.Error).Code)
}
Example #3
0
// TestErrors verifies that an error sent from a handler is correctly returned by a client
func (suite *clientServerSuite) TestErrors() {
	suite.server.AddEndpoints(server.Endpoint{
		Name:     "error",
		Request:  new(testproto.DummyRequest),
		Response: new(testproto.DummyResponse),
		Handler: func(req mercury.Request) (mercury.Response, error) {
			return nil, terrors.BadRequest("", "naughty naughty", nil)
		}})

	cl := client.NewClient().
		SetMiddleware(DefaultClientMiddleware()).
		Add(
			client.Call{
				Uid:      "call",
				Service:  testServiceName,
				Endpoint: "error",
				Body:     &testproto.DummyRequest{},
				Response: &testproto.DummyResponse{},
			}).
		SetTransport(suite.trans).
		SetTimeout(time.Second).
		Execute()

	suite.Assert().True(cl.Errors().Any())
	err := cl.Errors().ForUid("call")
	suite.Require().NotNil(err)
	suite.Assert().Equal(terrors.ErrBadRequest, err.Code)

	rsp := mercury.FromTyphonResponse(cl.Response("call").Copy())
	rsp.SetBody("FOO") // Deliberately set this to verify it is not mutated while accessing the error
	suite.Require().NotNil(rsp)
	suite.Assert().True(rsp.IsError())
	suite.Assert().NotNil(rsp.Error())
	suite.Assert().IsType(&terrors.Error{}, rsp.Error())
	err = rsp.Error().(*terrors.Error)
	suite.Assert().Equal(terrors.ErrBadRequest, err.Code)
	suite.Assert().Equal("FOO", rsp.Body())
}
Example #4
0
	ttrans "github.com/mondough/typhon/transport"
	"golang.org/x/net/context"
	"gopkg.in/tomb.v2"

	"github.com/mondough/mercury"
	"github.com/mondough/mercury/transport"
)

const (
	connectTimeout = 30 * time.Second
)

var (
	ErrAlreadyRunning   error = terrors.InternalService("", "Server is already running", nil) // empty dotted code so impl details don't leak outside
	ErrTransportClosed  error = terrors.InternalService("", "Transport closed", nil)
	errEndpointNotFound       = terrors.BadRequest("endpoint_not_found", "Endpoint not found", nil)
	defaultMiddleware   []ServerMiddleware
	defaultMiddlewareM  sync.RWMutex
)

func NewServer(name string) Server {
	defaultMiddlewareM.RLock()
	middleware := defaultMiddleware
	defaultMiddlewareM.RUnlock()

	return &server{
		name:       name,
		middleware: middleware,
	}
}