linkerd2/controller/cmd/service-mirror/cluster_watcher_probe_event...

215 lines
6.4 KiB
Go

package servicemirror
import (
"fmt"
"reflect"
"testing"
v1 "k8s.io/api/core/v1"
"k8s.io/client-go/util/workqueue"
)
type BufferingProbeEventSink struct {
events []interface{}
}
func (s *BufferingProbeEventSink) send(event interface{}) {
s.events = append(s.events, event)
}
type probeEventsTestCase struct {
description string
environment *testEnvironment
expectedEventsSentToProbeManager []interface{}
}
func (tc *probeEventsTestCase) run(t *testing.T) {
t.Run(tc.description, func(t *testing.T) {
q := workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter())
probeEventsSink := &BufferingProbeEventSink{}
_, err := tc.environment.runEnvironment(probeEventsSink, q)
if err != nil {
t.Fatal(err)
}
expectedNumEvents := len(tc.expectedEventsSentToProbeManager)
actualNumEvents := len(probeEventsSink.events)
if expectedNumEvents != actualNumEvents {
t.Fatalf("Was expecting %d events but got %d", expectedNumEvents, actualNumEvents)
}
for i, ev := range tc.expectedEventsSentToProbeManager {
evInQueue := probeEventsSink.events[i]
if !reflect.DeepEqual(ev, evInQueue) {
t.Fatalf("was expecting to see event %T but got %T", ev, evInQueue)
}
}
})
}
func gatewaySpec(name, namespace, clustername, address, resVersion, identity string, incomingPort, probePort uint32, probePath string, probePeriod uint32) GatewaySpec {
return GatewaySpec{
gatewayName: name,
gatewayNamespace: namespace,
clusterName: clustername,
addresses: []v1.EndpointAddress{
{
IP: address,
},
},
incomingPort: incomingPort,
resourceVersion: resVersion,
identity: identity,
ProbeConfig: &ProbeConfig{
path: probePath,
port: probePort,
periodInSeconds: probePeriod,
},
}
}
func TestRemoteServiceCreatedProbeEvents(t *testing.T) {
for _, tt := range []probeEventsTestCase{
{
description: "do not send event if gateway cannot be resolved",
environment: serviceCreateWithMissingGateway,
expectedEventsSentToProbeManager: []interface{}{},
},
{
description: "do not send event if gateway has wrong spec",
environment: createServiceWrongGatewaySpec,
expectedEventsSentToProbeManager: []interface{}{},
},
{
description: "create service and endpoints when gateway can be resolved",
environment: createServiceOkeGatewaySpec,
expectedEventsSentToProbeManager: []interface{}{
&MirroredServicePaired{
serviceName: fmt.Sprintf("service-one-%s", clusterName),
serviceNamespace: "ns1",
GatewaySpec: gatewaySpec("existing-gateway", "existing-namespace", clusterName, "192.0.2.127", "222", "gateway-identity", 888, defaultProbePort, defaultProbePath, defaultProbePeriod),
},
},
},
} {
tc := tt // pin
tc.run(t)
}
}
func TestRemoteServiceDeletedProbeEvents(t *testing.T) {
for _, tt := range []probeEventsTestCase{
{
description: "send a service unpaired event",
environment: deleteMirroredService,
expectedEventsSentToProbeManager: []interface{}{
&MirroredServiceUnpaired{
serviceName: fmt.Sprintf("test-service-remote-to-delete-%s", clusterName),
serviceNamespace: "test-namespace-to-delete",
gatewayName: "gateway",
gatewayNs: "gateway-ns",
clusterName: clusterName,
},
},
},
} {
tc := tt // pin
tc.run(t)
}
}
func TestRemoteServiceUpdatedProbeEvents(t *testing.T) {
for _, tt := range []probeEventsTestCase{
{
description: "unpairs from old and pairs to new gateway",
environment: updateServiceToNewGateway,
expectedEventsSentToProbeManager: []interface{}{
&MirroredServiceUnpaired{
serviceName: fmt.Sprintf("test-service-%s", clusterName),
serviceNamespace: "test-namespace",
gatewayName: "gateway",
gatewayNs: "gateway-ns",
clusterName: clusterName,
},
&MirroredServicePaired{
serviceName: fmt.Sprintf("test-service-%s", clusterName),
serviceNamespace: "test-namespace",
GatewaySpec: gatewaySpec("gateway-new", "gateway-ns", clusterName, "0.0.0.0", "currentGatewayResVersion", "", 999, defaultProbePort, defaultProbePath, defaultProbePeriod),
},
},
},
{
description: "does not send event when gateway assignment does not change",
environment: updateServiceWithChangedPorts,
},
} {
tc := tt // pin
tc.run(t)
}
}
func TestRemoteGatewayUpdatedProbeEvents(t *testing.T) {
for _, tt := range []probeEventsTestCase{
{
description: "sends gateway updated when endpoints ports",
environment: remoteGatewayUpdated,
expectedEventsSentToProbeManager: []interface{}{
&GatewayUpdated{
GatewaySpec: gatewaySpec("gateway", "gateway-ns", clusterName, "0.0.0.0", "currentGatewayResVersion", "", 999, defaultProbePort, defaultProbePath, defaultProbePeriod),
},
},
},
{
description: "sends gateway updated when address changes",
environment: gatewayAddressChanged,
expectedEventsSentToProbeManager: []interface{}{
&GatewayUpdated{
GatewaySpec: gatewaySpec("gateway", "gateway-ns", "some-cluster", "0.0.0.1", "currentGatewayResVersion", "", 888, 1, "/p", 222),
},
},
},
{
description: "sends gateway updated when identity changes",
environment: gatewayIdentityChanged,
expectedEventsSentToProbeManager: []interface{}{
&GatewayUpdated{
GatewaySpec: gatewaySpec("gateway", "gateway-ns", clusterName, "0.0.0.0", "currentGatewayResVersion", "new-identity", 888, defaultProbePort, defaultProbePath, defaultProbePeriod),
},
},
},
{
description: "sends gateway updated when probe changes",
environment: gatewayProbeConfigChanged,
expectedEventsSentToProbeManager: []interface{}{
&GatewayUpdated{
GatewaySpec: gatewaySpec("gateway", "gateway-ns", clusterName, "0.0.0.0", "currentGatewayResVersion", "identity", 888, defaultProbePort, "/new-path", defaultProbePeriod),
},
},
},
} {
tc := tt // pin
tc.run(t)
}
}
func TestRemoteGatewayDeletedProbeEvents(t *testing.T) {
for _, tt := range []probeEventsTestCase{
{
description: "sends a gateway deleted event to the probe manager",
environment: gatewayDeleted,
expectedEventsSentToProbeManager: []interface{}{
&GatewayDeleted{
gatewayName: "gateway",
gatewayNs: "gateway-ns",
clusterName: clusterName,
},
},
},
} {
tc := tt // pin
tc.run(t)
}
}