233 lines
6.7 KiB
Go
233 lines
6.7 KiB
Go
package mq
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestNormalizeSubscriptionSetValidDeclaration(t *testing.T) {
|
|
handler := func(context.Context, Message) {}
|
|
set := SubscriptionSet{
|
|
Owner: " orders ",
|
|
Provider: " RABBITMQ ",
|
|
Topics: []TopicSubscription{
|
|
{Topic: " orders.created ", QoS: AtMostOnce, Handler: handler},
|
|
{Topic: "orders.updated", QoS: AtLeastOnce, Handler: handler},
|
|
{Topic: "orders.deleted", QoS: ExactlyOnce, Handler: handler},
|
|
},
|
|
}
|
|
|
|
got, err := NormalizeSubscriptionSet(set)
|
|
if err != nil {
|
|
t.Fatalf("NormalizeSubscriptionSet() error = %v", err)
|
|
}
|
|
|
|
want := SubscriptionSet{
|
|
Owner: "orders",
|
|
Provider: ProviderRabbitMQ,
|
|
Topics: []TopicSubscription{
|
|
{Topic: "orders.created", QoS: AtMostOnce, Handler: handler},
|
|
{Topic: "orders.updated", QoS: AtLeastOnce, Handler: handler},
|
|
{Topic: "orders.deleted", QoS: ExactlyOnce, Handler: handler},
|
|
},
|
|
}
|
|
if got.Owner != want.Owner || got.Provider != want.Provider {
|
|
t.Fatalf("normalized identity = %#v, want owner=%q provider=%q", got, want.Owner, want.Provider)
|
|
}
|
|
if len(got.Topics) != len(want.Topics) {
|
|
t.Fatalf("normalized topic count = %d, want %d", len(got.Topics), len(want.Topics))
|
|
}
|
|
for index := range want.Topics {
|
|
if got.Topics[index].Topic != want.Topics[index].Topic {
|
|
t.Errorf("topic[%d] = %q, want %q", index, got.Topics[index].Topic, want.Topics[index].Topic)
|
|
}
|
|
if got.Topics[index].QoS != want.Topics[index].QoS {
|
|
t.Errorf("qos[%d] = %d, want %d", index, got.Topics[index].QoS, want.Topics[index].QoS)
|
|
}
|
|
if reflect.ValueOf(got.Topics[index].Handler).Pointer() != reflect.ValueOf(want.Topics[index].Handler).Pointer() {
|
|
t.Errorf("handler[%d] was changed", index)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestNormalizeSubscriptionSetRejectsInvalidDeclarations(t *testing.T) {
|
|
handler := func(context.Context, Message) {}
|
|
base := func() SubscriptionSet {
|
|
return SubscriptionSet{
|
|
Owner: "orders",
|
|
Provider: ProviderEMQX,
|
|
Topics: []TopicSubscription{
|
|
{Topic: "orders.created", QoS: AtLeastOnce, Handler: handler},
|
|
},
|
|
}
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
set SubscriptionSet
|
|
wantErr string
|
|
}{
|
|
{
|
|
name: "empty owner",
|
|
set: func() SubscriptionSet { set := base(); set.Owner = " "; return set }(),
|
|
wantErr: "owner is empty",
|
|
},
|
|
{
|
|
name: "empty provider",
|
|
set: func() SubscriptionSet { set := base(); set.Provider = " "; return set }(),
|
|
wantErr: "unsupported mq provider",
|
|
},
|
|
{
|
|
name: "unsupported provider",
|
|
set: func() SubscriptionSet { set := base(); set.Provider = "kafka"; return set }(),
|
|
wantErr: "unsupported mq provider",
|
|
},
|
|
{
|
|
name: "empty topics",
|
|
set: func() SubscriptionSet { set := base(); set.Topics = nil; return set }(),
|
|
wantErr: "topics are empty",
|
|
},
|
|
{
|
|
name: "empty topic",
|
|
set: func() SubscriptionSet {
|
|
set := base()
|
|
set.Topics[0].Topic = " "
|
|
return set
|
|
}(),
|
|
wantErr: "topic at index 0 is empty",
|
|
},
|
|
{
|
|
name: "duplicate topic",
|
|
set: func() SubscriptionSet {
|
|
set := base()
|
|
set.Topics = append(set.Topics, TopicSubscription{
|
|
Topic: " orders.created ", QoS: AtMostOnce, Handler: handler,
|
|
})
|
|
return set
|
|
}(),
|
|
wantErr: "duplicate mq subscription topic",
|
|
},
|
|
{
|
|
name: "nil handler",
|
|
set: func() SubscriptionSet {
|
|
set := base()
|
|
set.Topics[0].Handler = nil
|
|
return set
|
|
}(),
|
|
wantErr: "handler is nil",
|
|
},
|
|
{
|
|
name: "invalid qos",
|
|
set: func() SubscriptionSet {
|
|
set := base()
|
|
set.Topics[0].QoS = ExactlyOnce + 1
|
|
return set
|
|
}(),
|
|
wantErr: "invalid mq qos",
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
_, err := NormalizeSubscriptionSet(test.set)
|
|
if err == nil {
|
|
t.Fatal("NormalizeSubscriptionSet() error = nil, want error")
|
|
}
|
|
if !strings.Contains(err.Error(), test.wantErr) {
|
|
t.Fatalf("error = %q, want substring %q", err, test.wantErr)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
type subscriptionTestRegistrar struct {
|
|
sets []SubscriptionSet
|
|
}
|
|
|
|
func (r *subscriptionTestRegistrar) Register(set SubscriptionSet) error {
|
|
r.sets = append(r.sets, set)
|
|
return nil
|
|
}
|
|
|
|
func (*subscriptionTestRegistrar) Unregister(string) error { return nil }
|
|
|
|
type subscriptionTestContributor struct {
|
|
name string
|
|
set SubscriptionSet
|
|
order *[]string
|
|
err error
|
|
}
|
|
|
|
func (c *subscriptionTestContributor) RegisterSubscriptions(registrar SubscriptionRegistrar) error {
|
|
*c.order = append(*c.order, c.name)
|
|
if c.err != nil {
|
|
return c.err
|
|
}
|
|
return registrar.Register(c.set)
|
|
}
|
|
|
|
func TestApplySubscriptionsAppliesMultipleContributorsInOrder(t *testing.T) {
|
|
order := make([]string, 0, 2)
|
|
registrar := &subscriptionTestRegistrar{}
|
|
handler := func(context.Context, Message) {}
|
|
first := &subscriptionTestContributor{
|
|
name: "orders",
|
|
order: &order,
|
|
set: SubscriptionSet{
|
|
Owner: "orders",
|
|
Provider: ProviderRabbitMQ,
|
|
Topics: []TopicSubscription{{Topic: "orders.created", Handler: handler}},
|
|
},
|
|
}
|
|
second := &subscriptionTestContributor{
|
|
name: "notifications",
|
|
order: &order,
|
|
set: SubscriptionSet{
|
|
Owner: "notifications",
|
|
Provider: ProviderEMQX,
|
|
Topics: []TopicSubscription{{Topic: "notifications.sent", Handler: handler}},
|
|
},
|
|
}
|
|
|
|
if err := ApplySubscriptions(registrar, first, nil, second); err != nil {
|
|
t.Fatalf("ApplySubscriptions() error = %v", err)
|
|
}
|
|
if !reflect.DeepEqual(order, []string{"orders", "notifications"}) {
|
|
t.Fatalf("contributor order = %#v, want %#v", order, []string{"orders", "notifications"})
|
|
}
|
|
if len(registrar.sets) != 2 {
|
|
t.Fatalf("registered sets = %d, want 2", len(registrar.sets))
|
|
}
|
|
if registrar.sets[0].Owner != "orders" || registrar.sets[1].Owner != "notifications" {
|
|
t.Fatalf("registered owners = %q, %q", registrar.sets[0].Owner, registrar.sets[1].Owner)
|
|
}
|
|
}
|
|
|
|
func TestApplySubscriptionsPropagatesContributorError(t *testing.T) {
|
|
order := make([]string, 0, 2)
|
|
registrar := &subscriptionTestRegistrar{}
|
|
wantErr := errors.New("registration failed")
|
|
failing := &subscriptionTestContributor{name: "failing", order: &order, err: wantErr}
|
|
following := &subscriptionTestContributor{name: "following", order: &order}
|
|
|
|
err := ApplySubscriptions(registrar, failing, following)
|
|
if !errors.Is(err, wantErr) {
|
|
t.Fatalf("ApplySubscriptions() error = %v, want %v", err, wantErr)
|
|
}
|
|
if !reflect.DeepEqual(order, []string{"failing"}) {
|
|
t.Fatalf("contributors called = %#v, want %#v", order, []string{"failing"})
|
|
}
|
|
if len(registrar.sets) != 0 {
|
|
t.Fatalf("registered sets = %d, want 0", len(registrar.sets))
|
|
}
|
|
}
|
|
|
|
func TestApplySubscriptionsRejectsNilRegistrar(t *testing.T) {
|
|
if err := ApplySubscriptions(nil); err == nil || !strings.Contains(err.Error(), "registrar is nil") {
|
|
t.Fatalf("ApplySubscriptions(nil) error = %v, want nil-registrar error", err)
|
|
}
|
|
}
|