Skip to content

Commit 919c2b4

Browse files
committed
Refactor TrafficDistribution integration test
Split out a helper to assert correct EndpointSlice hints (and extend that helper to deal with node hints as well, including making sure they *aren't* present when the traffic distribution mode doesn't call for them).
1 parent 6403430 commit 919c2b4

File tree

1 file changed

+73
-92
lines changed

1 file changed

+73
-92
lines changed

test/integration/service/service_test.go

+73-92
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,71 @@ func Test_RemovingExternalIPsFromClusterIPServiceDropsExternalTrafficPolicy(t *t
290290
}
291291
}
292292

293+
func assertEndpointSliceHints(t *testing.T, ctx context.Context, client *clientset.Clientset, namespace, serviceName string, expectZoneHints, expectNodeHints bool) {
294+
t.Helper()
295+
logsBuffer := &bytes.Buffer{}
296+
297+
endpointSlicesHaveExpectedHints := func(ctx context.Context) (bool, error) {
298+
slices, err := client.DiscoveryV1().EndpointSlices(namespace).List(ctx, metav1.ListOptions{LabelSelector: fmt.Sprintf("%s=%s", discoveryv1.LabelServiceName, serviceName)})
299+
if err != nil {
300+
fmt.Fprintf(logsBuffer, "failed to list EndpointSlices for service %q: %v\n", serviceName, err)
301+
return false, nil
302+
}
303+
if slices == nil || len(slices.Items) == 0 {
304+
fmt.Fprintf(logsBuffer, "no EndpointSlices returned for service %q\n", serviceName)
305+
return false, nil
306+
}
307+
fmt.Fprintf(logsBuffer, "EndpointSlices=\n%v\n", format.Object(slices, 1 /* indent one level */))
308+
309+
for _, slice := range slices.Items {
310+
for _, endpoint := range slice.Endpoints {
311+
var ip, zone, nodeName string
312+
if len(endpoint.Addresses) > 0 {
313+
ip = endpoint.Addresses[0]
314+
}
315+
if endpoint.Zone != nil {
316+
zone = *endpoint.Zone
317+
}
318+
if endpoint.NodeName != nil {
319+
nodeName = *endpoint.NodeName
320+
}
321+
if endpoint.Hints == nil {
322+
if expectZoneHints || expectNodeHints {
323+
fmt.Fprintf(logsBuffer, "endpoint with ip %v has no hints, expectZoneHints=%v expectNodeHints=%v\n", ip, expectZoneHints, expectNodeHints)
324+
return false, nil
325+
}
326+
continue
327+
}
328+
if expectZoneHints {
329+
if len(endpoint.Hints.ForZones) != 1 || endpoint.Hints.ForZones[0].Name != zone {
330+
fmt.Fprintf(logsBuffer, "endpoint with ip %v does not have the correct hint, want hint for zone %q\n", ip, zone)
331+
return false, nil
332+
}
333+
} else if len(endpoint.Hints.ForZones) != 0 {
334+
fmt.Fprintf(logsBuffer, "endpoint with ip %v has unexpected hint for zone %q\n", ip, endpoint.Hints.ForZones[0].Name)
335+
return false, nil
336+
}
337+
if expectNodeHints {
338+
if len(endpoint.Hints.ForNodes) != 1 || endpoint.Hints.ForNodes[0].Name != nodeName {
339+
fmt.Fprintf(logsBuffer, "endpoint with ip %v does not have the correct hint, want hint for node %q\n", ip, nodeName)
340+
return false, nil
341+
}
342+
} else if len(endpoint.Hints.ForNodes) != 0 {
343+
fmt.Fprintf(logsBuffer, "endpoint with ip %v has unexpected hint for node %q\n", ip, endpoint.Hints.ForNodes[0].Name)
344+
return false, nil
345+
}
346+
}
347+
}
348+
return true, nil
349+
}
350+
351+
err := wait.PollUntilContextTimeout(ctx, 1*time.Second, 10*time.Second, true, endpointSlicesHaveExpectedHints)
352+
if err != nil {
353+
t.Logf("logsBuffer=\n%v", logsBuffer)
354+
t.Fatalf("Error waiting for EndpointSlices to have expected hints: %v", err)
355+
}
356+
}
357+
293358
// Test transitions involving the `trafficDistribution` field in Service spec.
294359
func Test_TransitionsForTrafficDistribution(t *testing.T) {
295360

@@ -421,43 +486,7 @@ func Test_TransitionsForTrafficDistribution(t *testing.T) {
421486
// hints in EndpointSlice.
422487
////////////////////////////////////////////////////////////////////////////
423488

424-
// logsBuffer captures logs during assertions which multiple retires. These
425-
// will only be printed if the assertion failed.
426-
logsBuffer := &bytes.Buffer{}
427-
428-
endpointSlicesHaveNoHints := func(ctx context.Context) (bool, error) {
429-
slices, err := client.DiscoveryV1().EndpointSlices(ns.GetName()).List(ctx, metav1.ListOptions{LabelSelector: fmt.Sprintf("%s=%s", discoveryv1.LabelServiceName, svc.GetName())})
430-
if err != nil {
431-
fmt.Fprintf(logsBuffer, "failed to list EndpointSlices for service %q: %v\n", svc.GetName(), err)
432-
return false, nil
433-
}
434-
if slices == nil || len(slices.Items) == 0 {
435-
fmt.Fprintf(logsBuffer, "no EndpointSlices returned for service %q\n", svc.GetName())
436-
return false, nil
437-
}
438-
fmt.Fprintf(logsBuffer, "EndpointSlices=\n%v\n", format.Object(slices, 1 /* indent one level */))
439-
440-
for _, slice := range slices.Items {
441-
for _, endpoint := range slice.Endpoints {
442-
var ip string
443-
if len(endpoint.Addresses) > 0 {
444-
ip = endpoint.Addresses[0]
445-
}
446-
if endpoint.Hints != nil && len(endpoint.Hints.ForZones) != 0 {
447-
fmt.Fprintf(logsBuffer, "endpoint with ip %v has hint %+v, want no hint\n", ip, endpoint.Hints)
448-
return false, nil
449-
}
450-
}
451-
}
452-
return true, nil
453-
}
454-
455-
err = wait.PollUntilContextTimeout(ctx, 1*time.Second, 10*time.Second, true, endpointSlicesHaveNoHints)
456-
if err != nil {
457-
t.Logf("logsBuffer=\n%v", logsBuffer)
458-
t.Fatalf("Error waiting for EndpointSlices to have same zone hints: %v", err)
459-
}
460-
logsBuffer.Reset()
489+
assertEndpointSliceHints(t, ctx, client, ns.GetName(), svc.GetName(), false, false)
461490

462491
////////////////////////////////////////////////////////////////////////////
463492
// Update the service by setting the `trafficDistribution: PreferClose` field
@@ -472,43 +501,7 @@ func Test_TransitionsForTrafficDistribution(t *testing.T) {
472501
t.Fatalf("Failed to update test service with 'trafficDistribution: PreferClose': %v", err)
473502
}
474503

475-
endpointSlicesHaveSameZoneHints := func(ctx context.Context) (bool, error) {
476-
slices, err := client.DiscoveryV1().EndpointSlices(ns.GetName()).List(ctx, metav1.ListOptions{LabelSelector: fmt.Sprintf("%s=%s", discoveryv1.LabelServiceName, svc.GetName())})
477-
if err != nil {
478-
fmt.Fprintf(logsBuffer, "failed to list EndpointSlices for service %q: %v\n", svc.GetName(), err)
479-
return false, nil
480-
}
481-
if slices == nil || len(slices.Items) == 0 {
482-
fmt.Fprintf(logsBuffer, "no EndpointSlices returned for service %q\n", svc.GetName())
483-
return false, nil
484-
}
485-
fmt.Fprintf(logsBuffer, "EndpointSlices=\n%v\n", format.Object(slices, 1 /* indent one level */))
486-
487-
for _, slice := range slices.Items {
488-
for _, endpoint := range slice.Endpoints {
489-
var ip string
490-
if len(endpoint.Addresses) > 0 {
491-
ip = endpoint.Addresses[0]
492-
}
493-
var zone string
494-
if endpoint.Zone != nil {
495-
zone = *endpoint.Zone
496-
}
497-
if endpoint.Hints == nil || len(endpoint.Hints.ForZones) != 1 || endpoint.Hints.ForZones[0].Name != zone {
498-
fmt.Fprintf(logsBuffer, "endpoint with ip %v does not have the correct hint, want hint for zone %q\n", ip, zone)
499-
return false, nil
500-
}
501-
}
502-
}
503-
return true, nil
504-
}
505-
506-
err = wait.PollUntilContextTimeout(ctx, 1*time.Second, 10*time.Second, true, endpointSlicesHaveSameZoneHints)
507-
if err != nil {
508-
t.Logf("logsBuffer=\n%v", logsBuffer)
509-
t.Fatalf("Error waiting for EndpointSlices to have same zone hints: %v", err)
510-
}
511-
logsBuffer.Reset()
504+
assertEndpointSliceHints(t, ctx, client, ns.GetName(), svc.GetName(), true, false)
512505

513506
////////////////////////////////////////////////////////////////////////////
514507
// Update the service with the service.kubernetes.io/topology-mode=Auto
@@ -518,18 +511,14 @@ func Test_TransitionsForTrafficDistribution(t *testing.T) {
518511
// service.kubernetes.io/topology-mode=Auto takes affect, since topology
519512
// annotation would not work with only one service pod.
520513
////////////////////////////////////////////////////////////////////////////
514+
521515
svc.Annotations = map[string]string{corev1.AnnotationTopologyMode: "Auto"}
522516
_, err = client.CoreV1().Services(ns.Name).Update(ctx, svc, metav1.UpdateOptions{})
523517
if err != nil {
524518
t.Fatalf("Failed to update test service with 'service.kubernetes.io/topology-mode=Auto' annotation: %v", err)
525519
}
526520

527-
err = wait.PollUntilContextTimeout(ctx, 1*time.Second, 10*time.Second, true, endpointSlicesHaveNoHints)
528-
if err != nil {
529-
t.Logf("logsBuffer=\n%v", logsBuffer)
530-
t.Fatalf("Error waiting for EndpointSlices to have no hints: %v", err)
531-
}
532-
logsBuffer.Reset()
521+
assertEndpointSliceHints(t, ctx, client, ns.GetName(), svc.GetName(), false, false)
533522

534523
////////////////////////////////////////////////////////////////////////////
535524
// Remove the annotation service.kubernetes.io/topology-mode=Auto from the
@@ -538,36 +527,28 @@ func Test_TransitionsForTrafficDistribution(t *testing.T) {
538527
// Assert that EndpointSlice for service again has the correct same-zone
539528
// hints because of the `trafficDistribution: PreferClose` field.
540529
////////////////////////////////////////////////////////////////////////////
530+
541531
svc.Annotations = map[string]string{}
542532
_, err = client.CoreV1().Services(ns.Name).Update(ctx, svc, metav1.UpdateOptions{})
543533
if err != nil {
544534
t.Fatalf("Failed to remove annotation 'service.kubernetes.io/topology-mode=Auto' from service: %v", err)
545535
}
546536

547-
err = wait.PollUntilContextTimeout(ctx, 1*time.Second, 10*time.Second, true, endpointSlicesHaveSameZoneHints)
548-
if err != nil {
549-
t.Logf("logsBuffer=\n%v", logsBuffer)
550-
t.Fatalf("Error waiting for EndpointSlices to have same zone hints: %v", err)
551-
}
552-
logsBuffer.Reset()
537+
assertEndpointSliceHints(t, ctx, client, ns.GetName(), svc.GetName(), true, false)
553538

554539
////////////////////////////////////////////////////////////////////////////
555540
// Remove the field `trafficDistribution: PreferClose` from the service.
556541
//
557542
// Assert that EndpointSlice for service again has no zone hints.
558543
////////////////////////////////////////////////////////////////////////////
544+
559545
svc.Spec.TrafficDistribution = nil
560546
_, err = client.CoreV1().Services(ns.Name).Update(ctx, svc, metav1.UpdateOptions{})
561547
if err != nil {
562548
t.Fatalf("Failed to remove annotation 'service.kubernetes.io/topology-mode=Auto' from service: %v", err)
563549
}
564550

565-
err = wait.PollUntilContextTimeout(ctx, 1*time.Second, 10*time.Second, true, endpointSlicesHaveNoHints)
566-
if err != nil {
567-
t.Logf("logsBuffer=\n%v", logsBuffer)
568-
t.Fatalf("Error waiting for EndpointSlices to have no hints: %v", err)
569-
}
570-
logsBuffer.Reset()
551+
assertEndpointSliceHints(t, ctx, client, ns.GetName(), svc.GetName(), false, false)
571552
}
572553

573554
func Test_TrafficDistribution_FeatureGateEnableDisable(t *testing.T) {

0 commit comments

Comments
 (0)