chore(source/traefik_proxy): code coverage and refactoring (#5380)

Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
This commit is contained in:
Ivan Ka 2025-05-15 07:38:48 +01:00 committed by GitHub
parent 52382e7183
commit 4ea5f9df60
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 273 additions and 325 deletions

View File

@ -171,7 +171,7 @@ func NewTraefikSource(ctx context.Context, dynamicKubeClient dynamic.Interface,
}, nil
}
func (ts *traefikSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, error) {
func (ts *traefikSource) Endpoints(_ context.Context) ([]*endpoint.Endpoint, error) {
var endpoints []*endpoint.Endpoint
if ts.ingressRouteInformer != nil {
@ -226,54 +226,18 @@ func (ts *traefikSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, e
// ingressRouteEndpoints extracts endpoints from all IngressRoute objects
func (ts *traefikSource) ingressRouteEndpoints() ([]*endpoint.Endpoint, error) {
var endpoints []*endpoint.Endpoint
irs, err := ts.ingressRouteInformer.Lister().ByNamespace(ts.namespace).List(labels.Everything())
if err != nil {
return nil, err
}
var ingressRoutes []*IngressRoute
for _, ingressRouteObj := range irs {
unstructuredHost, ok := ingressRouteObj.(*unstructured.Unstructured)
if !ok {
return nil, errors.New("could not convert IngressRoute object to unstructured")
}
ingressRoute := &IngressRoute{}
err := ts.unstructuredConverter.scheme.Convert(unstructuredHost, ingressRoute, nil)
if err != nil {
return nil, err
}
ingressRoutes = append(ingressRoutes, ingressRoute)
}
ingressRoutes, err = ts.filterIngressRouteByAnnotation(ingressRoutes)
if err != nil {
return nil, fmt.Errorf("failed to filter IngressRoute: %w", err)
}
for _, ingressRoute := range ingressRoutes {
var targets endpoint.Targets
targets = append(targets, annotations.TargetsFromTargetAnnotation(ingressRoute.Annotations)...)
fullname := fmt.Sprintf("%s/%s", ingressRoute.Namespace, ingressRoute.Name)
ingressEndpoints, err := ts.endpointsFromIngressRoute(ingressRoute, targets)
if err != nil {
return nil, err
}
if len(ingressEndpoints) == 0 {
log.Debugf("No endpoints could be generated from Host %s", fullname)
continue
}
log.Debugf("Endpoints generated from IngressRoute: %s: %v", fullname, ingressEndpoints)
endpoints = append(endpoints, ingressEndpoints...)
}
return endpoints, nil
return extractEndpoints[IngressRoute](
ts.ingressRouteInformer.Lister(),
ts.namespace,
func(u *unstructured.Unstructured) (*IngressRoute, error) {
typed := &IngressRoute{}
return typed, ts.unstructuredConverter.scheme.Convert(u, typed, nil)
},
ts.filterIngressRouteByAnnotation,
func(r *IngressRoute, targets endpoint.Targets) []*endpoint.Endpoint {
return ts.endpointsFromIngressRoute(r, targets)
},
)
}
// ingressRouteTCPEndpoints extracts endpoints from all IngressRouteTCP objects
@ -312,10 +276,7 @@ func (ts *traefikSource) ingressRouteTCPEndpoints() ([]*endpoint.Endpoint, error
fullname := fmt.Sprintf("%s/%s", ingressRouteTCP.Namespace, ingressRouteTCP.Name)
ingressEndpoints, err := ts.endpointsFromIngressRouteTCP(ingressRouteTCP, targets)
if err != nil {
return nil, err
}
ingressEndpoints := ts.endpointsFromIngressRouteTCP(ingressRouteTCP, targets)
if len(ingressEndpoints) == 0 {
log.Debugf("No endpoints could be generated from Host %s", fullname)
continue
@ -330,286 +291,85 @@ func (ts *traefikSource) ingressRouteTCPEndpoints() ([]*endpoint.Endpoint, error
// ingressRouteUDPEndpoints extracts endpoints from all IngressRouteUDP objects
func (ts *traefikSource) ingressRouteUDPEndpoints() ([]*endpoint.Endpoint, error) {
var endpoints []*endpoint.Endpoint
irs, err := ts.ingressRouteUdpInformer.Lister().ByNamespace(ts.namespace).List(labels.Everything())
if err != nil {
return nil, err
}
var ingressRouteUDPs []*IngressRouteUDP
for _, ingressRouteUDPObj := range irs {
unstructuredHost, ok := ingressRouteUDPObj.(*unstructured.Unstructured)
if !ok {
return nil, errors.New("could not convert IngressRouteUDP object to unstructured")
}
ingressRoute := &IngressRouteUDP{}
err := ts.unstructuredConverter.scheme.Convert(unstructuredHost, ingressRoute, nil)
if err != nil {
return nil, err
}
ingressRouteUDPs = append(ingressRouteUDPs, ingressRoute)
}
ingressRouteUDPs, err = ts.filterIngressRouteUdpByAnnotations(ingressRouteUDPs)
if err != nil {
return nil, fmt.Errorf("failed to filter IngressRouteUDP: %w", err)
}
for _, ingressRouteUDP := range ingressRouteUDPs {
var targets endpoint.Targets
targets = append(targets, annotations.TargetsFromTargetAnnotation(ingressRouteUDP.Annotations)...)
fullname := fmt.Sprintf("%s/%s", ingressRouteUDP.Namespace, ingressRouteUDP.Name)
ingressEndpoints, err := ts.endpointsFromIngressRouteUDP(ingressRouteUDP, targets)
if err != nil {
return nil, err
}
if len(ingressEndpoints) == 0 {
log.Debugf("No endpoints could be generated from Host %s", fullname)
continue
}
log.Debugf("Endpoints generated from IngressRouteUDP: %s: %v", fullname, ingressEndpoints)
endpoints = append(endpoints, ingressEndpoints...)
}
return endpoints, nil
return extractEndpoints[IngressRouteUDP](
ts.ingressRouteUdpInformer.Lister(),
ts.namespace,
func(u *unstructured.Unstructured) (*IngressRouteUDP, error) {
typed := &IngressRouteUDP{}
return typed, ts.unstructuredConverter.scheme.Convert(u, typed, nil)
},
ts.filterIngressRouteUdpByAnnotations,
ts.endpointsFromIngressRouteUDP,
)
}
// oldIngressRouteEndpoints extracts endpoints from all IngressRoute objects
func (ts *traefikSource) oldIngressRouteEndpoints() ([]*endpoint.Endpoint, error) {
var endpoints []*endpoint.Endpoint
irs, err := ts.oldIngressRouteInformer.Lister().ByNamespace(ts.namespace).List(labels.Everything())
if err != nil {
return nil, err
}
var ingressRoutes []*IngressRoute
for _, ingressRouteObj := range irs {
unstructuredHost, ok := ingressRouteObj.(*unstructured.Unstructured)
if !ok {
return nil, errors.New("could not convert IngressRoute object to unstructured")
}
ingressRoute := &IngressRoute{}
err := ts.unstructuredConverter.scheme.Convert(unstructuredHost, ingressRoute, nil)
if err != nil {
return nil, err
}
ingressRoutes = append(ingressRoutes, ingressRoute)
}
ingressRoutes, err = ts.filterIngressRouteByAnnotation(ingressRoutes)
if err != nil {
return nil, fmt.Errorf("failed to filter IngressRoute: %w", err)
}
for _, ingressRoute := range ingressRoutes {
var targets endpoint.Targets
targets = append(targets, annotations.TargetsFromTargetAnnotation(ingressRoute.Annotations)...)
fullname := fmt.Sprintf("%s/%s", ingressRoute.Namespace, ingressRoute.Name)
ingressEndpoints, err := ts.endpointsFromIngressRoute(ingressRoute, targets)
if err != nil {
return nil, err
}
if len(ingressEndpoints) == 0 {
log.Debugf("No endpoints could be generated from Host %s", fullname)
continue
}
log.Debugf("Endpoints generated from IngressRoute: %s: %v", fullname, ingressEndpoints)
endpoints = append(endpoints, ingressEndpoints...)
}
return endpoints, nil
return extractEndpoints[IngressRoute](
ts.oldIngressRouteInformer.Lister(),
ts.namespace,
func(u *unstructured.Unstructured) (*IngressRoute, error) {
typed := &IngressRoute{}
return typed, ts.unstructuredConverter.scheme.Convert(u, typed, nil)
},
ts.filterIngressRouteByAnnotation,
func(r *IngressRoute, targets endpoint.Targets) []*endpoint.Endpoint {
return ts.endpointsFromIngressRoute(r, targets)
},
)
}
// oldIngressRouteTCPEndpoints extracts endpoints from all IngressRouteTCP objects
func (ts *traefikSource) oldIngressRouteTCPEndpoints() ([]*endpoint.Endpoint, error) {
var endpoints []*endpoint.Endpoint
irs, err := ts.oldIngressRouteTcpInformer.Lister().ByNamespace(ts.namespace).List(labels.Everything())
if err != nil {
return nil, err
}
var ingressRouteTCPs []*IngressRouteTCP
for _, ingressRouteTCPObj := range irs {
unstructuredHost, ok := ingressRouteTCPObj.(*unstructured.Unstructured)
if !ok {
return nil, errors.New("could not convert IngressRouteTCP object to unstructured")
}
ingressRouteTCP := &IngressRouteTCP{}
err := ts.unstructuredConverter.scheme.Convert(unstructuredHost, ingressRouteTCP, nil)
if err != nil {
return nil, err
}
ingressRouteTCPs = append(ingressRouteTCPs, ingressRouteTCP)
}
ingressRouteTCPs, err = ts.filterIngressRouteTcpByAnnotations(ingressRouteTCPs)
if err != nil {
return nil, fmt.Errorf("failed to filter IngressRouteTCP: %w", err)
}
for _, ingressRouteTCP := range ingressRouteTCPs {
var targets endpoint.Targets
targets = append(targets, annotations.TargetsFromTargetAnnotation(ingressRouteTCP.Annotations)...)
fullname := fmt.Sprintf("%s/%s", ingressRouteTCP.Namespace, ingressRouteTCP.Name)
ingressEndpoints, err := ts.endpointsFromIngressRouteTCP(ingressRouteTCP, targets)
if err != nil {
return nil, err
}
if len(ingressEndpoints) == 0 {
log.Debugf("No endpoints could be generated from Host %s", fullname)
continue
}
log.Debugf("Endpoints generated from IngressRouteTCP: %s: %v", fullname, ingressEndpoints)
endpoints = append(endpoints, ingressEndpoints...)
}
return endpoints, nil
return extractEndpoints[IngressRouteTCP](
ts.oldIngressRouteTcpInformer.Lister(),
ts.namespace,
func(u *unstructured.Unstructured) (*IngressRouteTCP, error) {
typed := &IngressRouteTCP{}
return typed, ts.unstructuredConverter.scheme.Convert(u, typed, nil)
},
ts.filterIngressRouteTcpByAnnotations,
ts.endpointsFromIngressRouteTCP,
)
}
// oldIngressRouteUDPEndpoints extracts endpoints from all IngressRouteUDP objects
func (ts *traefikSource) oldIngressRouteUDPEndpoints() ([]*endpoint.Endpoint, error) {
var endpoints []*endpoint.Endpoint
irs, err := ts.oldIngressRouteUdpInformer.Lister().ByNamespace(ts.namespace).List(labels.Everything())
if err != nil {
return nil, err
}
var ingressRouteUDPs []*IngressRouteUDP
for _, ingressRouteUDPObj := range irs {
unstructuredHost, ok := ingressRouteUDPObj.(*unstructured.Unstructured)
if !ok {
return nil, errors.New("could not convert IngressRouteUDP object to unstructured")
}
ingressRoute := &IngressRouteUDP{}
err := ts.unstructuredConverter.scheme.Convert(unstructuredHost, ingressRoute, nil)
if err != nil {
return nil, err
}
ingressRouteUDPs = append(ingressRouteUDPs, ingressRoute)
}
ingressRouteUDPs, err = ts.filterIngressRouteUdpByAnnotations(ingressRouteUDPs)
if err != nil {
return nil, fmt.Errorf("failed to filter IngressRouteUDP: %w", err)
}
for _, ingressRouteUDP := range ingressRouteUDPs {
var targets endpoint.Targets
targets = append(targets, annotations.TargetsFromTargetAnnotation(ingressRouteUDP.Annotations)...)
fullname := fmt.Sprintf("%s/%s", ingressRouteUDP.Namespace, ingressRouteUDP.Name)
ingressEndpoints, err := ts.endpointsFromIngressRouteUDP(ingressRouteUDP, targets)
if err != nil {
return nil, err
}
if len(ingressEndpoints) == 0 {
log.Debugf("No endpoints could be generated from Host %s", fullname)
continue
}
log.Debugf("Endpoints generated from IngressRouteUDP: %s: %v", fullname, ingressEndpoints)
endpoints = append(endpoints, ingressEndpoints...)
}
return endpoints, nil
return extractEndpoints[IngressRouteUDP](
ts.oldIngressRouteUdpInformer.Lister(),
ts.namespace,
func(u *unstructured.Unstructured) (*IngressRouteUDP, error) {
typed := &IngressRouteUDP{}
return typed, ts.unstructuredConverter.scheme.Convert(u, typed, nil)
},
ts.filterIngressRouteUdpByAnnotations,
ts.endpointsFromIngressRouteUDP,
)
}
// filterIngressRouteByAnnotation filters a list of IngressRoute by a given annotation selector.
func (ts *traefikSource) filterIngressRouteByAnnotation(ingressRoutes []*IngressRoute) ([]*IngressRoute, error) {
selector, err := annotations.ParseFilter(ts.annotationFilter)
if err != nil {
return nil, err
}
// empty filter returns original list
if selector.Empty() {
return ingressRoutes, nil
}
filteredList := []*IngressRoute{}
for _, ingressRoute := range ingressRoutes {
// include IngressRoute if its annotations match the selector
if selector.Matches(labels.Set(ingressRoute.Annotations)) {
filteredList = append(filteredList, ingressRoute)
}
}
return filteredList, nil
func (ts *traefikSource) filterIngressRouteByAnnotation(input []*IngressRoute) ([]*IngressRoute, error) {
return filterResourcesByAnnotations(input, ts.annotationFilter, func(ir *IngressRoute) map[string]string {
return ir.Annotations
})
}
// filterIngressRouteTcpByAnnotations filters a list of IngressRouteTCP by a given annotation selector.
func (ts *traefikSource) filterIngressRouteTcpByAnnotations(ingressRoutes []*IngressRouteTCP) ([]*IngressRouteTCP, error) {
selector, err := annotations.ParseFilter(ts.annotationFilter)
if err != nil {
return nil, err
}
// empty filter returns original list
if selector.Empty() {
return ingressRoutes, nil
}
var filteredList []*IngressRouteTCP
for _, ingressRoute := range ingressRoutes {
// include IngressRoute if its annotations match the selector
if selector.Matches(labels.Set(ingressRoute.Annotations)) {
filteredList = append(filteredList, ingressRoute)
}
}
return filteredList, nil
func (ts *traefikSource) filterIngressRouteTcpByAnnotations(input []*IngressRouteTCP) ([]*IngressRouteTCP, error) {
return filterResourcesByAnnotations(input, ts.annotationFilter, func(ir *IngressRouteTCP) map[string]string {
return ir.Annotations
})
}
// filterIngressRouteUdpByAnnotations filters a list of IngressRoute by a given annotation selector.
func (ts *traefikSource) filterIngressRouteUdpByAnnotations(ingressRoutes []*IngressRouteUDP) ([]*IngressRouteUDP, error) {
selector, err := annotations.ParseFilter(ts.annotationFilter)
if err != nil {
return nil, err
}
// empty filter returns original list
if selector.Empty() {
return ingressRoutes, nil
}
var filteredList []*IngressRouteUDP
for _, ingressRoute := range ingressRoutes {
// include IngressRoute if its annotations match the selector
if selector.Matches(labels.Set(ingressRoute.Annotations)) {
filteredList = append(filteredList, ingressRoute)
}
}
return filteredList, nil
func (ts *traefikSource) filterIngressRouteUdpByAnnotations(input []*IngressRouteUDP) ([]*IngressRouteUDP, error) {
return filterResourcesByAnnotations(input, ts.annotationFilter, func(ir *IngressRouteUDP) map[string]string {
return ir.Annotations
})
}
// endpointsFromIngressRoute extracts the endpoints from a IngressRoute object
func (ts *traefikSource) endpointsFromIngressRoute(ingressRoute *IngressRoute, targets endpoint.Targets) ([]*endpoint.Endpoint, error) {
func (ts *traefikSource) endpointsFromIngressRoute(ingressRoute *IngressRoute, targets endpoint.Targets) []*endpoint.Endpoint {
var endpoints []*endpoint.Endpoint
resource := fmt.Sprintf("ingressroute/%s/%s", ingressRoute.Namespace, ingressRoute.Name)
@ -626,12 +386,9 @@ func (ts *traefikSource) endpointsFromIngressRoute(ingressRoute *IngressRoute, t
}
for _, route := range ingressRoute.Spec.Routes {
match := route.Match
for _, hostEntry := range traefikHostExtractor.FindAllString(match, -1) {
for _, hostEntry := range traefikHostExtractor.FindAllString(route.Match, -1) {
for _, host := range traefikValueProcessor.FindAllString(hostEntry, -1) {
host = strings.TrimPrefix(host, "`")
host = strings.TrimSuffix(host, "`")
host = strings.Trim(host, "`")
// Checking for host = * is required, as Host(`*`) can be set
if host != "*" && host != "" {
@ -641,11 +398,11 @@ func (ts *traefikSource) endpointsFromIngressRoute(ingressRoute *IngressRoute, t
}
}
return endpoints, nil
return endpoints
}
// endpointsFromIngressRouteTCP extracts the endpoints from a IngressRouteTCP object
func (ts *traefikSource) endpointsFromIngressRouteTCP(ingressRoute *IngressRouteTCP, targets endpoint.Targets) ([]*endpoint.Endpoint, error) {
func (ts *traefikSource) endpointsFromIngressRouteTCP(ingressRoute *IngressRouteTCP, targets endpoint.Targets) []*endpoint.Endpoint {
var endpoints []*endpoint.Endpoint
resource := fmt.Sprintf("ingressroutetcp/%s/%s", ingressRoute.Namespace, ingressRoute.Name)
@ -662,13 +419,9 @@ func (ts *traefikSource) endpointsFromIngressRouteTCP(ingressRoute *IngressRoute
}
for _, route := range ingressRoute.Spec.Routes {
match := route.Match
for _, hostEntry := range traefikHostExtractor.FindAllString(match, -1) {
for _, hostEntry := range traefikHostExtractor.FindAllString(route.Match, -1) {
for _, host := range traefikValueProcessor.FindAllString(hostEntry, -1) {
host = strings.TrimPrefix(host, "`")
host = strings.TrimSuffix(host, "`")
host = strings.Trim(host, "`")
// Checking for host = * is required, as HostSNI(`*`) can be set
// in the case of TLS passthrough
if host != "*" && host != "" {
@ -678,11 +431,11 @@ func (ts *traefikSource) endpointsFromIngressRouteTCP(ingressRoute *IngressRoute
}
}
return endpoints, nil
return endpoints
}
// endpointsFromIngressRouteUDP extracts the endpoints from a IngressRouteUDP object
func (ts *traefikSource) endpointsFromIngressRouteUDP(ingressRoute *IngressRouteUDP, targets endpoint.Targets) ([]*endpoint.Endpoint, error) {
func (ts *traefikSource) endpointsFromIngressRouteUDP(ingressRoute *IngressRouteUDP, targets endpoint.Targets) []*endpoint.Endpoint {
var endpoints []*endpoint.Endpoint
resource := fmt.Sprintf("ingressrouteudp/%s/%s", ingressRoute.Namespace, ingressRoute.Name)
@ -698,7 +451,7 @@ func (ts *traefikSource) endpointsFromIngressRouteUDP(ingressRoute *IngressRoute
}
}
return endpoints, nil
return endpoints
}
func (ts *traefikSource) AddEventHandler(ctx context.Context, handler func()) {
@ -1081,3 +834,119 @@ func (in *IngressRouteUDPList) DeepCopyObject() runtime.Object {
}
return nil
}
// extractEndpoints is a generic function that extracts endpoints from Kubernetes resources.
// It performs the following steps:
// 1. Lists all objects in the specified namespace using the provided informer.
// 2. Converts the unstructured objects to the desired type using the convertFunc.
// 3. Filters the converted objects based on the provided filterFunc.
// 4. Generates endpoints for each filtered object using the generateEndpoints function.
// Returns a list of generated endpoints or an error if any step fails.
func extractEndpoints[T any](
informer cache.GenericLister,
namespace string,
convertFunc func(*unstructured.Unstructured) (*T, error),
filterFunc func([]*T) ([]*T, error),
generateEndpoints func(*T, endpoint.Targets) []*endpoint.Endpoint,
) ([]*endpoint.Endpoint, error) {
var endpoints []*endpoint.Endpoint
objs, err := informer.ByNamespace(namespace).List(labels.Everything())
if err != nil {
return nil, err
}
var typedObjs []*T
for _, obj := range objs {
unstructuredObj, ok := obj.(*unstructured.Unstructured)
if !ok {
return nil, errors.New("failed to cast to unstructured.Unstructured")
}
typed, err := convertFunc(unstructuredObj)
if err != nil {
return nil, err
}
typedObjs = append(typedObjs, typed)
}
typedObjs, err = filterFunc(typedObjs)
if err != nil {
return nil, err
}
for _, item := range typedObjs {
targets := annotations.TargetsFromTargetAnnotation(getAnnotations(item))
name := getObjectFullName(item)
ingressEndpoints := generateEndpoints(item, targets)
if len(ingressEndpoints) == 0 {
log.Debugf("No endpoints could be generated from Host %s", name)
continue
}
log.Debugf("Endpoints generated from %s: %v", name, ingressEndpoints)
endpoints = append(endpoints, ingressEndpoints...)
}
return endpoints, nil
}
// filterResourcesByAnnotations filters a list of resources based on a given annotation selector.
// It performs the following steps:
// 1. Parses the annotation filter into a label selector.
// 2. Converts the label selector into a Kubernetes selector.
// 3. If the selector is empty, returns the original list of resources.
// 4. Iterates through the resources and matches their annotations against the selector.
// 5. Returns the filtered list of resources or an error if any step fails.
func filterResourcesByAnnotations[T any](resources []*T, annotationFilter string, getAnnotations func(*T) map[string]string) ([]*T, error) {
labelSelector, err := metav1.ParseToLabelSelector(annotationFilter)
if err != nil {
return nil, err
}
selector, err := metav1.LabelSelectorAsSelector(labelSelector)
if err != nil {
return nil, err
}
if selector.Empty() {
return resources, nil
}
var filteredList []*T
for _, resource := range resources {
annotations := getAnnotations(resource)
if selector.Matches(labels.Set(annotations)) {
filteredList = append(filteredList, resource)
}
}
return filteredList, nil
}
func getAnnotations(obj interface{}) map[string]string {
switch o := obj.(type) {
case *IngressRouteUDP:
return o.Annotations
case *IngressRoute:
return o.Annotations
case *IngressRouteTCP:
return o.Annotations
default:
return nil
}
}
func getObjectFullName(obj interface{}) string {
switch o := obj.(type) {
case *IngressRouteUDP:
return fmt.Sprintf("%s/%s", o.Namespace, o.Name)
case *IngressRoute:
return fmt.Sprintf("%s/%s", o.Namespace, o.Name)
case *IngressRouteTCP:
return fmt.Sprintf("%s/%s", o.Namespace, o.Name)
default:
return ""
}
}

View File

@ -21,7 +21,9 @@ import (
"encoding/json"
"testing"
"github.com/stretchr/testify/mock"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/tools/cache"
"github.com/stretchr/testify/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -1731,3 +1733,80 @@ func TestTraefikAPIGroupDisableFlags(t *testing.T) {
})
}
}
func TestAddEventHandler_AllBranches(t *testing.T) {
ctx := context.Background()
handlerCalled := false
handler := func() { handlerCalled = true }
inf := testInformer{}
fakeInformer := new(FakeInformer)
fakeInformer.On("Informer").Return(&inf)
cases := []struct {
name string
ts *traefikSource
want int
}{
{"all nil", &traefikSource{}, 0},
{"all set", &traefikSource{
ingressRouteInformer: fakeInformer,
oldIngressRouteInformer: fakeInformer,
ingressRouteTcpInformer: fakeInformer,
oldIngressRouteTcpInformer: fakeInformer,
ingressRouteUdpInformer: fakeInformer,
oldIngressRouteUdpInformer: fakeInformer,
}, 6},
{"some set", &traefikSource{
ingressRouteInformer: fakeInformer,
oldIngressRouteInformer: fakeInformer,
ingressRouteTcpInformer: nil,
oldIngressRouteTcpInformer: fakeInformer,
ingressRouteUdpInformer: nil,
oldIngressRouteUdpInformer: nil,
}, 3},
}
for _, test := range cases {
t.Run(test.name, func(t *testing.T) {
test.ts.AddEventHandler(ctx, handler)
assert.Equal(t, test.want, inf.times)
assert.False(t, handlerCalled)
if test.want > 0 {
fakeInformer.AssertExpectations(t)
fakeInformer.AssertCalled(t, "Informer")
} else {
fakeInformer.AssertNotCalled(t, "Informer")
}
// reset the call count
inf.times = 0
})
}
}
type FakeInformer struct {
mock.Mock
informer cache.SharedIndexInformer
lister cache.GenericLister
}
func (f *FakeInformer) Informer() cache.SharedIndexInformer {
args := f.Called()
return args.Get(0).(cache.SharedIndexInformer)
}
func (f *FakeInformer) Lister() cache.GenericLister {
return f.lister
}
type testInformer struct {
cache.SharedIndexInformer
times int
}
func (t *testInformer) AddEventHandler(handler cache.ResourceEventHandler) (cache.ResourceEventHandlerRegistration, error) {
t.times += 1
return nil, nil
}