package watcher import ( "sync" "testing" "github.com/go-test/deep" sp "github.com/linkerd/linkerd2/controller/gen/apis/serviceprofile/v1alpha2" "github.com/linkerd/linkerd2/controller/k8s" ) // DeletingProfileListener implements ProfileUpdateListener and registers // deletions. Useful for unit testing type DeletingProfileListener struct { NumDeletes int } // NewDeletingProfileListener creates a new NewDeletingProfileListener. func NewDeletingProfileListener() *DeletingProfileListener { return &DeletingProfileListener{ NumDeletes: 0, } } // Update registers a deletion func (dpl *DeletingProfileListener) Update(profile *sp.ServiceProfile) { if profile == nil { dpl.NumDeletes++ } } // BufferingProfileListener implements ProfileUpdateListener and stores updates // in a slice. Useful for unit tests. type BufferingProfileListener struct { Profiles []*sp.ServiceProfile mu sync.RWMutex } // NewBufferingProfileListener creates a new BufferingProfileListener. func NewBufferingProfileListener() *BufferingProfileListener { return &BufferingProfileListener{ Profiles: []*sp.ServiceProfile{}, } } func CreateMockDecoder(configs ...string) configDecoder { // Create a mock decoder with some random objs to satisfy client creation return func(data []byte, cluster string, enableEndpointSlices bool) (*k8s.API, *k8s.MetadataAPI, error) { remoteAPI, err := k8s.NewFakeAPI(configs...) if err != nil { return nil, nil, err } metadataAPI, err := k8s.NewFakeMetadataAPI(nil) if err != nil { return nil, nil, err } return remoteAPI, metadataAPI, nil } } // Update stores the update in the internal buffer. func (bpl *BufferingProfileListener) Update(profile *sp.ServiceProfile) { bpl.mu.Lock() defer bpl.mu.Unlock() bpl.Profiles = append(bpl.Profiles, profile) } func testCompare(t *testing.T, expected interface{}, actual interface{}) { t.Helper() if diff := deep.Equal(expected, actual); diff != nil { t.Fatalf("%v", diff) } }