linkerd2/controller/api/destination/test_helper.go

127 lines
3.7 KiB
Go

package destination
import (
"context"
"fmt"
proxyNet "github.com/linkerd/linkerd2-proxy-api/go/net"
sp "github.com/linkerd/linkerd2/controller/gen/apis/serviceprofile/v1alpha1"
"github.com/linkerd/linkerd2/pkg/addr"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
type collectListener struct {
context context.Context
stopCh chan struct{}
}
func (c *collectListener) ClientClose() <-chan struct{} {
return c.context.Done()
}
func (c *collectListener) ServerClose() <-chan struct{} {
return c.stopCh
}
func (c *collectListener) Stop() {
close(c.stopCh)
}
// implements the endpointUpdateListener interface
type collectUpdateListener struct {
collectListener
added []*updateAddress
removed []*updateAddress
noEndpointsCalled bool
noEndpointsExists bool
}
func (c *collectUpdateListener) Update(add, remove []*updateAddress) {
c.added = append(c.added, add...)
c.removed = append(c.removed, remove...)
}
func (c *collectUpdateListener) NoEndpoints(exists bool) {
c.noEndpointsCalled = true
c.noEndpointsExists = exists
}
func (c *collectUpdateListener) SetServiceID(id *serviceID) {}
func newCollectUpdateListener() (*collectUpdateListener, context.CancelFunc) {
ctx, cancelFn := context.WithCancel(context.Background())
return &collectUpdateListener{collectListener: collectListener{context: ctx}}, cancelFn
}
// implements the profileUpdateListener interface
type collectProfileListener struct {
collectListener
profiles []*sp.ServiceProfile
}
func (c *collectProfileListener) Update(profile *sp.ServiceProfile) {
c.profiles = append(c.profiles, profile)
}
func newCollectProfileListener() (*collectProfileListener, context.CancelFunc) {
ctx, cancelFn := context.WithCancel(context.Background())
return &collectProfileListener{collectListener: collectListener{context: ctx}}, cancelFn
}
// validate whether two servicePorts structs are equal
func equalServicePorts(servicePorts1, servicePorts2 servicePorts) error {
if len(servicePorts1) != len(servicePorts2) {
return fmt.Errorf("servicePorts length mismatch: [%+v] != [%+v]", servicePorts1, servicePorts2)
}
for serviceID := range servicePorts1 {
portMap1 := servicePorts1[serviceID]
portMap2 := servicePorts2[serviceID]
if len(portMap1) != len(portMap2) {
return fmt.Errorf("servicePorts portMap length mismatch: [%+v] != [%+v]", portMap1, portMap2)
}
for port := range portMap1 {
sp1 := portMap1[port]
sp2 := portMap2[port]
if sp1.port != sp2.port {
return fmt.Errorf("servicePort port mismatch: [%+v] != [%+v]", sp1.port, sp2.port)
}
if sp1.targetPort != sp2.targetPort {
return fmt.Errorf("servicePort targetPort mismatch: [%+v] != [%+v]", sp1.targetPort, sp2.targetPort)
}
if sp1.service != sp2.service {
return fmt.Errorf("servicePort service mismatch: [%+v] != [%+v]", sp1.service, sp2.service)
}
if len(sp1.addresses) != len(sp2.addresses) {
return fmt.Errorf("servicePort addresses mismatch: [%+v] != [%+v]", sp1.addresses, sp2.addresses)
}
if sp1.endpoints.String() != sp2.endpoints.String() {
return fmt.Errorf("servicePort endpoints mismatch: [%s] != [%s]", sp1.endpoints, sp2.endpoints)
}
for i := range sp1.addresses {
if sp1.addresses[i].String() != sp2.addresses[i].String() {
return fmt.Errorf("servicePort address mismatch: [%s] != [%s]", sp1.addresses[i], sp2.addresses[i])
}
}
}
}
return nil
}
func makeUpdateAddress(ipStr string, portNum uint32, name string) *updateAddress {
ip, _ := addr.ParseProxyIPV4(ipStr)
return &updateAddress{
address: &proxyNet.TcpAddress{Ip: ip, Port: portNum},
pod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Namespace: "ns",
Name: name,
},
},
}
}