Skip to content

Commit

Permalink
feat(pubsub/pstest)!: Add status code to error injection (#2926)
Browse files Browse the repository at this point in the history
A status code is added into `errorInjectionReactor`, this is necessary
as the retry setting for some calls depends on the error code. Also
the `errorInjectionReactor` is not exported. Note that the previous
version is same as having an `Unknown` code as the server will always
wrap the error to a proper status error.

BREAKING CHANGE: this will invalidate the previous exported
ErrorInjectionReactor struct and WithErrorInjection function.
  • Loading branch information
Zhongduo Lin (Jimmy) committed Sep 28, 2020
1 parent 9f44d66 commit b084dce
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 11 deletions.
20 changes: 11 additions & 9 deletions pubsub/pstest/fake.go
Original file line number Diff line number Diff line change
Expand Up @@ -1171,20 +1171,22 @@ func (s *GServer) runReactor(req interface{}, funcName string, defaultObj interf
return false, nil, nil
}

// ErrorInjectionReactor is a reactor to inject an error message
type ErrorInjectionReactor struct {
errMsg string
// errorInjectionReactor is a reactor to inject an error message with status code.
type errorInjectionReactor struct {
code codes.Code
msg string
}

// React simply returns an error with defined error message.
func (e *ErrorInjectionReactor) React(_ interface{}) (handled bool, ret interface{}, err error) {
return true, nil, fmt.Errorf(e.errMsg)
// React simply returns an error with defined error message and status code.
func (e *errorInjectionReactor) React(_ interface{}) (handled bool, ret interface{}, err error) {
return true, nil, status.Errorf(e.code, e.msg)
}

// WithErrorInjection creates a ServerReactorOption that injects error for a certain function.
func WithErrorInjection(funcName string, errMsg string) ServerReactorOption {
// WithErrorInjection creates a ServerReactorOption that injects error with defined status code and
// message for a certain function.
func WithErrorInjection(funcName string, code codes.Code, msg string) ServerReactorOption {
return ServerReactorOption{
FuncName: funcName,
Reactor: &ErrorInjectionReactor{errMsg: errMsg},
Reactor: &errorInjectionReactor{code: code, msg: msg},
}
}
13 changes: 11 additions & 2 deletions pubsub/pstest/fake_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -951,15 +951,19 @@ func TestErrorInjection(t *testing.T) {
testcases := []struct {
funcName string
param interface{}
code codes.Code
}{
{
funcName: "CreateTopic",
code: codes.Internal,
},
{
funcName: "GetTopic",
code: codes.Aborted,
},
{
funcName: "UpdateTopic",
code: codes.DeadlineExceeded,
},
{
funcName: "ListTopics",
Expand Down Expand Up @@ -1010,8 +1014,13 @@ func TestErrorInjection(t *testing.T) {
for _, tc := range testcases {
ctx := context.TODO()
errMsg := "error-injection-" + tc.funcName
// set error code to unknown unless specified
ec := codes.Unknown
if tc.code != codes.OK {
ec = tc.code
}
opts := []ServerReactorOption{
WithErrorInjection(tc.funcName, errMsg),
WithErrorInjection(tc.funcName, ec, errMsg),
}
_, _, server, cleanup := newFake(ctx, t, opts...)
defer cleanup()
Expand All @@ -1033,7 +1042,7 @@ func TestErrorInjection(t *testing.T) {
ret := reflect.ValueOf(&server.GServer).MethodByName(tc.funcName).Call([]reflect.Value{reflect.ValueOf(ctx), req})

got := ret[1].Interface().(error)
if got == nil || !strings.Contains(got.Error(), errMsg) {
if got == nil || status.Code(got) != ec || !strings.Contains(got.Error(), errMsg) {
t.Errorf("Got error does not contain the right key %v", got)
}
}
Expand Down

0 comments on commit b084dce

Please sign in to comment.