go-sdk/service/grpc/topic_test.go

240 lines
5.9 KiB
Go

package grpc
import (
"context"
"errors"
"testing"
"github.com/golang/protobuf/ptypes/empty"
"github.com/stretchr/testify/assert"
runtime "github.com/dapr/dapr/pkg/proto/runtime/v1"
"github.com/dapr/go-sdk/service/common"
)
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",
}
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",
}
server := getTestServer()
err := server.AddTopicEventHandler(sub, eventHandler)
assert.Nil(t, err)
startTestServer(server)
t.Run("topic event without request", func(t *testing.T) {
_, err := server.OnTopicEvent(ctx, nil)
assert.Error(t, err)
})
t.Run("topic event for wrong topic", func(t *testing.T) {
in := &runtime.TopicEventRequest{
Topic: "invalid",
}
_, err := server.OnTopicEvent(ctx, in)
assert.Error(t, err)
})
t.Run("topic event for valid topic", func(t *testing.T) {
in := &runtime.TopicEventRequest{
Id: "a123",
Source: "test",
Type: "test",
SpecVersion: "v1.0",
DataContentType: "text/plain",
Data: []byte("test"),
Topic: sub.Topic,
PubsubName: sub.PubsubName,
}
_, err := server.OnTopicEvent(ctx, in)
assert.NoError(t, err)
})
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")
}
func TestEventDataHandling(t *testing.T) {
ctx := context.Background()
tests := map[string]struct {
contentType string
data string
value interface{}
}{
"JSON bytes": {
contentType: "application/json",
data: `{"message":"hello"}`,
value: map[string]interface{}{
"message": "hello",
},
},
"JSON entension media type bytes": {
contentType: "application/extension+json",
data: `{"message":"hello"}`,
value: map[string]interface{}{
"message": "hello",
},
},
"Test": {
contentType: "text/plain",
data: `message = hello`,
value: `message = hello`,
},
"Other": {
contentType: "application/octet-stream",
data: `message = hello`,
value: []byte(`message = hello`),
},
}
s := getTestServer()
sub := &common.Subscription{
PubsubName: "messages",
Topic: "test",
Route: "/test",
Metadata: map[string]string{},
}
recv := make(chan struct{}, 1)
var topicEvent *common.TopicEvent
handler := func(ctx context.Context, e *common.TopicEvent) (retry bool, err error) {
topicEvent = e
recv <- struct{}{}
return false, nil
}
err := s.AddTopicEventHandler(sub, handler)
assert.NoErrorf(t, err, "error adding event handler")
startTestServer(s)
for name, tt := range tests {
t.Run(name, func(t *testing.T) {
in := runtime.TopicEventRequest{
Id: "a123",
Source: "test",
Type: "test",
SpecVersion: "v1.0",
DataContentType: tt.contentType,
Data: []byte(tt.data),
Topic: sub.Topic,
PubsubName: sub.PubsubName,
}
s.OnTopicEvent(ctx, &in)
<-recv
assert.Equal(t, tt.value, topicEvent.Data)
})
}
}