From 7a78897d0b6e8994c5c9151748be40dc6d6d9933 Mon Sep 17 00:00:00 2001 From: Filip Petkovski Date: Tue, 7 Jun 2022 17:19:40 +0200 Subject: [PATCH] Improve reliability of Kubernetes SD tests (#10761) The tests for Kubernetes SD rely on comparing target groups by first serializing them to JSON. However, the target group MarshalJSON function only serializes the __address__ label, which makes eliminates all other labels from the comparison. This commit implements a separate marshaling function intended for use in Kubernetes SD tests. The function serializes all target labels, making comparisons much more reliable. The commit also fixes all tests that started to fail due to the newly introduced change. Signed-off-by: Filip Petkovski --- discovery/kubernetes/endpointslice_test.go | 48 ++++++++++++++++------ discovery/kubernetes/kubernetes_test.go | 20 ++++++++- 2 files changed, 54 insertions(+), 14 deletions(-) diff --git a/discovery/kubernetes/endpointslice_test.go b/discovery/kubernetes/endpointslice_test.go index 0065bdd06b..16148d2a0f 100644 --- a/discovery/kubernetes/endpointslice_test.go +++ b/discovery/kubernetes/endpointslice_test.go @@ -644,10 +644,16 @@ func TestEndpointSliceDiscoveryWithServiceUpdate(t *testing.T) { Targets: []model.LabelSet{ { "__address__": "1.2.3.4:9000", - "__meta_kubernetes_endpointslice_endpoint_hostname": "testendpoint1", - "__meta_kubernetes_endpointslice_port": "9000", - "__meta_kubernetes_endpointslice_port_name": "testport", - "__meta_kubernetes_endpointslice_port_protocol": "TCP", + "__meta_kubernetes_endpointslice_address_target_kind": "", + "__meta_kubernetes_endpointslice_address_target_name": "", + "__meta_kubernetes_endpointslice_endpoint_conditions_ready": "true", + "__meta_kubernetes_endpointslice_endpoint_hostname": "testendpoint1", + "__meta_kubernetes_endpointslice_endpoint_topology_present_topology": "true", + "__meta_kubernetes_endpointslice_endpoint_topology_topology": "value", + "__meta_kubernetes_endpointslice_port": "9000", + "__meta_kubernetes_endpointslice_port_app_protocol": "http", + "__meta_kubernetes_endpointslice_port_name": "testport", + "__meta_kubernetes_endpointslice_port_protocol": "TCP", }, { "__address__": "2.3.4.5:9000", @@ -655,6 +661,7 @@ func TestEndpointSliceDiscoveryWithServiceUpdate(t *testing.T) { "__meta_kubernetes_endpointslice_port": "9000", "__meta_kubernetes_endpointslice_port_name": "testport", "__meta_kubernetes_endpointslice_port_protocol": "TCP", + "__meta_kubernetes_endpointslice_port_app_protocol": "http", }, { "__address__": "3.4.5.6:9000", @@ -662,6 +669,7 @@ func TestEndpointSliceDiscoveryWithServiceUpdate(t *testing.T) { "__meta_kubernetes_endpointslice_port": "9000", "__meta_kubernetes_endpointslice_port_name": "testport", "__meta_kubernetes_endpointslice_port_protocol": "TCP", + "__meta_kubernetes_endpointslice_port_app_protocol": "http", }, }, Labels: model.LabelSet{ @@ -755,10 +763,16 @@ func TestEndpointSliceDiscoveryNamespaces(t *testing.T) { Targets: []model.LabelSet{ { "__address__": "1.2.3.4:9000", - "__meta_kubernetes_endpointslice_endpoint_hostname": "testendpoint1", - "__meta_kubernetes_endpointslice_port": "9000", - "__meta_kubernetes_endpointslice_port_name": "testport", - "__meta_kubernetes_endpointslice_port_protocol": "TCP", + "__meta_kubernetes_endpointslice_address_target_kind": "", + "__meta_kubernetes_endpointslice_address_target_name": "", + "__meta_kubernetes_endpointslice_endpoint_conditions_ready": "true", + "__meta_kubernetes_endpointslice_endpoint_hostname": "testendpoint1", + "__meta_kubernetes_endpointslice_endpoint_topology_present_topology": "true", + "__meta_kubernetes_endpointslice_endpoint_topology_topology": "value", + "__meta_kubernetes_endpointslice_port": "9000", + "__meta_kubernetes_endpointslice_port_app_protocol": "http", + "__meta_kubernetes_endpointslice_port_name": "testport", + "__meta_kubernetes_endpointslice_port_protocol": "TCP", }, { "__address__": "2.3.4.5:9000", @@ -766,6 +780,7 @@ func TestEndpointSliceDiscoveryNamespaces(t *testing.T) { "__meta_kubernetes_endpointslice_port": "9000", "__meta_kubernetes_endpointslice_port_name": "testport", "__meta_kubernetes_endpointslice_port_protocol": "TCP", + "__meta_kubernetes_endpointslice_port_app_protocol": "http", }, { "__address__": "3.4.5.6:9000", @@ -773,6 +788,7 @@ func TestEndpointSliceDiscoveryNamespaces(t *testing.T) { "__meta_kubernetes_endpointslice_port": "9000", "__meta_kubernetes_endpointslice_port_name": "testport", "__meta_kubernetes_endpointslice_port_protocol": "TCP", + "__meta_kubernetes_endpointslice_port_app_protocol": "http", }, }, Labels: model.LabelSet{ @@ -871,10 +887,16 @@ func TestEndpointSliceDiscoveryOwnNamespace(t *testing.T) { Targets: []model.LabelSet{ { "__address__": "1.2.3.4:9000", - "__meta_kubernetes_endpointslice_endpoint_hostname": "testendpoint1", - "__meta_kubernetes_endpointslice_port": "9000", - "__meta_kubernetes_endpointslice_port_name": "testport", - "__meta_kubernetes_endpointslice_port_protocol": "TCP", + "__meta_kubernetes_endpointslice_address_target_kind": "", + "__meta_kubernetes_endpointslice_address_target_name": "", + "__meta_kubernetes_endpointslice_endpoint_conditions_ready": "true", + "__meta_kubernetes_endpointslice_endpoint_hostname": "testendpoint1", + "__meta_kubernetes_endpointslice_endpoint_topology_present_topology": "true", + "__meta_kubernetes_endpointslice_endpoint_topology_topology": "value", + "__meta_kubernetes_endpointslice_port": "9000", + "__meta_kubernetes_endpointslice_port_app_protocol": "http", + "__meta_kubernetes_endpointslice_port_name": "testport", + "__meta_kubernetes_endpointslice_port_protocol": "TCP", }, { "__address__": "2.3.4.5:9000", @@ -882,6 +904,7 @@ func TestEndpointSliceDiscoveryOwnNamespace(t *testing.T) { "__meta_kubernetes_endpointslice_port": "9000", "__meta_kubernetes_endpointslice_port_name": "testport", "__meta_kubernetes_endpointslice_port_protocol": "TCP", + "__meta_kubernetes_endpointslice_port_app_protocol": "http", }, { "__address__": "3.4.5.6:9000", @@ -889,6 +912,7 @@ func TestEndpointSliceDiscoveryOwnNamespace(t *testing.T) { "__meta_kubernetes_endpointslice_port": "9000", "__meta_kubernetes_endpointslice_port_name": "testport", "__meta_kubernetes_endpointslice_port_protocol": "TCP", + "__meta_kubernetes_endpointslice_port_app_protocol": "http", }, }, Labels: model.LabelSet{ diff --git a/discovery/kubernetes/kubernetes_test.go b/discovery/kubernetes/kubernetes_test.go index 1c6c237805..d0ed4c6ca1 100644 --- a/discovery/kubernetes/kubernetes_test.go +++ b/discovery/kubernetes/kubernetes_test.go @@ -163,11 +163,11 @@ Loop: func requireTargetGroups(t *testing.T, expected, res map[string]*targetgroup.Group) { t.Helper() - b1, err := json.Marshal(expected) + b1, err := marshalTargetGroups(expected) if err != nil { panic(err) } - b2, err := json.Marshal(res) + b2, err := marshalTargetGroups(res) if err != nil { panic(err) } @@ -175,6 +175,22 @@ func requireTargetGroups(t *testing.T, expected, res map[string]*targetgroup.Gro require.Equal(t, string(b1), string(b2)) } +// marshalTargetGroups serializes a set of target groups to JSON, ignoring the +// custom MarshalJSON function defined on the targetgroup.Group struct. +// marshalTargetGroups can be used for making exact comparisons between target groups +// as it will serialize all target labels. +func marshalTargetGroups(tgs map[string]*targetgroup.Group) ([]byte, error) { + type targetGroupAlias targetgroup.Group + + aliases := make(map[string]*targetGroupAlias, len(tgs)) + for k, v := range tgs { + tg := targetGroupAlias(*v) + aliases[k] = &tg + } + + return json.Marshal(aliases) +} + type hasSynced interface { // hasSynced returns true if all informers synced. // This is only used in testing to determine when discoverer synced to