From c49c3f189470bfeb1a9954fef02babcce083f2ec Mon Sep 17 00:00:00 2001 From: Mark Chmarny Date: Wed, 4 Nov 2020 08:56:52 -0800 Subject: [PATCH] adds grpc serving error tests (#102) --- service/grpc/binding_test.go | 22 +++++++ service/grpc/invoke_test.go | 28 +++++++++ service/grpc/service_test.go | 10 ++++ service/grpc/topic_test.go | 108 +++++++++++++++++++++++++++++++++-- 4 files changed, 164 insertions(+), 4 deletions(-) diff --git a/service/grpc/binding_test.go b/service/grpc/binding_test.go index 76c1657..7cc7591 100644 --- a/service/grpc/binding_test.go +++ b/service/grpc/binding_test.go @@ -7,6 +7,7 @@ import ( "github.com/dapr/go-sdk/dapr/proto/runtime/v1" "github.com/dapr/go-sdk/service/common" + "github.com/golang/protobuf/ptypes/empty" "github.com/stretchr/testify/assert" ) @@ -17,6 +18,27 @@ func testBindingHandler(ctx context.Context, in *common.BindingEvent) (out []byt return in.Data, nil } +func TestListInputBindings(t *testing.T) { + server := getTestServer() + err := server.AddBindingInvocationHandler("test1", testBindingHandler) + assert.NoError(t, err) + err = server.AddBindingInvocationHandler("test2", testBindingHandler) + assert.NoError(t, err) + resp, err := server.ListInputBindings(context.Background(), &empty.Empty{}) + assert.NoError(t, err) + assert.NotNil(t, resp) + assert.Lenf(t, resp.Bindings, 2, "expected 2 handlers") +} + +func TestBindingForErrors(t *testing.T) { + server := getTestServer() + err := server.AddBindingInvocationHandler("", nil) + assert.Errorf(t, err, "expected error on nil method name") + + err = server.AddBindingInvocationHandler("test", nil) + assert.Errorf(t, err, "expected error on nil method handler") +} + // go test -timeout 30s ./service/grpc -count 1 -run ^TestBinding$ func TestBinding(t *testing.T) { ctx := context.Background() diff --git a/service/grpc/invoke_test.go b/service/grpc/invoke_test.go index 66319f2..6f108fa 100644 --- a/service/grpc/invoke_test.go +++ b/service/grpc/invoke_test.go @@ -6,6 +6,7 @@ import ( "github.com/dapr/go-sdk/dapr/proto/common/v1" cc "github.com/dapr/go-sdk/service/common" + "github.com/pkg/errors" "github.com/stretchr/testify/assert" "google.golang.org/protobuf/types/known/anypb" ) @@ -21,14 +22,31 @@ func testInvokeHandler(ctx context.Context, in *cc.InvocationEvent) (out *cc.Con return } +func testInvokeHandlerWithError(ctx context.Context, in *cc.InvocationEvent) (out *cc.Content, err error) { + return nil, errors.New("test error") +} + +func TestInvokeErrors(t *testing.T) { + server := getTestServer() + err := server.AddServiceInvocationHandler("", nil) + assert.Error(t, err) + err = server.AddServiceInvocationHandler("test", nil) + assert.Error(t, err) +} + // go test -timeout 30s ./service/grpc -count 1 -run ^TestInvoke$ func TestInvoke(t *testing.T) { methodName := "test" + methodNameWithError := "error" ctx := context.Background() server := getTestServer() err := server.AddServiceInvocationHandler(methodName, testInvokeHandler) assert.Nil(t, err) + + err = server.AddServiceInvocationHandler(methodNameWithError, testInvokeHandlerWithError) + assert.Nil(t, err) + startTestServer(server) t.Run("invoke without request", func(t *testing.T) { @@ -61,5 +79,15 @@ func TestInvoke(t *testing.T) { assert.Equal(t, data, string(out.Data.Value)) }) + t.Run("invoke request with error", func(t *testing.T) { + data := "hello there" + dataContentType := "text/plain" + in := &common.InvokeRequest{Method: methodNameWithError} + in.Data = &anypb.Any{Value: []byte(data)} + in.ContentType = dataContentType + _, err := server.OnInvoke(ctx, in) + assert.Error(t, err) + }) + stopTestServer(t, server) } diff --git a/service/grpc/service_test.go b/service/grpc/service_test.go index 9c92a67..ed86150 100644 --- a/service/grpc/service_test.go +++ b/service/grpc/service_test.go @@ -13,6 +13,16 @@ func TestServer(t *testing.T) { stopTestServer(t, server) } +func TestServerWithListener(t *testing.T) { + server := NewServiceWithListener(bufconn.Listen(1024 * 1024)) + assert.NotNil(t, server) +} + +func TestService(t *testing.T) { + _, err := NewService("") + assert.Errorf(t, err, "expected error from lack of address") +} + func getTestServer() *Server { return newService(bufconn.Listen(1024 * 1024)) } diff --git a/service/grpc/topic_test.go b/service/grpc/topic_test.go index acc0d7f..dbe7308 100644 --- a/service/grpc/topic_test.go +++ b/service/grpc/topic_test.go @@ -7,19 +7,46 @@ import ( "github.com/dapr/go-sdk/dapr/proto/runtime/v1" "github.com/dapr/go-sdk/service/common" + "github.com/golang/protobuf/ptypes/empty" "github.com/stretchr/testify/assert" ) -func eventHandler(ctx context.Context, event *common.TopicEvent) (retry bool, err error) { - if event == nil { - return true, errors.New("nil event") +func TestTopicErrors(t *testing.T) { + server := getTestServer() + err := server.AddTopicEventHandler(nil, nil) + assert.Errorf(t, err, "expected error on nil sub") + + sub := &common.Subscription{} + err = server.AddTopicEventHandler(sub, nil) + assert.Errorf(t, err, "expected error on invalid sub") + + sub.PubsubName = "messages" + err = server.AddTopicEventHandler(sub, nil) + assert.Errorf(t, err, "expected error on sub without topic") + + sub.Topic = "test" + err = server.AddTopicEventHandler(sub, nil) + assert.Errorf(t, err, "expected error on sub without handler") +} + +func TestTopicSubscriptionList(t *testing.T) { + sub := &common.Subscription{ + PubsubName: "messages", + Topic: "test", } - return false, nil + server := getTestServer() + err := server.AddTopicEventHandler(sub, eventHandler) + assert.Nil(t, err) + resp, err := server.ListTopicSubscriptions(context.Background(), &empty.Empty{}) + assert.NoError(t, err) + assert.NotNil(t, resp) + assert.Lenf(t, resp.Subscriptions, 1, "expected 1 handlers") } // go test -timeout 30s ./service/grpc -count 1 -run ^TestTopic$ func TestTopic(t *testing.T) { ctx := context.Background() + sub := &common.Subscription{ PubsubName: "messages", Topic: "test", @@ -28,6 +55,7 @@ func TestTopic(t *testing.T) { err := server.AddTopicEventHandler(sub, eventHandler) assert.Nil(t, err) + startTestServer(server) t.Run("topic event without request", func(t *testing.T) { @@ -60,3 +88,75 @@ func TestTopic(t *testing.T) { stopTestServer(t, server) } + +func TestTopicWithErrors(t *testing.T) { + ctx := context.Background() + + sub1 := &common.Subscription{ + PubsubName: "messages", + Topic: "test1", + } + + sub2 := &common.Subscription{ + PubsubName: "messages", + Topic: "test2", + } + server := getTestServer() + + err := server.AddTopicEventHandler(sub1, eventHandlerWithRetryError) + assert.Nil(t, err) + + err = server.AddTopicEventHandler(sub2, eventHandlerWithError) + assert.Nil(t, err) + + startTestServer(server) + + t.Run("topic event for retry error", func(t *testing.T) { + in := &runtime.TopicEventRequest{ + Id: "a123", + Source: "test", + Type: "test", + SpecVersion: "v1.0", + DataContentType: "text/plain", + Data: []byte("test"), + Topic: sub1.Topic, + PubsubName: sub1.PubsubName, + } + resp, err := server.OnTopicEvent(ctx, in) + assert.Error(t, err) + assert.Equal(t, resp.GetStatus(), runtime.TopicEventResponse_RETRY) + }) + + t.Run("topic event for error", func(t *testing.T) { + in := &runtime.TopicEventRequest{ + Id: "a123", + Source: "test", + Type: "test", + SpecVersion: "v1.0", + DataContentType: "text/plain", + Data: []byte("test"), + Topic: sub2.Topic, + PubsubName: sub2.PubsubName, + } + resp, err := server.OnTopicEvent(ctx, in) + assert.Error(t, err) + assert.Equal(t, resp.GetStatus(), runtime.TopicEventResponse_DROP) + }) + + stopTestServer(t, server) +} + +func eventHandler(ctx context.Context, event *common.TopicEvent) (retry bool, err error) { + if event == nil { + return true, errors.New("nil event") + } + return false, nil +} + +func eventHandlerWithRetryError(ctx context.Context, event *common.TopicEvent) (retry bool, err error) { + return true, errors.New("nil event") +} + +func eventHandlerWithError(ctx context.Context, event *common.TopicEvent) (retry bool, err error) { + return false, errors.New("nil event") +}