From a8b4f321523deb10efd79e2654aa2c30fffc369d Mon Sep 17 00:00:00 2001 From: Shardool Patil Date: Fri, 2 Oct 2026 07:13:02 +0000 Subject: [PATCH] test(kubernetes): add unit tests for ingressStatusAddressesFromService Signed-off-by: Shardool Patil --- dataclients/kubernetes/ingress_status_test.go | 169 +++++++++++++++--- 1 file changed, 148 insertions(+), 21 deletions(-) diff --git a/dataclients/kubernetes/ingress_status_test.go b/dataclients/kubernetes/ingress_status_test.go index eb3003b8c3..c78edcaec8 100644 --- a/dataclients/kubernetes/ingress_status_test.go +++ b/dataclients/kubernetes/ingress_status_test.go @@ -42,46 +42,173 @@ func TestIngressStatusAddressesFromService(t *testing.T) { newResourceID("default", "external-name"): { Spec: &serviceSpec{Type: "ExternalName", ExternalName: "example.org"}, }, + newResourceID("default", "external-name-empty"): { + Spec: &serviceSpec{Type: "ExternalName", ExternalName: ""}, + }, newResourceID("default", "cluster-ip"): { Spec: &serviceSpec{Type: "ClusterIP", ClusterIP: "10.0.0.9"}, }, + newResourceID("default", "cluster-ip-empty"): { + Spec: &serviceSpec{Type: "ClusterIP", ClusterIP: ""}, + }, + newResourceID("default", "cluster-ip-none"): { + Spec: &serviceSpec{Type: "ClusterIP", ClusterIP: "None"}, + }, + newResourceID("default", "node-port-external-ips"): { + Spec: &serviceSpec{Type: "NodePort", ExternalIPs: []string{"198.51.100.1"}}, + }, + newResourceID("default", "node-port-endpoints"): { + Spec: &serviceSpec{Type: "NodePort"}, + }, newResourceID("default", "load-balancer"): { - Spec: &serviceSpec{Type: "LoadBalancer"}, - Status: &serviceStatus{LoadBalancer: serviceLoadBalancerStatus{Ingress: []serviceLoadBalancerIngress{{IP: "1.2.3.4"}}}}, + Spec: &serviceSpec{Type: "LoadBalancer"}, + Status: &serviceStatus{ + LoadBalancer: serviceLoadBalancerStatus{ + Ingress: []serviceLoadBalancerIngress{ + {IP: "1.2.3.4"}, + {Hostname: "lb.example.org"}, + {IP: "", Hostname: ""}, + }, + }, + }, + }, + newResourceID("default", "load-balancer-external-ips"): { + Spec: &serviceSpec{Type: "LoadBalancer", ExternalIPs: []string{"198.51.100.2"}}, + }, + newResourceID("default", "load-balancer-empty"): { + Spec: &serviceSpec{Type: "LoadBalancer"}, + }, + newResourceID("default", "custom-type-external-ips"): { + Spec: &serviceSpec{Type: "CustomType", ExternalIPs: []string{"198.51.100.3"}}, + }, + newResourceID("default", "custom-type-empty"): { + Spec: &serviceSpec{Type: "CustomType"}, + }, + newResourceID("default", "nil-spec"): { + Spec: nil, + }, + }, + endpoints: map[definitions.ResourceID]*endpoint{ + newResourceID("default", "node-port-endpoints"): { + Subsets: []*subset{ + { + Addresses: []*address{ + {IP: "10.2.0.1"}, + }, + }, + }, }, }, } for _, tt := range []struct { - name string - service string - expected []definitions.IngressLoadBalancerIngress + name string + service string + zone string + expected []definitions.IngressLoadBalancerIngress + expectErr bool + errContains string }{ { - name: "external name", - service: "default/external-name", - expected: []definitions.IngressLoadBalancerIngress{{ - Hostname: "example.org", - }}, + name: "empty ingress status service config", + service: "", + expected: nil, }, { - name: "cluster ip", - service: "default/cluster-ip", - expected: []definitions.IngressLoadBalancerIngress{{ - IP: "10.0.0.9", - }}, + name: "invalid namespace/name format", + service: "invalid-service-name", + expectErr: true, + errContains: "invalid resource reference", + }, + { + name: "service not found in cluster state", + service: "default/nonexistent-service", + expectErr: true, + errContains: "service not found: default/nonexistent-service", + }, + { + name: "service with nil spec returns error", + service: "default/nil-spec", + expectErr: true, + errContains: "service not found: default/nil-spec", + }, + { + name: "external name", + service: "default/external-name", + expected: []definitions.IngressLoadBalancerIngress{{Hostname: "example.org"}}, }, { - name: "load balancer", + name: "external name empty returns nil", + service: "default/external-name-empty", + expected: nil, + }, + { + name: "cluster ip", + service: "default/cluster-ip", + expected: []definitions.IngressLoadBalancerIngress{{IP: "10.0.0.9"}}, + }, + { + name: "cluster ip empty returns nil", + service: "default/cluster-ip-empty", + expected: nil, + }, + { + name: "cluster ip None (headless) returns nil", + service: "default/cluster-ip-none", + expected: nil, + }, + { + name: "node port with external IPs", + service: "default/node-port-external-ips", + expected: []definitions.IngressLoadBalancerIngress{{IP: "198.51.100.1"}}, + }, + { + name: "node port fallback to endpoint addresses", + service: "default/node-port-endpoints", + expected: []definitions.IngressLoadBalancerIngress{{IP: "10.2.0.1"}}, + }, + { + name: "load balancer with ingress status (filters empty entries)", service: "default/load-balancer", - expected: []definitions.IngressLoadBalancerIngress{{ - IP: "1.2.3.4", - }}, + expected: []definitions.IngressLoadBalancerIngress{ + {IP: "1.2.3.4"}, + {Hostname: "lb.example.org"}, + }, + }, + { + name: "load balancer fallback to external IPs", + service: "default/load-balancer-external-ips", + expected: []definitions.IngressLoadBalancerIngress{{IP: "198.51.100.2"}}, + }, + { + name: "load balancer without status or external IPs returns nil", + service: "default/load-balancer-empty", + expected: nil, + }, + { + name: "default/unknown service type with external IPs", + service: "default/custom-type-external-ips", + expected: []definitions.IngressLoadBalancerIngress{{IP: "198.51.100.3"}}, + }, + { + name: "default/unknown service type without external IPs returns nil", + service: "default/custom-type-empty", + expected: nil, }, } { t.Run(tt.name, func(t *testing.T) { - c := &clusterClient{ingressStatusFromService: tt.service} + c := &clusterClient{ + ingressStatusFromService: tt.service, + zone: tt.zone, + } addresses, err := c.ingressStatusAddressesFromService(state) + if tt.expectErr { + require.Error(t, err) + if tt.errContains != "" { + require.Contains(t, err.Error(), tt.errContains) + } + return + } require.NoError(t, err) require.Equal(t, tt.expected, addresses) }) @@ -99,7 +226,7 @@ func TestUpdateIngressesV1Status(t *testing.T) { patched = true patchedPath = r.URL.Path - defer r.Body.Close() + defer func() { _ = r.Body.Close() }() require.NoError(t, json.NewDecoder(r.Body).Decode(&patchedPayload)) w.WriteHeader(http.StatusOK) }))