From e5581201d95ba95edf2f68950db0d1c7df2c5038 Mon Sep 17 00:00:00 2001 From: Spencer Hance Date: Tue, 12 Nov 2019 17:35:01 -0800 Subject: [PATCH] Add session affinity e2e tests for l7-ilb --- cmd/e2e-test/affinity_test.go | 139 +++++++++++++++++++++++++++++++++- pkg/fuzz/features/affinity.go | 8 +- 2 files changed, 142 insertions(+), 5 deletions(-) diff --git a/cmd/e2e-test/affinity_test.go b/cmd/e2e-test/affinity_test.go index d807d126f1..32e9650e69 100644 --- a/cmd/e2e-test/affinity_test.go +++ b/cmd/e2e-test/affinity_test.go @@ -175,9 +175,144 @@ func TestAffinity(t *testing.T) { } } +func TestILBAffinity(t *testing.T) { + t.Parallel() + + for _, tc := range []struct { + desc string + ttl int64 + expect string + transition affinityTransition + beConfig *backendconfig.BackendConfig + }{ + { + desc: "http with no affinity.", + beConfig: fuzz.NewBackendConfigBuilder("", "backendconfig-1").Build(), + expect: "NONE", + transition: affinityTransition{"CLIENT_IP", 0}, + }, + { + desc: "http with cookie based affinity.", + beConfig: fuzz.NewBackendConfigBuilder("", "backendconfig-1"). + SetSessionAffinity("GENERATED_COOKIE"). + Build(), + expect: "GENERATED_COOKIE", + transition: affinityTransition{"NONE", 0}, + }, + { + desc: "http with cookie based affinity and 60s ttl.", + beConfig: fuzz.NewBackendConfigBuilder("", "backendconfig-1"). + SetSessionAffinity("GENERATED_COOKIE"). + SetAffinityCookieTtlSec(60). + Build(), + expect: "GENERATED_COOKIE", + ttl: 60, + transition: affinityTransition{"CLIENT_IP", 0}, + }, + } { + tc := tc // Capture tc as we are running this in parallel. + Framework.RunWithSandbox(tc.desc, t, func(t *testing.T, s *e2e.Sandbox) { + t.Parallel() + + ctx := context.Background() + + svcAnnotation := map[string]string{ + annotations.BackendConfigKey: `{"default":"backendconfig-1"}`, + annotations.NEGAnnotationKey: negVal.String(), + } + + if _, err := Framework.BackendConfigClient.CloudV1beta1().BackendConfigs(s.Namespace).Create(tc.beConfig); err != nil { + t.Fatalf("error creating BackendConfig: %v", err) + } + t.Logf("BackendConfig created (%s/%s) ", s.Namespace, tc.beConfig.Name) + + _, err := e2e.CreateEchoService(s, "service-1", svcAnnotation) + if err != nil { + t.Fatalf("error creating echo service: %v", err) + } + t.Logf("Echo service created (%s/%s)", s.Namespace, "service-1") + + ing := fuzz.NewIngressBuilder(s.Namespace, "ingress-1", ""). + AddPath("test.com", "/", "service-1", intstr.FromInt(80)). + ConfigureForILB(). + Build() + crud := e2e.IngressCRUD{C: Framework.Clientset} + if _, err := crud.Create(ing); err != nil { + t.Fatalf("error creating Ingress spec: %v", err) + } + t.Logf("Ingress created (%s/%s)", s.Namespace, ing.Name) + + ing, err = e2e.WaitForIngress(s, ing, nil) + if err != nil { + t.Fatalf("error waiting for Ingress to stabilize: %v", err) + } + t.Logf("GCLB resources created (%s/%s)", s.Namespace, ing.Name) + + vip := ing.Status.LoadBalancer.Ingress[0].IP + t.Logf("Ingress %s/%s VIP = %s", s.Namespace, ing.Name, vip) + + params := &fuzz.GCLBForVIPParams{VIP: vip, Validators: fuzz.FeatureValidators(features.All), Region: Framework.Region} + gclb, err := fuzz.GCLBForVIP(context.Background(), Framework.Cloud, params) + if err != nil { + t.Fatalf("Error getting GCP resources for LB with IP = %q: %v", vip, err) + } + + // Check conformity + if err := verifyAffinity(t, gclb, s.Namespace, "service-1", tc.expect, tc.ttl); err != nil { + t.Error(err) + } + + // Test modifications + if err := retry.RetryOnConflict(retry.DefaultRetry, func() error { + bc, err := Framework.BackendConfigClient.CloudV1beta1().BackendConfigs(s.Namespace).Get(tc.beConfig.Name, metav1.GetOptions{}) + if err != nil { + return err + } + if bc.Spec.SessionAffinity == nil { + bc.Spec.SessionAffinity = &backendconfig.SessionAffinityConfig{} + } + bc.Spec.SessionAffinity.AffinityType = tc.transition.affinity + bc.Spec.SessionAffinity.AffinityCookieTtlSec = &tc.transition.ttl + _, err = Framework.BackendConfigClient.CloudV1beta1().BackendConfigs(s.Namespace).Update(bc) + return err + }); err != nil { + t.Errorf("Failed to update BackendConfig affinity settings for %s: %v", t.Name(), err) + } + + if err := wait.Poll(tansitionPollInterval, transitionPollTimeout, func() (bool, error) { + gclb, err = fuzz.GCLBForVIP(context.Background(), Framework.Cloud, params) + if err != nil { + t.Logf("error getting GCP resources for LB with IP = %q: %v", vip, err) + return false, nil + } + if err := verifyAffinity(t, gclb, s.Namespace, "service-1", tc.transition.affinity, tc.transition.ttl); err != nil { + return false, nil + } + return true, nil + }); err != nil { + t.Errorf("error waiting for BackendConfig affinity transition propagation to GCLB: %v", err) + } + + // Wait for GCLB resources to be deleted. + if err := crud.Delete(s.Namespace, ing.Name); err != nil { + t.Errorf("Delete(%q) = %v, want nil", ing.Name, err) + } + + deleteOptions := &fuzz.GCLBDeleteOptions{ + SkipDefaultBackend: true, + } + t.Logf("Waiting for GCLB resources to be deleted (%s/%s)", s.Namespace, ing.Name) + if err := e2e.WaitForGCLBDeletion(ctx, Framework.Cloud, gclb, deleteOptions); err != nil { + t.Errorf("e2e.WaitForGCLBDeletion(...) = %v, want nil", err) + } + t.Logf("GCLB resources deleted (%s/%s)", s.Namespace, ing.Name) + }) + } +} + func verifyAffinity(t *testing.T, gclb *fuzz.GCLB, svcNamespace, svcName string, expect string, ttl int64) error { for _, bs := range gclb.BackendService { - desc := utils.DescriptionFromString(bs.GA.Description) + desc := utils.DescriptionFromString(bs.Beta.Description) if desc.ServiceName != fmt.Sprintf("%s/%s", svcNamespace, svcName) { continue } @@ -187,7 +322,7 @@ func verifyAffinity(t *testing.T, gclb *fuzz.GCLB, svcNamespace, svcName string, } if bs.GA.AffinityCookieTtlSec != ttl { return fmt.Errorf("verifyAffinity(..., %q, %q, ...) = %v, want %v (AffinityCookieTtlSec)", - svcNamespace, svcName, bs.GA.SessionAffinity, ttl) + svcNamespace, svcName, bs.GA.AffinityCookieTtlSec, ttl) } } return nil diff --git a/pkg/fuzz/features/affinity.go b/pkg/fuzz/features/affinity.go index ff2600e41e..9550f561bb 100644 --- a/pkg/fuzz/features/affinity.go +++ b/pkg/fuzz/features/affinity.go @@ -106,9 +106,11 @@ func haveGCLBCookie(resp *http.Response) bool { return false } - if !strings.HasPrefix(cookie, "GCLB") { - return false + fmt.Printf("cookie = %+v\n", cookie) + + if strings.HasPrefix(cookie, "GCLB") || strings.HasPrefix(cookie, "GCILB") { + return true } - return true + return false }