diff --git a/pkg/proxy/topology_test.go b/pkg/proxy/topology_test.go index 14a09612eee..a151fc2b182 100644 --- a/pkg/proxy/topology_test.go +++ b/pkg/proxy/topology_test.go @@ -113,6 +113,158 @@ func TestFilterEndpoints(t *testing.T) { &BaseEndpointInfo{Endpoint: "10.1.2.6:80", ZoneHints: sets.NewString("zone-a"), Ready: true}, }, expectedEndpoints: sets.NewString("10.1.2.3:80", "10.1.2.4:80", "10.1.2.5:80", "10.1.2.6:80"), + }, { + name: "empty node labels", + hintsEnabled: true, + nodeLabels: map[string]string{}, + serviceInfo: &BaseServiceInfo{hintsAnnotation: "auto"}, + endpoints: []Endpoint{ + &BaseEndpointInfo{Endpoint: "10.1.2.3:80", ZoneHints: sets.NewString("zone-a"), Ready: true}, + }, + expectedEndpoints: sets.NewString("10.1.2.3:80"), + }, { + name: "empty zone label", + hintsEnabled: true, + nodeLabels: map[string]string{v1.LabelTopologyZone: ""}, + serviceInfo: &BaseServiceInfo{hintsAnnotation: "auto"}, + endpoints: []Endpoint{ + &BaseEndpointInfo{Endpoint: "10.1.2.3:80", ZoneHints: sets.NewString("zone-a"), Ready: true}, + }, + expectedEndpoints: sets.NewString("10.1.2.3:80"), + }, { + name: "node in different zone, no endpoint filtering", + hintsEnabled: true, + nodeLabels: map[string]string{v1.LabelTopologyZone: "zone-b"}, + serviceInfo: &BaseServiceInfo{hintsAnnotation: "auto"}, + endpoints: []Endpoint{ + &BaseEndpointInfo{Endpoint: "10.1.2.3:80", ZoneHints: sets.NewString("zone-a"), Ready: true}, + }, + expectedEndpoints: sets.NewString("10.1.2.3:80"), + }, { + name: "normal endpoint filtering, auto annotation", + hintsEnabled: true, + nodeLabels: map[string]string{v1.LabelTopologyZone: "zone-a"}, + serviceInfo: &BaseServiceInfo{hintsAnnotation: "auto"}, + endpoints: []Endpoint{ + &BaseEndpointInfo{Endpoint: "10.1.2.3:80", ZoneHints: sets.NewString("zone-a"), Ready: true}, + &BaseEndpointInfo{Endpoint: "10.1.2.4:80", ZoneHints: sets.NewString("zone-b"), Ready: true}, + &BaseEndpointInfo{Endpoint: "10.1.2.5:80", ZoneHints: sets.NewString("zone-c"), Ready: true}, + &BaseEndpointInfo{Endpoint: "10.1.2.6:80", ZoneHints: sets.NewString("zone-a"), Ready: true}, + }, + expectedEndpoints: sets.NewString("10.1.2.3:80", "10.1.2.6:80"), + }, { + name: "unready endpoint", + hintsEnabled: true, + nodeLabels: map[string]string{v1.LabelTopologyZone: "zone-a"}, + serviceInfo: &BaseServiceInfo{hintsAnnotation: "auto"}, + endpoints: []Endpoint{ + &BaseEndpointInfo{Endpoint: "10.1.2.3:80", ZoneHints: sets.NewString("zone-a"), Ready: true}, + &BaseEndpointInfo{Endpoint: "10.1.2.4:80", ZoneHints: sets.NewString("zone-b"), Ready: true}, + &BaseEndpointInfo{Endpoint: "10.1.2.5:80", ZoneHints: sets.NewString("zone-c"), Ready: true}, + &BaseEndpointInfo{Endpoint: "10.1.2.6:80", ZoneHints: sets.NewString("zone-a"), Ready: false}, + }, + expectedEndpoints: sets.NewString("10.1.2.3:80"), + }, { + name: "only unready endpoints in same zone (should not filter)", + hintsEnabled: true, + nodeLabels: map[string]string{v1.LabelTopologyZone: "zone-a"}, + serviceInfo: &BaseServiceInfo{hintsAnnotation: "auto"}, + endpoints: []Endpoint{ + &BaseEndpointInfo{Endpoint: "10.1.2.3:80", ZoneHints: sets.NewString("zone-a"), Ready: false}, + &BaseEndpointInfo{Endpoint: "10.1.2.4:80", ZoneHints: sets.NewString("zone-b"), Ready: true}, + &BaseEndpointInfo{Endpoint: "10.1.2.5:80", ZoneHints: sets.NewString("zone-c"), Ready: true}, + &BaseEndpointInfo{Endpoint: "10.1.2.6:80", ZoneHints: sets.NewString("zone-a"), Ready: false}, + }, + expectedEndpoints: sets.NewString("10.1.2.3:80", "10.1.2.4:80", "10.1.2.5:80", "10.1.2.6:80"), + }, { + name: "normal endpoint filtering, Auto annotation", + hintsEnabled: true, + nodeLabels: map[string]string{v1.LabelTopologyZone: "zone-a"}, + serviceInfo: &BaseServiceInfo{hintsAnnotation: "Auto"}, + endpoints: []Endpoint{ + &BaseEndpointInfo{Endpoint: "10.1.2.3:80", ZoneHints: sets.NewString("zone-a"), Ready: true}, + &BaseEndpointInfo{Endpoint: "10.1.2.4:80", ZoneHints: sets.NewString("zone-b"), Ready: true}, + &BaseEndpointInfo{Endpoint: "10.1.2.5:80", ZoneHints: sets.NewString("zone-c"), Ready: true}, + &BaseEndpointInfo{Endpoint: "10.1.2.6:80", ZoneHints: sets.NewString("zone-a"), Ready: true}, + }, + expectedEndpoints: sets.NewString("10.1.2.3:80", "10.1.2.6:80"), + }, { + name: "hintsAnnotation empty, no filtering applied", + hintsEnabled: true, + nodeLabels: map[string]string{v1.LabelTopologyZone: "zone-a"}, + serviceInfo: &BaseServiceInfo{hintsAnnotation: ""}, + endpoints: []Endpoint{ + &BaseEndpointInfo{Endpoint: "10.1.2.3:80", ZoneHints: sets.NewString("zone-a"), Ready: true}, + &BaseEndpointInfo{Endpoint: "10.1.2.4:80", ZoneHints: sets.NewString("zone-b"), Ready: true}, + &BaseEndpointInfo{Endpoint: "10.1.2.5:80", ZoneHints: sets.NewString("zone-c"), Ready: true}, + &BaseEndpointInfo{Endpoint: "10.1.2.6:80", ZoneHints: sets.NewString("zone-a"), Ready: true}, + }, + expectedEndpoints: sets.NewString("10.1.2.3:80", "10.1.2.4:80", "10.1.2.5:80", "10.1.2.6:80"), + }, { + name: "hintsAnnotation disabled, no filtering applied", + hintsEnabled: true, + nodeLabels: map[string]string{v1.LabelTopologyZone: "zone-a"}, + serviceInfo: &BaseServiceInfo{hintsAnnotation: "disabled"}, + endpoints: []Endpoint{ + &BaseEndpointInfo{Endpoint: "10.1.2.3:80", ZoneHints: sets.NewString("zone-a"), Ready: true}, + &BaseEndpointInfo{Endpoint: "10.1.2.4:80", ZoneHints: sets.NewString("zone-b"), Ready: true}, + &BaseEndpointInfo{Endpoint: "10.1.2.5:80", ZoneHints: sets.NewString("zone-c"), Ready: true}, + &BaseEndpointInfo{Endpoint: "10.1.2.6:80", ZoneHints: sets.NewString("zone-a"), Ready: true}, + }, + expectedEndpoints: sets.NewString("10.1.2.3:80", "10.1.2.4:80", "10.1.2.5:80", "10.1.2.6:80"), + }, { + name: "missing hints, no filtering applied", + hintsEnabled: true, + nodeLabels: map[string]string{v1.LabelTopologyZone: "zone-a"}, + serviceInfo: &BaseServiceInfo{hintsAnnotation: "auto"}, + endpoints: []Endpoint{ + &BaseEndpointInfo{Endpoint: "10.1.2.3:80", ZoneHints: sets.NewString("zone-a"), Ready: true}, + &BaseEndpointInfo{Endpoint: "10.1.2.4:80", ZoneHints: sets.NewString("zone-b"), Ready: true}, + &BaseEndpointInfo{Endpoint: "10.1.2.5:80", ZoneHints: nil, Ready: true}, + &BaseEndpointInfo{Endpoint: "10.1.2.6:80", ZoneHints: sets.NewString("zone-a"), Ready: true}, + }, + expectedEndpoints: sets.NewString("10.1.2.3:80", "10.1.2.4:80", "10.1.2.5:80", "10.1.2.6:80"), + }, { + name: "multiple hints per endpoint, filtering includes any endpoint with zone included", + hintsEnabled: true, + nodeLabels: map[string]string{v1.LabelTopologyZone: "zone-c"}, + serviceInfo: &BaseServiceInfo{hintsAnnotation: "auto"}, + endpoints: []Endpoint{ + &BaseEndpointInfo{Endpoint: "10.1.2.3:80", ZoneHints: sets.NewString("zone-a", "zone-b", "zone-c"), Ready: true}, + &BaseEndpointInfo{Endpoint: "10.1.2.4:80", ZoneHints: sets.NewString("zone-b", "zone-c"), Ready: true}, + &BaseEndpointInfo{Endpoint: "10.1.2.5:80", ZoneHints: sets.NewString("zone-b", "zone-d"), Ready: true}, + &BaseEndpointInfo{Endpoint: "10.1.2.6:80", ZoneHints: sets.NewString("zone-c"), Ready: true}, + }, + expectedEndpoints: sets.NewString("10.1.2.3:80", "10.1.2.4:80", "10.1.2.6:80"), + }, { + name: "internalTrafficPolicy: Local, with empty endpoints", + serviceInfo: &BaseServiceInfo{nodeLocalInternal: true}, + endpoints: []Endpoint{}, + expectedEndpoints: nil, + }, { + name: "internalTrafficPolicy: Local, but all endpoints are remote", + serviceInfo: &BaseServiceInfo{nodeLocalInternal: true}, + endpoints: []Endpoint{ + &BaseEndpointInfo{Endpoint: "10.0.0.0:80", Ready: true, IsLocal: false}, + &BaseEndpointInfo{Endpoint: "10.0.0.1:80", Ready: true, IsLocal: false}, + }, + expectedEndpoints: nil, + }, { + name: "internalTrafficPolicy: Local, all endpoints are local", + serviceInfo: &BaseServiceInfo{nodeLocalInternal: true}, + endpoints: []Endpoint{ + &BaseEndpointInfo{Endpoint: "10.0.0.0:80", Ready: true, IsLocal: true}, + &BaseEndpointInfo{Endpoint: "10.0.0.1:80", Ready: true, IsLocal: true}, + }, + expectedEndpoints: sets.NewString("10.0.0.0:80", "10.0.0.1:80"), + }, { + name: "internalTrafficPolicy: Local, some endpoints are local", + serviceInfo: &BaseServiceInfo{nodeLocalInternal: true}, + endpoints: []Endpoint{ + &BaseEndpointInfo{Endpoint: "10.0.0.0:80", Ready: true, IsLocal: true}, + &BaseEndpointInfo{Endpoint: "10.0.0.1:80", Ready: true, IsLocal: false}, + }, + expectedEndpoints: sets.NewString("10.0.0.0:80"), }} for _, tc := range testCases { @@ -127,182 +279,3 @@ func TestFilterEndpoints(t *testing.T) { }) } } - -func Test_filterEndpointsWithHints(t *testing.T) { - testCases := []struct { - name string - nodeLabels map[string]string - hintsAnnotation string - endpoints []Endpoint - expectedEndpoints sets.String - }{{ - name: "empty node labels", - nodeLabels: map[string]string{}, - hintsAnnotation: "auto", - endpoints: []Endpoint{ - &BaseEndpointInfo{Endpoint: "10.1.2.3:80", ZoneHints: sets.NewString("zone-a"), Ready: true}, - }, - expectedEndpoints: sets.NewString("10.1.2.3:80"), - }, { - name: "empty zone label", - nodeLabels: map[string]string{v1.LabelTopologyZone: ""}, - hintsAnnotation: "auto", - endpoints: []Endpoint{ - &BaseEndpointInfo{Endpoint: "10.1.2.3:80", ZoneHints: sets.NewString("zone-a"), Ready: true}, - }, - expectedEndpoints: sets.NewString("10.1.2.3:80"), - }, { - name: "node in different zone, no endpoint filtering", - nodeLabels: map[string]string{v1.LabelTopologyZone: "zone-b"}, - hintsAnnotation: "auto", - endpoints: []Endpoint{ - &BaseEndpointInfo{Endpoint: "10.1.2.3:80", ZoneHints: sets.NewString("zone-a"), Ready: true}, - }, - expectedEndpoints: sets.NewString("10.1.2.3:80"), - }, { - name: "normal endpoint filtering, auto annotation", - nodeLabels: map[string]string{v1.LabelTopologyZone: "zone-a"}, - hintsAnnotation: "auto", - endpoints: []Endpoint{ - &BaseEndpointInfo{Endpoint: "10.1.2.3:80", ZoneHints: sets.NewString("zone-a"), Ready: true}, - &BaseEndpointInfo{Endpoint: "10.1.2.4:80", ZoneHints: sets.NewString("zone-b"), Ready: true}, - &BaseEndpointInfo{Endpoint: "10.1.2.5:80", ZoneHints: sets.NewString("zone-c"), Ready: true}, - &BaseEndpointInfo{Endpoint: "10.1.2.6:80", ZoneHints: sets.NewString("zone-a"), Ready: true}, - }, - expectedEndpoints: sets.NewString("10.1.2.3:80", "10.1.2.6:80"), - }, { - name: "unready endpoint", - nodeLabels: map[string]string{v1.LabelTopologyZone: "zone-a"}, - hintsAnnotation: "auto", - endpoints: []Endpoint{ - &BaseEndpointInfo{Endpoint: "10.1.2.3:80", ZoneHints: sets.NewString("zone-a"), Ready: true}, - &BaseEndpointInfo{Endpoint: "10.1.2.4:80", ZoneHints: sets.NewString("zone-b"), Ready: true}, - &BaseEndpointInfo{Endpoint: "10.1.2.5:80", ZoneHints: sets.NewString("zone-c"), Ready: true}, - &BaseEndpointInfo{Endpoint: "10.1.2.6:80", ZoneHints: sets.NewString("zone-a"), Ready: false}, - }, - expectedEndpoints: sets.NewString("10.1.2.3:80"), - }, { - name: "only unready endpoints in same zone (should not filter)", - nodeLabels: map[string]string{v1.LabelTopologyZone: "zone-a"}, - hintsAnnotation: "auto", - endpoints: []Endpoint{ - &BaseEndpointInfo{Endpoint: "10.1.2.3:80", ZoneHints: sets.NewString("zone-a"), Ready: false}, - &BaseEndpointInfo{Endpoint: "10.1.2.4:80", ZoneHints: sets.NewString("zone-b"), Ready: true}, - &BaseEndpointInfo{Endpoint: "10.1.2.5:80", ZoneHints: sets.NewString("zone-c"), Ready: true}, - &BaseEndpointInfo{Endpoint: "10.1.2.6:80", ZoneHints: sets.NewString("zone-a"), Ready: false}, - }, - expectedEndpoints: sets.NewString("10.1.2.3:80", "10.1.2.4:80", "10.1.2.5:80", "10.1.2.6:80"), - }, { - name: "normal endpoint filtering, Auto annotation", - nodeLabels: map[string]string{v1.LabelTopologyZone: "zone-a"}, - hintsAnnotation: "Auto", - endpoints: []Endpoint{ - &BaseEndpointInfo{Endpoint: "10.1.2.3:80", ZoneHints: sets.NewString("zone-a"), Ready: true}, - &BaseEndpointInfo{Endpoint: "10.1.2.4:80", ZoneHints: sets.NewString("zone-b"), Ready: true}, - &BaseEndpointInfo{Endpoint: "10.1.2.5:80", ZoneHints: sets.NewString("zone-c"), Ready: true}, - &BaseEndpointInfo{Endpoint: "10.1.2.6:80", ZoneHints: sets.NewString("zone-a"), Ready: true}, - }, - expectedEndpoints: sets.NewString("10.1.2.3:80", "10.1.2.6:80"), - }, { - name: "hintsAnnotation empty, no filtering applied", - nodeLabels: map[string]string{v1.LabelTopologyZone: "zone-a"}, - hintsAnnotation: "", - endpoints: []Endpoint{ - &BaseEndpointInfo{Endpoint: "10.1.2.3:80", ZoneHints: sets.NewString("zone-a"), Ready: true}, - &BaseEndpointInfo{Endpoint: "10.1.2.4:80", ZoneHints: sets.NewString("zone-b"), Ready: true}, - &BaseEndpointInfo{Endpoint: "10.1.2.5:80", ZoneHints: sets.NewString("zone-c"), Ready: true}, - &BaseEndpointInfo{Endpoint: "10.1.2.6:80", ZoneHints: sets.NewString("zone-a"), Ready: true}, - }, - expectedEndpoints: sets.NewString("10.1.2.3:80", "10.1.2.4:80", "10.1.2.5:80", "10.1.2.6:80"), - }, { - name: "hintsAnnotation disabled, no filtering applied", - nodeLabels: map[string]string{v1.LabelTopologyZone: "zone-a"}, - hintsAnnotation: "disabled", - endpoints: []Endpoint{ - &BaseEndpointInfo{Endpoint: "10.1.2.3:80", ZoneHints: sets.NewString("zone-a"), Ready: true}, - &BaseEndpointInfo{Endpoint: "10.1.2.4:80", ZoneHints: sets.NewString("zone-b"), Ready: true}, - &BaseEndpointInfo{Endpoint: "10.1.2.5:80", ZoneHints: sets.NewString("zone-c"), Ready: true}, - &BaseEndpointInfo{Endpoint: "10.1.2.6:80", ZoneHints: sets.NewString("zone-a"), Ready: true}, - }, - expectedEndpoints: sets.NewString("10.1.2.3:80", "10.1.2.4:80", "10.1.2.5:80", "10.1.2.6:80"), - }, { - name: "missing hints, no filtering applied", - nodeLabels: map[string]string{v1.LabelTopologyZone: "zone-a"}, - hintsAnnotation: "auto", - endpoints: []Endpoint{ - &BaseEndpointInfo{Endpoint: "10.1.2.3:80", ZoneHints: sets.NewString("zone-a"), Ready: true}, - &BaseEndpointInfo{Endpoint: "10.1.2.4:80", ZoneHints: sets.NewString("zone-b"), Ready: true}, - &BaseEndpointInfo{Endpoint: "10.1.2.5:80", ZoneHints: nil, Ready: true}, - &BaseEndpointInfo{Endpoint: "10.1.2.6:80", ZoneHints: sets.NewString("zone-a"), Ready: true}, - }, - expectedEndpoints: sets.NewString("10.1.2.3:80", "10.1.2.4:80", "10.1.2.5:80", "10.1.2.6:80"), - }, { - name: "multiple hints per endpoint, filtering includes any endpoint with zone included", - nodeLabels: map[string]string{v1.LabelTopologyZone: "zone-c"}, - hintsAnnotation: "auto", - endpoints: []Endpoint{ - &BaseEndpointInfo{Endpoint: "10.1.2.3:80", ZoneHints: sets.NewString("zone-a", "zone-b", "zone-c"), Ready: true}, - &BaseEndpointInfo{Endpoint: "10.1.2.4:80", ZoneHints: sets.NewString("zone-b", "zone-c"), Ready: true}, - &BaseEndpointInfo{Endpoint: "10.1.2.5:80", ZoneHints: sets.NewString("zone-b", "zone-d"), Ready: true}, - &BaseEndpointInfo{Endpoint: "10.1.2.6:80", ZoneHints: sets.NewString("zone-c"), Ready: true}, - }, - expectedEndpoints: sets.NewString("10.1.2.3:80", "10.1.2.4:80", "10.1.2.6:80"), - }} - - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - filteredEndpoints := filterEndpointsWithHints(tc.endpoints, tc.hintsAnnotation, tc.nodeLabels) - err := checkExpectedEndpoints(tc.expectedEndpoints, filteredEndpoints) - if err != nil { - t.Errorf(err.Error()) - } - }) - } -} - -func TestFilterLocalEndpoint(t *testing.T) { - testCases := []struct { - name string - endpoints []Endpoint - expected sets.String - }{ - { - name: "with empty endpoints", - endpoints: []Endpoint{}, - expected: nil, - }, - { - name: "all endpoints not local", - endpoints: []Endpoint{ - &BaseEndpointInfo{Endpoint: "10.0.0.0:80", Ready: true, IsLocal: false}, - &BaseEndpointInfo{Endpoint: "10.0.0.1:80", Ready: true, IsLocal: false}, - }, - expected: nil, - }, - { - name: "all endpoints are local", - endpoints: []Endpoint{ - &BaseEndpointInfo{Endpoint: "10.0.0.0:80", Ready: true, IsLocal: true}, - &BaseEndpointInfo{Endpoint: "10.0.0.1:80", Ready: true, IsLocal: true}, - }, - expected: sets.NewString("10.0.0.0:80", "10.0.0.1:80"), - }, - { - name: "some endpoints are local", - endpoints: []Endpoint{ - &BaseEndpointInfo{Endpoint: "10.0.0.0:80", Ready: true, IsLocal: true}, - &BaseEndpointInfo{Endpoint: "10.0.0.1:80", Ready: true, IsLocal: false}, - }, - expected: sets.NewString("10.0.0.0:80"), - }, - } - for _, tc := range testCases { - t.Run(tc.name, func(t *testing.T) { - filteredEndpoint := FilterLocalEndpoint(tc.endpoints) - err := checkExpectedEndpoints(tc.expected, filteredEndpoint) - if err != nil { - t.Errorf(err.Error()) - } - }) - } -}