Просмотр исходного кода

test(e2e): make provider push capabilities explicit

Moritz Johner 2 месяцев назад
Родитель
Сommit
39d3e27971

+ 57 - 0
e2e/suites/provider/cases/common/provider_runtime_test.go

@@ -46,3 +46,60 @@ func TestClusterProviderExternalSecretRuntimeSupportsAuthLifecycle(t *testing.T)
 		t.Fatalf("expected SupportsAuthLifecycle to return true when both hooks are present")
 	}
 }
+
+func TestClusterProviderPushRuntimeSupportsAuthLifecycle(t *testing.T) {
+	runtimeWithoutHooks := &ClusterProviderPushRuntime{}
+	if runtimeWithoutHooks.SupportsAuthLifecycle() {
+		t.Fatalf("expected SupportsAuthLifecycle to return false when both hooks are nil")
+	}
+
+	runtimeWithBreakOnly := &ClusterProviderPushRuntime{
+		BreakAuth: func() {},
+	}
+	if runtimeWithBreakOnly.SupportsAuthLifecycle() {
+		t.Fatalf("expected SupportsAuthLifecycle to return false when RepairAuth is nil")
+	}
+
+	runtimeWithRepairOnly := &ClusterProviderPushRuntime{
+		RepairAuth: func() {},
+	}
+	if runtimeWithRepairOnly.SupportsAuthLifecycle() {
+		t.Fatalf("expected SupportsAuthLifecycle to return false when BreakAuth is nil")
+	}
+
+	runtimeWithBothHooks := &ClusterProviderPushRuntime{
+		BreakAuth:  func() {},
+		RepairAuth: func() {},
+	}
+	if !runtimeWithBothHooks.SupportsAuthLifecycle() {
+		t.Fatalf("expected SupportsAuthLifecycle to return true when both hooks are present")
+	}
+}
+
+func TestClusterProviderPushRuntimeSupportsRemoteAbsenceAssertions(t *testing.T) {
+	runtimeWithoutExpectation := &ClusterProviderPushRuntime{}
+	if runtimeWithoutExpectation.SupportsRemoteAbsenceAssertions() {
+		t.Fatalf("expected SupportsRemoteAbsenceAssertions to return false when ExpectNoRemoteSecret is nil")
+	}
+
+	runtimeWithExpectation := &ClusterProviderPushRuntime{
+		ExpectNoRemoteSecret: func(_, _ string) {},
+	}
+	if !runtimeWithExpectation.SupportsRemoteAbsenceAssertions() {
+		t.Fatalf("expected SupportsRemoteAbsenceAssertions to return true when ExpectNoRemoteSecret is present")
+	}
+}
+
+func TestClusterProviderPushRuntimeSupportsRemoteNamespaceOverrides(t *testing.T) {
+	runtimeWithoutFactory := &ClusterProviderPushRuntime{}
+	if runtimeWithoutFactory.SupportsRemoteNamespaceOverrides() {
+		t.Fatalf("expected SupportsRemoteNamespaceOverrides to return false when CreateWritableRemoteScope is nil")
+	}
+
+	runtimeWithFactory := &ClusterProviderPushRuntime{
+		CreateWritableRemoteScope: func(_ string) string { return "override-namespace" },
+	}
+	if !runtimeWithFactory.SupportsRemoteNamespaceOverrides() {
+		t.Fatalf("expected SupportsRemoteNamespaceOverrides to return true when CreateWritableRemoteScope is present")
+	}
+}

+ 29 - 3
e2e/suites/provider/cases/common/push_secret.go

@@ -49,6 +49,18 @@ type ClusterProviderPushRuntime struct {
 	CreateWritableRemoteScope func(prefix string) string
 }
 
+func (r *ClusterProviderPushRuntime) SupportsAuthLifecycle() bool {
+	return r != nil && r.BreakAuth != nil && r.RepairAuth != nil
+}
+
+func (r *ClusterProviderPushRuntime) SupportsRemoteAbsenceAssertions() bool {
+	return r != nil && r.ExpectNoRemoteSecret != nil
+}
+
+func (r *ClusterProviderPushRuntime) SupportsRemoteNamespaceOverrides() bool {
+	return r != nil && r.CreateWritableRemoteScope != nil
+}
+
 func PushSecretPreservesSourceMetadata(f *framework.Framework) (string, func(*framework.TestCase)) {
 	return "[common] should preserve source secret type, labels, and annotations when pushing to the namespaced Provider", func(tc *framework.TestCase) {
 		tc.PushSecretSource = &corev1.Secret{
@@ -224,13 +236,19 @@ func ClusterProviderPushAllowsRemoteNamespaceOverride(f *framework.Framework, ha
 				Name:      "push-remote-override",
 				AuthScope: esv1.AuthenticationScopeManifestNamespace,
 			})
+			Expect(runtime).NotTo(BeNil(), "cluster provider push harness returned nil runtime")
+			if !runtime.SupportsRemoteNamespaceOverrides() {
+				Skip(fmt.Sprintf("provider %q does not support remote namespace override hooks", runtime.ClusterProviderName))
+			}
 			overrideNamespace := runtime.CreateWritableRemoteScope("push-remote-override-target")
 			applyClusterProviderPushSecret(tc, runtime, "push-remote-override-remote")
 			tc.PushSecret.Spec.Data[0].Metadata = pushSecretMetadataWithRemoteNamespace(overrideNamespace)
 			tc.VerifyPushSecretOutcome = func(ps *esv1alpha1.PushSecret, _ esv1.SecretsClient) {
 				waitForPushSecretStatus(tc.Framework, ps.Namespace, ps.Name, corev1.ConditionTrue)
 				runtime.WaitForRemoteSecretValue(overrideNamespace, "push-remote-override-remote", "value", "override-push-value")
-				runtime.ExpectNoRemoteSecret(runtime.DefaultRemoteNamespace, "push-remote-override-remote")
+				if runtime.SupportsRemoteAbsenceAssertions() {
+					runtime.ExpectNoRemoteSecret(runtime.DefaultRemoteNamespace, "push-remote-override-remote")
+				}
 			}
 		}
 	}
@@ -261,7 +279,9 @@ func ClusterProviderPushDeniedByConditions(f *framework.Framework, harness Clust
 		}
 		tc.VerifyPushSecretOutcome = func(ps *esv1alpha1.PushSecret, _ esv1.SecretsClient) {
 			waitForPushSecretStatus(tc.Framework, ps.Namespace, ps.Name, corev1.ConditionFalse)
-			runtime.ExpectNoRemoteSecret(runtime.DefaultRemoteNamespace, "push-deny-remote")
+			if runtime.SupportsRemoteAbsenceAssertions() {
+				runtime.ExpectNoRemoteSecret(runtime.DefaultRemoteNamespace, "push-deny-remote")
+			}
 			expectEventMessage(tc.Framework, ps.Namespace, ps.Name, "PushSecret", fmt.Sprintf("using ClusterProvider %q is not allowed from namespace %q: denied by spec.conditions", runtime.ClusterProviderName, f.Namespace.Name))
 		}
 	}
@@ -312,13 +332,19 @@ func clusterProviderPushRecoveryCase(f *framework.Framework, harness ClusterProv
 				Name:      name,
 				AuthScope: authScope,
 			})
+			Expect(runtime).NotTo(BeNil(), "cluster provider push harness returned nil runtime")
+			if !runtime.SupportsAuthLifecycle() {
+				Skip(fmt.Sprintf("provider %q does not support auth lifecycle recovery hooks", runtime.ClusterProviderName))
+			}
 			applyClusterProviderPushSecret(tc, runtime, fmt.Sprintf("%s-remote", name))
 			tc.PushSecret.Spec.RefreshInterval = &metav1.Duration{Duration: time.Hour}
 			runtime.BreakAuth()
 		}
 		tc.VerifyPushSecretOutcome = func(ps *esv1alpha1.PushSecret, _ esv1.SecretsClient) {
 			waitForPushSecretStatus(tc.Framework, ps.Namespace, ps.Name, corev1.ConditionFalse)
-			runtime.ExpectNoRemoteSecret(runtime.DefaultRemoteNamespace, fmt.Sprintf("%s-remote", name))
+			if runtime.SupportsRemoteAbsenceAssertions() {
+				runtime.ExpectNoRemoteSecret(runtime.DefaultRemoteNamespace, fmt.Sprintf("%s-remote", name))
+			}
 			runtime.RepairAuth()
 			waitForPushSecretStatus(tc.Framework, ps.Namespace, ps.Name, corev1.ConditionTrue)
 			runtime.WaitForRemoteSecretValue(runtime.DefaultRemoteNamespace, fmt.Sprintf("%s-remote", name), "value", expectedValue)

+ 0 - 6
e2e/suites/provider/cases/fake/provider_v2.go

@@ -243,18 +243,12 @@ func newFakeClusterProviderPushHarness(f *framework.Framework) common.ClusterPro
 			return &common.ClusterProviderPushRuntime{
 				ClusterProviderName:    clusterProviderName,
 				DefaultRemoteNamespace: s.fakeConfigNamespace,
-				BreakAuth:              func() {},
-				RepairAuth:             func() {},
 				WaitForRemoteSecretValue: func(_, name, _ string, expectedValue string) {
 					waitForPushedValueViaExternalSecret(f, esv1.SecretStoreRef{
 						Name: clusterProviderName,
 						Kind: esv1.ClusterProviderKindStr,
 					}, name, expectedValue)
 				},
-				ExpectNoRemoteSecret: func(string, string) {},
-				CreateWritableRemoteScope: func(prefix string) string {
-					return common.CreateProviderCaseNamespace(f, prefix, defaultV2PollInterval)
-				},
 			}
 		},
 	}

+ 1 - 0
e2e/suites/provider/cases/kubernetes/push_v2.go

@@ -67,6 +67,7 @@ func newKubernetesClusterProviderPushHarness(f *framework.Framework) common.Clus
 			clusterProviderName := s.createClusterProvider(cfg.Name, cfg.AuthScope, cfg.Conditions)
 			frameworkv2.WaitForClusterProviderReady(f, clusterProviderName, defaultV2WaitTimeout)
 
+			// Kubernetes push harness supports all optional ClusterProvider push capabilities.
 			return &common.ClusterProviderPushRuntime{
 				ClusterProviderName:    clusterProviderName,
 				DefaultRemoteNamespace: s.remoteNamespace,