From ced6ffabd122d001c86398374094e1b53c636afe Mon Sep 17 00:00:00 2001 From: TheiLLeniumStudios <104288623+TheiLLeniumStudios@users.noreply.github.com> Date: Sun, 28 Dec 2025 08:47:59 +0100 Subject: [PATCH] refactor: Move test helpers to testutil --- .../controller/configmap_reconciler_test.go | 53 +-- .../controller/namespace_reconciler_test.go | 9 +- internal/pkg/controller/retry_test.go | 21 +- .../pkg/controller/secret_reconciler_test.go | 57 +-- internal/pkg/controller/test_helpers_test.go | 340 ++---------------- internal/pkg/reload/service_test.go | 82 ++--- internal/pkg/testutil/fixtures.go | 286 +++++++++++++++ internal/pkg/testutil/testutil.go | 174 ++------- internal/pkg/workload/registry_test.go | 4 - test/e2e/e2e_test.go | 107 +++--- 10 files changed, 489 insertions(+), 644 deletions(-) create mode 100644 internal/pkg/testutil/fixtures.go diff --git a/internal/pkg/controller/configmap_reconciler_test.go b/internal/pkg/controller/configmap_reconciler_test.go index ad457d98..1b114057 100644 --- a/internal/pkg/controller/configmap_reconciler_test.go +++ b/internal/pkg/controller/configmap_reconciler_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/stakater/Reloader/internal/pkg/config" + "github.com/stakater/Reloader/internal/pkg/testutil" ) func TestConfigMapReconciler_NotFound(t *testing.T) { @@ -16,7 +17,7 @@ func TestConfigMapReconciler_NotFound_ReloadOnDelete(t *testing.T) { cfg := config.NewDefault() cfg.ReloadOnDelete = true - deployment := testDeployment("test-deployment", "default", map[string]string{ + deployment := testutil.NewDeployment("test-deployment", "default", map[string]string{ cfg.Annotations.ConfigmapReload: "deleted-cm", }) reconciler := newConfigMapReconciler(t, cfg, deployment) @@ -27,7 +28,7 @@ func TestConfigMapReconciler_IgnoredNamespace(t *testing.T) { cfg := config.NewDefault() cfg.IgnoredNamespaces = []string{"kube-system"} - cm := testConfigMap("test-cm", "kube-system") + cm := testutil.NewConfigMap("test-cm", "kube-system") reconciler := newConfigMapReconciler(t, cfg, cm) assertReconcileSuccess(t, reconciler, reconcileRequest("test-cm", "kube-system")) } @@ -35,8 +36,8 @@ func TestConfigMapReconciler_IgnoredNamespace(t *testing.T) { func TestConfigMapReconciler_NoMatchingWorkloads(t *testing.T) { cfg := config.NewDefault() - cm := testConfigMap("test-cm", "default") - deployment := testDeployment("test-deployment", "default", nil) + cm := testutil.NewConfigMap("test-cm", "default") + deployment := testutil.NewDeployment("test-deployment", "default", nil) reconciler := newConfigMapReconciler(t, cfg, cm, deployment) assertReconcileSuccess(t, reconciler, reconcileRequest("test-cm", "default")) } @@ -45,8 +46,8 @@ func TestConfigMapReconciler_MatchingDeployment_AutoAnnotation(t *testing.T) { cfg := config.NewDefault() cfg.AutoReloadAll = true - cm := testConfigMap("test-cm", "default") - deployment := testDeploymentWithEnvFrom("test-deployment", "default", "test-cm", "") + cm := testutil.NewConfigMap("test-cm", "default") + deployment := testutil.NewDeploymentWithEnvFrom("test-deployment", "default", "test-cm", "") reconciler := newConfigMapReconciler(t, cfg, cm, deployment) assertReconcileSuccess(t, reconciler, reconcileRequest("test-cm", "default")) } @@ -54,8 +55,8 @@ func TestConfigMapReconciler_MatchingDeployment_AutoAnnotation(t *testing.T) { func TestConfigMapReconciler_MatchingDeployment_ExplicitAnnotation(t *testing.T) { cfg := config.NewDefault() - cm := testConfigMap("test-cm", "default") - deployment := testDeployment("test-deployment", "default", map[string]string{ + cm := testutil.NewConfigMap("test-cm", "default") + deployment := testutil.NewDeployment("test-deployment", "default", map[string]string{ cfg.Annotations.ConfigmapReload: "test-cm", }) reconciler := newConfigMapReconciler(t, cfg, cm, deployment) @@ -65,8 +66,8 @@ func TestConfigMapReconciler_MatchingDeployment_ExplicitAnnotation(t *testing.T) func TestConfigMapReconciler_WorkloadInDifferentNamespace(t *testing.T) { cfg := config.NewDefault() - cm := testConfigMap("test-cm", "namespace-a") - deployment := testDeployment("test-deployment", "namespace-b", map[string]string{ + cm := testutil.NewConfigMap("test-cm", "namespace-a") + deployment := testutil.NewDeployment("test-deployment", "namespace-b", map[string]string{ cfg.Annotations.ConfigmapReload: "test-cm", }) reconciler := newConfigMapReconciler(t, cfg, cm, deployment) @@ -77,8 +78,8 @@ func TestConfigMapReconciler_IgnoredWorkloadType(t *testing.T) { cfg := config.NewDefault() cfg.IgnoredWorkloads = []string{"deployment"} - cm := testConfigMap("test-cm", "default") - deployment := testDeployment("test-deployment", "default", map[string]string{ + cm := testutil.NewConfigMap("test-cm", "default") + deployment := testutil.NewDeployment("test-deployment", "default", map[string]string{ cfg.Annotations.ConfigmapReload: "test-cm", }) reconciler := newConfigMapReconciler(t, cfg, cm, deployment) @@ -88,8 +89,8 @@ func TestConfigMapReconciler_IgnoredWorkloadType(t *testing.T) { func TestConfigMapReconciler_DaemonSet(t *testing.T) { cfg := config.NewDefault() - cm := testConfigMap("test-cm", "default") - daemonset := testDaemonSet("test-daemonset", "default", map[string]string{ + cm := testutil.NewConfigMap("test-cm", "default") + daemonset := testutil.NewDaemonSet("test-daemonset", "default", map[string]string{ cfg.Annotations.ConfigmapReload: "test-cm", }) reconciler := newConfigMapReconciler(t, cfg, cm, daemonset) @@ -99,8 +100,8 @@ func TestConfigMapReconciler_DaemonSet(t *testing.T) { func TestConfigMapReconciler_StatefulSet(t *testing.T) { cfg := config.NewDefault() - cm := testConfigMap("test-cm", "default") - statefulset := testStatefulSet("test-statefulset", "default", map[string]string{ + cm := testutil.NewConfigMap("test-cm", "default") + statefulset := testutil.NewStatefulSet("test-statefulset", "default", map[string]string{ cfg.Annotations.ConfigmapReload: "test-cm", }) reconciler := newConfigMapReconciler(t, cfg, cm, statefulset) @@ -110,14 +111,14 @@ func TestConfigMapReconciler_StatefulSet(t *testing.T) { func TestConfigMapReconciler_MultipleWorkloads(t *testing.T) { cfg := config.NewDefault() - cm := testConfigMap("shared-cm", "default") - deployment1 := testDeployment("deployment-1", "default", map[string]string{ + cm := testutil.NewConfigMap("shared-cm", "default") + deployment1 := testutil.NewDeployment("deployment-1", "default", map[string]string{ cfg.Annotations.ConfigmapReload: "shared-cm", }) - deployment2 := testDeployment("deployment-2", "default", map[string]string{ + deployment2 := testutil.NewDeployment("deployment-2", "default", map[string]string{ cfg.Annotations.ConfigmapReload: "shared-cm", }) - daemonset := testDaemonSet("daemonset-1", "default", map[string]string{ + daemonset := testutil.NewDaemonSet("daemonset-1", "default", map[string]string{ cfg.Annotations.ConfigmapReload: "shared-cm", }) @@ -129,8 +130,8 @@ func TestConfigMapReconciler_VolumeMount(t *testing.T) { cfg := config.NewDefault() cfg.AutoReloadAll = true - cm := testConfigMap("volume-cm", "default") - deployment := testDeploymentWithVolume("test-deployment", "default", "volume-cm", "") + cm := testutil.NewConfigMap("volume-cm", "default") + deployment := testutil.NewDeploymentWithVolume("test-deployment", "default", "volume-cm", "") reconciler := newConfigMapReconciler(t, cfg, cm, deployment) assertReconcileSuccess(t, reconciler, reconcileRequest("volume-cm", "default")) } @@ -139,8 +140,8 @@ func TestConfigMapReconciler_ProjectedVolume(t *testing.T) { cfg := config.NewDefault() cfg.AutoReloadAll = true - cm := testConfigMap("projected-cm", "default") - deployment := testDeploymentWithProjectedVolume("test-deployment", "default", "projected-cm", "") + cm := testutil.NewConfigMap("projected-cm", "default") + deployment := testutil.NewDeploymentWithProjectedVolume("test-deployment", "default", "projected-cm", "") reconciler := newConfigMapReconciler(t, cfg, cm, deployment) assertReconcileSuccess(t, reconciler, reconcileRequest("projected-cm", "default")) } @@ -148,10 +149,10 @@ func TestConfigMapReconciler_ProjectedVolume(t *testing.T) { func TestConfigMapReconciler_SearchAnnotation(t *testing.T) { cfg := config.NewDefault() - cm := testConfigMapWithAnnotations("test-cm", "default", map[string]string{ + cm := testutil.NewConfigMapWithAnnotations("test-cm", "default", map[string]string{ cfg.Annotations.Match: "true", }) - deployment := testDeployment("test-deployment", "default", map[string]string{ + deployment := testutil.NewDeployment("test-deployment", "default", map[string]string{ cfg.Annotations.Search: "true", }) reconciler := newConfigMapReconciler(t, cfg, cm, deployment) diff --git a/internal/pkg/controller/namespace_reconciler_test.go b/internal/pkg/controller/namespace_reconciler_test.go index 3d4fcc65..516b5816 100644 --- a/internal/pkg/controller/namespace_reconciler_test.go +++ b/internal/pkg/controller/namespace_reconciler_test.go @@ -5,6 +5,7 @@ import ( "github.com/stakater/Reloader/internal/pkg/config" "github.com/stakater/Reloader/internal/pkg/controller" + "github.com/stakater/Reloader/internal/pkg/testutil" "k8s.io/apimachinery/pkg/labels" ) @@ -70,7 +71,7 @@ func TestNamespaceReconciler_Add(t *testing.T) { cfg.NamespaceSelectors = []labels.Selector{selector} cache := controller.NewNamespaceCache(true) - ns := testNamespace("test-ns", map[string]string{"env": "production"}) + ns := testutil.NewNamespace("test-ns", map[string]string{"env": "production"}) reconciler := newNamespaceReconciler(t, cfg, cache, ns) assertReconcileSuccess(t, reconciler, namespaceRequest("test-ns")) @@ -88,7 +89,7 @@ func TestNamespaceReconciler_Remove_LabelChange(t *testing.T) { cache := controller.NewNamespaceCache(true) cache.Add("test-ns") // Pre-populate - ns := testNamespace("test-ns", map[string]string{"env": "staging"}) // Non-matching + ns := testutil.NewNamespace("test-ns", map[string]string{"env": "staging"}) // Non-matching reconciler := newNamespaceReconciler(t, cfg, cache, ns) assertReconcileSuccess(t, reconciler, namespaceRequest("test-ns")) @@ -122,7 +123,7 @@ func TestNamespaceReconciler_MultipleSelectors(t *testing.T) { cfg.NamespaceSelectors = []labels.Selector{selector1, selector2} cache := controller.NewNamespaceCache(true) - ns := testNamespace("test-ns", map[string]string{"team": "platform"}) + ns := testutil.NewNamespace("test-ns", map[string]string{"team": "platform"}) reconciler := newNamespaceReconciler(t, cfg, cache, ns) assertReconcileSuccess(t, reconciler, namespaceRequest("test-ns")) @@ -138,7 +139,7 @@ func TestNamespaceReconciler_NoLabels(t *testing.T) { cfg.NamespaceSelectors = []labels.Selector{selector} cache := controller.NewNamespaceCache(true) - ns := testNamespace("test-ns", nil) // No labels + ns := testutil.NewNamespace("test-ns", nil) // No labels reconciler := newNamespaceReconciler(t, cfg, cache, ns) assertReconcileSuccess(t, reconciler, namespaceRequest("test-ns")) diff --git a/internal/pkg/controller/retry_test.go b/internal/pkg/controller/retry_test.go index a6237586..b62bc7a4 100644 --- a/internal/pkg/controller/retry_test.go +++ b/internal/pkg/controller/retry_test.go @@ -7,6 +7,7 @@ import ( "github.com/stakater/Reloader/internal/pkg/config" "github.com/stakater/Reloader/internal/pkg/controller" "github.com/stakater/Reloader/internal/pkg/reload" + "github.com/stakater/Reloader/internal/pkg/testutil" "github.com/stakater/Reloader/internal/pkg/workload" appsv1 "k8s.io/api/apps/v1" batchv1 "k8s.io/api/batch/v1" @@ -27,7 +28,7 @@ func TestUpdateWorkloadWithRetry_WorkloadTypes(t *testing.T) { }{ { name: "Deployment", - object: testDeployment("test-deployment", "default", nil), + object: testutil.NewDeployment("test-deployment", "default", nil), workload: func(o runtime.Object) workload.WorkloadAccessor { return workload.NewDeploymentWorkload(o.(*appsv1.Deployment)) }, @@ -44,7 +45,7 @@ func TestUpdateWorkloadWithRetry_WorkloadTypes(t *testing.T) { }, { name: "DaemonSet", - object: testDaemonSet("test-daemonset", "default", nil), + object: testutil.NewDaemonSet("test-daemonset", "default", nil), workload: func(o runtime.Object) workload.WorkloadAccessor { return workload.NewDaemonSetWorkload(o.(*appsv1.DaemonSet)) }, @@ -61,7 +62,7 @@ func TestUpdateWorkloadWithRetry_WorkloadTypes(t *testing.T) { }, { name: "StatefulSet", - object: testStatefulSet("test-statefulset", "default", nil), + object: testutil.NewStatefulSet("test-statefulset", "default", nil), workload: func(o runtime.Object) workload.WorkloadAccessor { return workload.NewStatefulSetWorkload(o.(*appsv1.StatefulSet)) }, @@ -78,7 +79,7 @@ func TestUpdateWorkloadWithRetry_WorkloadTypes(t *testing.T) { }, { name: "Job", - object: testJob("test-job", "default"), + object: testutil.NewJob("test-job", "default"), workload: func(o runtime.Object) workload.WorkloadAccessor { return workload.NewJobWorkload(o.(*batchv1.Job)) }, @@ -95,7 +96,7 @@ func TestUpdateWorkloadWithRetry_WorkloadTypes(t *testing.T) { }, { name: "CronJob", - object: testCronJob("test-cronjob", "default"), + object: testutil.NewCronJob("test-cronjob", "default"), workload: func(o runtime.Object) workload.WorkloadAccessor { return workload.NewCronJobWorkload(o.(*batchv1.CronJob)) }, @@ -122,7 +123,7 @@ func TestUpdateWorkloadWithRetry_WorkloadTypes(t *testing.T) { reloadService := reload.NewService(cfg) fakeClient := fake.NewClientBuilder(). - WithScheme(testScheme()). + WithScheme(testutil.NewScheme()). WithRuntimeObjects(tt.object). Build() @@ -201,9 +202,9 @@ func TestUpdateWorkloadWithRetry_Strategies(t *testing.T) { cfg.ReloadStrategy = tt.strategy reloadService := reload.NewService(cfg) - deployment := testDeployment("test-deployment", "default", nil) + deployment := testutil.NewDeployment("test-deployment", "default", nil) fakeClient := fake.NewClientBuilder(). - WithScheme(testScheme()). + WithScheme(testutil.NewScheme()). WithObjects(deployment). Build() @@ -245,7 +246,7 @@ func TestUpdateWorkloadWithRetry_NoUpdate(t *testing.T) { cfg := config.NewDefault() reloadService := reload.NewService(cfg) - deployment := testDeployment("test-deployment", "default", nil) + deployment := testutil.NewDeployment("test-deployment", "default", nil) deployment.Spec.Template.Spec.Containers[0].Env = []corev1.EnvVar{ { Name: "STAKATER_TEST_CM_CONFIGMAP", @@ -254,7 +255,7 @@ func TestUpdateWorkloadWithRetry_NoUpdate(t *testing.T) { } fakeClient := fake.NewClientBuilder(). - WithScheme(testScheme()). + WithScheme(testutil.NewScheme()). WithObjects(deployment). Build() diff --git a/internal/pkg/controller/secret_reconciler_test.go b/internal/pkg/controller/secret_reconciler_test.go index 11a879b4..f55e84a8 100644 --- a/internal/pkg/controller/secret_reconciler_test.go +++ b/internal/pkg/controller/secret_reconciler_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/stakater/Reloader/internal/pkg/config" + "github.com/stakater/Reloader/internal/pkg/testutil" ) func TestSecretReconciler_NotFound(t *testing.T) { @@ -16,7 +17,7 @@ func TestSecretReconciler_NotFound_ReloadOnDelete(t *testing.T) { cfg := config.NewDefault() cfg.ReloadOnDelete = true - deployment := testDeployment("test-deployment", "default", map[string]string{ + deployment := testutil.NewDeployment("test-deployment", "default", map[string]string{ cfg.Annotations.SecretReload: "deleted-secret", }) reconciler := newSecretReconciler(t, cfg, deployment) @@ -27,7 +28,7 @@ func TestSecretReconciler_IgnoredNamespace(t *testing.T) { cfg := config.NewDefault() cfg.IgnoredNamespaces = []string{"kube-system"} - secret := testSecret("test-secret", "kube-system") + secret := testutil.NewSecret("test-secret", "kube-system") reconciler := newSecretReconciler(t, cfg, secret) assertReconcileSuccess(t, reconciler, reconcileRequest("test-secret", "kube-system")) } @@ -35,8 +36,8 @@ func TestSecretReconciler_IgnoredNamespace(t *testing.T) { func TestSecretReconciler_NoMatchingWorkloads(t *testing.T) { cfg := config.NewDefault() - secret := testSecret("test-secret", "default") - deployment := testDeployment("test-deployment", "default", nil) + secret := testutil.NewSecret("test-secret", "default") + deployment := testutil.NewDeployment("test-deployment", "default", nil) reconciler := newSecretReconciler(t, cfg, secret, deployment) assertReconcileSuccess(t, reconciler, reconcileRequest("test-secret", "default")) } @@ -45,8 +46,8 @@ func TestSecretReconciler_MatchingDeployment_AutoAnnotation(t *testing.T) { cfg := config.NewDefault() cfg.AutoReloadAll = true - secret := testSecret("test-secret", "default") - deployment := testDeploymentWithEnvFrom("test-deployment", "default", "", "test-secret") + secret := testutil.NewSecret("test-secret", "default") + deployment := testutil.NewDeploymentWithEnvFrom("test-deployment", "default", "", "test-secret") reconciler := newSecretReconciler(t, cfg, secret, deployment) assertReconcileSuccess(t, reconciler, reconcileRequest("test-secret", "default")) } @@ -54,8 +55,8 @@ func TestSecretReconciler_MatchingDeployment_AutoAnnotation(t *testing.T) { func TestSecretReconciler_MatchingDeployment_ExplicitAnnotation(t *testing.T) { cfg := config.NewDefault() - secret := testSecret("test-secret", "default") - deployment := testDeployment("test-deployment", "default", map[string]string{ + secret := testutil.NewSecret("test-secret", "default") + deployment := testutil.NewDeployment("test-deployment", "default", map[string]string{ cfg.Annotations.SecretReload: "test-secret", }) reconciler := newSecretReconciler(t, cfg, secret, deployment) @@ -65,8 +66,8 @@ func TestSecretReconciler_MatchingDeployment_ExplicitAnnotation(t *testing.T) { func TestSecretReconciler_WorkloadInDifferentNamespace(t *testing.T) { cfg := config.NewDefault() - secret := testSecret("test-secret", "namespace-a") - deployment := testDeployment("test-deployment", "namespace-b", map[string]string{ + secret := testutil.NewSecret("test-secret", "namespace-a") + deployment := testutil.NewDeployment("test-deployment", "namespace-b", map[string]string{ cfg.Annotations.SecretReload: "test-secret", }) reconciler := newSecretReconciler(t, cfg, secret, deployment) @@ -77,8 +78,8 @@ func TestSecretReconciler_IgnoredWorkloadType(t *testing.T) { cfg := config.NewDefault() cfg.IgnoredWorkloads = []string{"deployment"} - secret := testSecret("test-secret", "default") - deployment := testDeployment("test-deployment", "default", map[string]string{ + secret := testutil.NewSecret("test-secret", "default") + deployment := testutil.NewDeployment("test-deployment", "default", map[string]string{ cfg.Annotations.SecretReload: "test-secret", }) reconciler := newSecretReconciler(t, cfg, secret, deployment) @@ -88,8 +89,8 @@ func TestSecretReconciler_IgnoredWorkloadType(t *testing.T) { func TestSecretReconciler_DaemonSet(t *testing.T) { cfg := config.NewDefault() - secret := testSecret("test-secret", "default") - daemonset := testDaemonSet("test-daemonset", "default", map[string]string{ + secret := testutil.NewSecret("test-secret", "default") + daemonset := testutil.NewDaemonSet("test-daemonset", "default", map[string]string{ cfg.Annotations.SecretReload: "test-secret", }) reconciler := newSecretReconciler(t, cfg, secret, daemonset) @@ -99,8 +100,8 @@ func TestSecretReconciler_DaemonSet(t *testing.T) { func TestSecretReconciler_StatefulSet(t *testing.T) { cfg := config.NewDefault() - secret := testSecret("test-secret", "default") - statefulset := testStatefulSet("test-statefulset", "default", map[string]string{ + secret := testutil.NewSecret("test-secret", "default") + statefulset := testutil.NewStatefulSet("test-statefulset", "default", map[string]string{ cfg.Annotations.SecretReload: "test-secret", }) reconciler := newSecretReconciler(t, cfg, secret, statefulset) @@ -110,14 +111,14 @@ func TestSecretReconciler_StatefulSet(t *testing.T) { func TestSecretReconciler_MultipleWorkloads(t *testing.T) { cfg := config.NewDefault() - secret := testSecret("shared-secret", "default") - deployment1 := testDeployment("deployment-1", "default", map[string]string{ + secret := testutil.NewSecret("shared-secret", "default") + deployment1 := testutil.NewDeployment("deployment-1", "default", map[string]string{ cfg.Annotations.SecretReload: "shared-secret", }) - deployment2 := testDeployment("deployment-2", "default", map[string]string{ + deployment2 := testutil.NewDeployment("deployment-2", "default", map[string]string{ cfg.Annotations.SecretReload: "shared-secret", }) - daemonset := testDaemonSet("daemonset-1", "default", map[string]string{ + daemonset := testutil.NewDaemonSet("daemonset-1", "default", map[string]string{ cfg.Annotations.SecretReload: "shared-secret", }) @@ -129,8 +130,8 @@ func TestSecretReconciler_VolumeMount(t *testing.T) { cfg := config.NewDefault() cfg.AutoReloadAll = true - secret := testSecret("volume-secret", "default") - deployment := testDeploymentWithVolume("test-deployment", "default", "", "volume-secret") + secret := testutil.NewSecret("volume-secret", "default") + deployment := testutil.NewDeploymentWithVolume("test-deployment", "default", "", "volume-secret") reconciler := newSecretReconciler(t, cfg, secret, deployment) assertReconcileSuccess(t, reconciler, reconcileRequest("volume-secret", "default")) } @@ -139,8 +140,8 @@ func TestSecretReconciler_ProjectedVolume(t *testing.T) { cfg := config.NewDefault() cfg.AutoReloadAll = true - secret := testSecret("projected-secret", "default") - deployment := testDeploymentWithProjectedVolume("test-deployment", "default", "", "projected-secret") + secret := testutil.NewSecret("projected-secret", "default") + deployment := testutil.NewDeploymentWithProjectedVolume("test-deployment", "default", "", "projected-secret") reconciler := newSecretReconciler(t, cfg, secret, deployment) assertReconcileSuccess(t, reconciler, reconcileRequest("projected-secret", "default")) } @@ -148,10 +149,10 @@ func TestSecretReconciler_ProjectedVolume(t *testing.T) { func TestSecretReconciler_SearchAnnotation(t *testing.T) { cfg := config.NewDefault() - secret := testSecretWithAnnotations("test-secret", "default", map[string]string{ + secret := testutil.NewSecretWithAnnotations("test-secret", "default", map[string]string{ cfg.Annotations.Match: "true", }) - deployment := testDeployment("test-deployment", "default", map[string]string{ + deployment := testutil.NewDeployment("test-deployment", "default", map[string]string{ cfg.Annotations.Search: "true", }) reconciler := newSecretReconciler(t, cfg, secret, deployment) @@ -163,10 +164,10 @@ func TestSecretReconciler_ServiceAccountTokenIgnored(t *testing.T) { cfg.AutoReloadAll = true // Service account tokens should be ignored - secret := testSecret("sa-token", "default") + secret := testutil.NewSecret("sa-token", "default") secret.Type = "kubernetes.io/service-account-token" - deployment := testDeploymentWithEnvFrom("test-deployment", "default", "", "sa-token") + deployment := testutil.NewDeploymentWithEnvFrom("test-deployment", "default", "", "sa-token") reconciler := newSecretReconciler(t, cfg, secret, deployment) assertReconcileSuccess(t, reconciler, reconcileRequest("sa-token", "default")) } diff --git a/internal/pkg/controller/test_helpers_test.go b/internal/pkg/controller/test_helpers_test.go index b3315232..317039ea 100644 --- a/internal/pkg/controller/test_helpers_test.go +++ b/internal/pkg/controller/test_helpers_test.go @@ -11,32 +11,21 @@ import ( "github.com/stakater/Reloader/internal/pkg/events" "github.com/stakater/Reloader/internal/pkg/metrics" "github.com/stakater/Reloader/internal/pkg/reload" + "github.com/stakater/Reloader/internal/pkg/testutil" "github.com/stakater/Reloader/internal/pkg/webhook" "github.com/stakater/Reloader/internal/pkg/workload" - appsv1 "k8s.io/api/apps/v1" - batchv1 "k8s.io/api/batch/v1" corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client/fake" ) -// testScheme is a shared scheme for all controller tests. -func testScheme() *runtime.Scheme { - scheme := runtime.NewScheme() - _ = corev1.AddToScheme(scheme) - _ = appsv1.AddToScheme(scheme) - _ = batchv1.AddToScheme(scheme) - return scheme -} - // newConfigMapReconciler creates a ConfigMapReconciler for testing. func newConfigMapReconciler(t *testing.T, cfg *config.Config, objects ...runtime.Object) *controller.ConfigMapReconciler { t.Helper() fakeClient := fake.NewClientBuilder(). - WithScheme(testScheme()). + WithScheme(testutil.NewScheme()). WithRuntimeObjects(objects...). Build() @@ -59,7 +48,7 @@ func newConfigMapReconciler(t *testing.T, cfg *config.Config, objects ...runtime func newSecretReconciler(t *testing.T, cfg *config.Config, objects ...runtime.Object) *controller.SecretReconciler { t.Helper() fakeClient := fake.NewClientBuilder(). - WithScheme(testScheme()). + WithScheme(testutil.NewScheme()). WithRuntimeObjects(objects...). Build() @@ -78,260 +67,6 @@ func newSecretReconciler(t *testing.T, cfg *config.Config, objects ...runtime.Ob } } -// testConfigMap creates a ConfigMap for testing. -func testConfigMap(name, namespace string) *corev1.ConfigMap { - return &corev1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - }, - Data: map[string]string{"key": "value"}, - } -} - -// testConfigMapWithAnnotations creates a ConfigMap with annotations. -func testConfigMapWithAnnotations(name, namespace string, annotations map[string]string) *corev1.ConfigMap { - cm := testConfigMap(name, namespace) - cm.Annotations = annotations - return cm -} - -// testSecret creates a Secret for testing. -func testSecret(name, namespace string) *corev1.Secret { - return &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - }, - Data: map[string][]byte{"key": []byte("value")}, - } -} - -// testSecretWithAnnotations creates a Secret with annotations. -func testSecretWithAnnotations(name, namespace string, annotations map[string]string) *corev1.Secret { - secret := testSecret(name, namespace) - secret.Annotations = annotations - return secret -} - -// testDeployment creates a minimal Deployment for testing. -func testDeployment(name, namespace string, annotations map[string]string) *appsv1.Deployment { - return &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - Annotations: annotations, - }, - Spec: appsv1.DeploymentSpec{ - Selector: &metav1.LabelSelector{ - MatchLabels: map[string]string{"app": name}, - }, - Template: corev1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: map[string]string{"app": name}, - }, - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Name: "main", - Image: "nginx", - }, - }, - }, - }, - }, - } -} - -// testDeploymentWithEnvFrom creates a Deployment with EnvFrom referencing a ConfigMap or Secret. -func testDeploymentWithEnvFrom(name, namespace string, configMapName, secretName string) *appsv1.Deployment { - d := testDeployment(name, namespace, nil) - if configMapName != "" { - d.Spec.Template.Spec.Containers[0].EnvFrom = append( - d.Spec.Template.Spec.Containers[0].EnvFrom, - corev1.EnvFromSource{ - ConfigMapRef: &corev1.ConfigMapEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{Name: configMapName}, - }, - }, - ) - } - if secretName != "" { - d.Spec.Template.Spec.Containers[0].EnvFrom = append( - d.Spec.Template.Spec.Containers[0].EnvFrom, - corev1.EnvFromSource{ - SecretRef: &corev1.SecretEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{Name: secretName}, - }, - }, - ) - } - return d -} - -// testDeploymentWithVolume creates a Deployment with a volume from ConfigMap or Secret. -func testDeploymentWithVolume(name, namespace string, configMapName, secretName string) *appsv1.Deployment { - d := testDeployment(name, namespace, nil) - d.Spec.Template.Spec.Containers[0].VolumeMounts = []corev1.VolumeMount{ - { - Name: "config", - MountPath: "/etc/config", - }, - } - - if configMapName != "" { - d.Spec.Template.Spec.Volumes = []corev1.Volume{ - { - Name: "config", - VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ - LocalObjectReference: corev1.LocalObjectReference{Name: configMapName}, - }, - }, - }, - } - } - if secretName != "" { - d.Spec.Template.Spec.Volumes = []corev1.Volume{ - { - Name: "config", - VolumeSource: corev1.VolumeSource{ - Secret: &corev1.SecretVolumeSource{ - SecretName: secretName, - }, - }, - }, - } - } - return d -} - -// testDeploymentWithProjectedVolume creates a Deployment with a projected volume. -func testDeploymentWithProjectedVolume(name, namespace string, configMapName, secretName string) *appsv1.Deployment { - d := testDeployment(name, namespace, nil) - d.Spec.Template.Spec.Containers[0].VolumeMounts = []corev1.VolumeMount{ - { - Name: "config", - MountPath: "/etc/config", - }, - } - - var sources []corev1.VolumeProjection - if configMapName != "" { - sources = append( - sources, corev1.VolumeProjection{ - ConfigMap: &corev1.ConfigMapProjection{ - LocalObjectReference: corev1.LocalObjectReference{Name: configMapName}, - }, - }, - ) - } - if secretName != "" { - sources = append( - sources, corev1.VolumeProjection{ - Secret: &corev1.SecretProjection{ - LocalObjectReference: corev1.LocalObjectReference{Name: secretName}, - }, - }, - ) - } - - d.Spec.Template.Spec.Volumes = []corev1.Volume{ - { - Name: "config", - VolumeSource: corev1.VolumeSource{ - Projected: &corev1.ProjectedVolumeSource{Sources: sources}, - }, - }, - } - return d -} - -// testDaemonSet creates a minimal DaemonSet for testing. -func testDaemonSet(name, namespace string, annotations map[string]string) *appsv1.DaemonSet { - return &appsv1.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - Annotations: annotations, - }, - Spec: appsv1.DaemonSetSpec{ - Selector: &metav1.LabelSelector{ - MatchLabels: map[string]string{"app": name}, - }, - Template: corev1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: map[string]string{"app": name}, - }, - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Name: "main", - Image: "nginx", - }, - }, - }, - }, - }, - } -} - -// testStatefulSet creates a minimal StatefulSet for testing. -func testStatefulSet(name, namespace string, annotations map[string]string) *appsv1.StatefulSet { - return &appsv1.StatefulSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - Annotations: annotations, - }, - Spec: appsv1.StatefulSetSpec{ - Selector: &metav1.LabelSelector{ - MatchLabels: map[string]string{"app": name}, - }, - Template: corev1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: map[string]string{"app": name}, - }, - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Name: "main", - Image: "nginx", - }, - }, - }, - }, - }, - } -} - -// reconcileRequest creates a ctrl.Request for the given name and namespace. -func reconcileRequest(name, namespace string) ctrl.Request { - return ctrl.Request{ - NamespacedName: types.NamespacedName{ - Name: name, - Namespace: namespace, - }, - } -} - -// namespaceRequest creates a ctrl.Request for a namespace (no namespace field needed). -func namespaceRequest(name string) ctrl.Request { - return ctrl.Request{ - NamespacedName: types.NamespacedName{Name: name}, - } -} - -// testNamespace creates a Namespace with optional labels. -func testNamespace(name string, labels map[string]string) *corev1.Namespace { - return &corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Labels: labels, - }, - } -} - // newNamespaceReconciler creates a NamespaceReconciler for testing. func newNamespaceReconciler(t *testing.T, cfg *config.Config, cache *controller.NamespaceCache, objects ...runtime.Object) *controller.NamespaceReconciler { t.Helper() @@ -351,6 +86,23 @@ func newNamespaceReconciler(t *testing.T, cfg *config.Config, cache *controller. } } +// reconcileRequest creates a ctrl.Request for the given name and namespace. +func reconcileRequest(name, namespace string) ctrl.Request { + return ctrl.Request{ + NamespacedName: types.NamespacedName{ + Name: name, + Namespace: namespace, + }, + } +} + +// namespaceRequest creates a ctrl.Request for a namespace (no namespace field needed). +func namespaceRequest(name string) ctrl.Request { + return ctrl.Request{ + NamespacedName: types.NamespacedName{Name: name}, + } +} + // assertReconcileSuccess runs reconcile and asserts no error and no requeue. func assertReconcileSuccess(t *testing.T, reconciler interface { Reconcile(context.Context, ctrl.Request) (ctrl.Result, error) @@ -364,55 +116,3 @@ func assertReconcileSuccess(t *testing.T, reconciler interface { t.Error("Should not requeue") } } - -// testJob creates a minimal Job for testing. -func testJob(name, namespace string) *batchv1.Job { - return &batchv1.Job{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - }, - Spec: batchv1.JobSpec{ - Template: corev1.PodTemplateSpec{ - Spec: corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyNever, - Containers: []corev1.Container{ - { - Name: "main", - Image: "busybox", - }, - }, - }, - }, - }, - } -} - -// testCronJob creates a minimal CronJob for testing. -func testCronJob(name, namespace string) *batchv1.CronJob { - return &batchv1.CronJob{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - UID: "test-uid", - }, - Spec: batchv1.CronJobSpec{ - Schedule: "*/5 * * * *", - JobTemplate: batchv1.JobTemplateSpec{ - Spec: batchv1.JobSpec{ - Template: corev1.PodTemplateSpec{ - Spec: corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyNever, - Containers: []corev1.Container{ - { - Name: "main", - Image: "busybox", - }, - }, - }, - }, - }, - }, - }, - } -} diff --git a/internal/pkg/reload/service_test.go b/internal/pkg/reload/service_test.go index cd94873f..dae653f7 100644 --- a/internal/pkg/reload/service_test.go +++ b/internal/pkg/reload/service_test.go @@ -5,8 +5,8 @@ import ( "testing" "github.com/stakater/Reloader/internal/pkg/config" + "github.com/stakater/Reloader/internal/pkg/testutil" "github.com/stakater/Reloader/internal/pkg/workload" - appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -16,7 +16,7 @@ func TestService_ProcessConfigMap_AutoReload(t *testing.T) { svc := NewService(cfg) // Create a deployment with auto annotation that uses the configmap - deploy := createTestDeployment( + deploy := testutil.NewDeployment( "test-deploy", "default", map[string]string{ "reloader.stakater.com/auto": "true", }, @@ -76,7 +76,7 @@ func TestService_ProcessConfigMap_ExplicitAnnotation(t *testing.T) { cfg := config.NewDefault() svc := NewService(cfg) - deploy := createTestDeployment( + deploy := testutil.NewDeployment( "test-deploy", "default", map[string]string{ "configmap.reloader.stakater.com/reload": "test-cm", }, @@ -121,7 +121,7 @@ func TestService_ProcessConfigMap_IgnoredResource(t *testing.T) { svc := NewService(cfg) // Create a deployment with auto annotation - deploy := createTestDeployment( + deploy := testutil.NewDeployment( "test-deploy", "default", map[string]string{ "reloader.stakater.com/auto": "true", }, @@ -177,7 +177,7 @@ func TestService_ProcessSecret_AutoReload(t *testing.T) { svc := NewService(cfg) // Create a deployment with auto annotation that uses the secret - deploy := createTestDeployment( + deploy := testutil.NewDeployment( "test-deploy", "default", map[string]string{ "reloader.stakater.com/auto": "true", }, @@ -233,7 +233,7 @@ func TestService_ProcessConfigMap_DeleteEvent(t *testing.T) { svc := NewService(cfg) // Create a deployment with explicit configmap annotation - deploy := createTestDeployment( + deploy := testutil.NewDeployment( "test-deploy", "default", map[string]string{ "configmap.reloader.stakater.com/reload": "test-cm", }, @@ -276,7 +276,7 @@ func TestService_ProcessConfigMap_DeleteEventDisabled(t *testing.T) { cfg.ReloadOnDelete = false // Disabled by default svc := NewService(cfg) - deploy := createTestDeployment( + deploy := testutil.NewDeployment( "test-deploy", "default", map[string]string{ "configmap.reloader.stakater.com/reload": "test-cm", }, @@ -311,7 +311,7 @@ func TestService_ApplyReload_EnvVarStrategy(t *testing.T) { cfg.ReloadStrategy = config.ReloadStrategyEnvVars svc := NewService(cfg) - deploy := createTestDeployment("test-deploy", "default", nil) + deploy := testutil.NewDeployment("test-deploy", "default", nil) accessor := workload.NewDeploymentWorkload(deploy) ctx := context.Background() @@ -355,7 +355,7 @@ func TestService_ApplyReload_AnnotationStrategy(t *testing.T) { cfg.ReloadStrategy = config.ReloadStrategyAnnotations svc := NewService(cfg) - deploy := createTestDeployment("test-deploy", "default", nil) + deploy := testutil.NewDeployment("test-deploy", "default", nil) accessor := workload.NewDeploymentWorkload(deploy) ctx := context.Background() @@ -381,7 +381,7 @@ func TestService_ApplyReload_EnvVarDeletion(t *testing.T) { cfg.ReloadStrategy = config.ReloadStrategyEnvVars svc := NewService(cfg) - deploy := createTestDeployment("test-deploy", "default", nil) + deploy := testutil.NewDeployment("test-deploy", "default", nil) // Pre-add an env var deploy.Spec.Template.Spec.Containers[0].Env = []corev1.EnvVar{ {Name: "STAKATER_TEST_CM_CONFIGMAP", Value: "oldhash"}, @@ -427,7 +427,7 @@ func TestService_ApplyReload_NoChangeIfSameHash(t *testing.T) { cfg.ReloadStrategy = config.ReloadStrategyEnvVars svc := NewService(cfg) - deploy := createTestDeployment("test-deploy", "default", nil) + deploy := testutil.NewDeployment("test-deploy", "default", nil) // Pre-add env var with same hash deploy.Spec.Template.Spec.Containers[0].Env = []corev1.EnvVar{ {Name: "STAKATER_TEST_CM_CONFIGMAP", Value: "abc123hash"}, @@ -451,7 +451,7 @@ func TestService_ProcessConfigMap_MultipleWorkloads(t *testing.T) { svc := NewService(cfg) // Create multiple workloads - deploy1 := createTestDeployment( + deploy1 := testutil.NewDeployment( "deploy1", "default", map[string]string{ "reloader.stakater.com/auto": "true", }, @@ -469,7 +469,7 @@ func TestService_ProcessConfigMap_MultipleWorkloads(t *testing.T) { }, } - deploy2 := createTestDeployment( + deploy2 := testutil.NewDeployment( "deploy2", "default", map[string]string{ "reloader.stakater.com/auto": "true", }, @@ -488,7 +488,7 @@ func TestService_ProcessConfigMap_MultipleWorkloads(t *testing.T) { } // Deploy3 doesn't use the configmap - deploy3 := createTestDeployment( + deploy3 := testutil.NewDeployment( "deploy3", "default", map[string]string{ "reloader.stakater.com/auto": "true", }, @@ -538,7 +538,7 @@ func TestService_ProcessConfigMap_DifferentNamespaces(t *testing.T) { svc := NewService(cfg) // Create deployments in different namespaces - deploy1 := createTestDeployment( + deploy1 := testutil.NewDeployment( "deploy1", "namespace-a", map[string]string{ "reloader.stakater.com/auto": "true", }, @@ -556,7 +556,7 @@ func TestService_ProcessConfigMap_DifferentNamespaces(t *testing.T) { }, } - deploy2 := createTestDeployment( + deploy2 := testutil.NewDeployment( "deploy2", "namespace-b", map[string]string{ "reloader.stakater.com/auto": "true", }, @@ -1102,7 +1102,7 @@ func TestService_findTargetContainer_AutoReload(t *testing.T) { svc := NewService(cfg) // Test with autoReload=true and volume mount - deploy := createTestDeployment("test", "default", nil) + deploy := testutil.NewDeployment("test", "default", nil) deploy.Spec.Template.Spec.Volumes = []corev1.Volume{ { Name: "config-vol", @@ -1138,7 +1138,7 @@ func TestService_findTargetContainer_AutoReload_EnvRef(t *testing.T) { svc := NewService(cfg) // Test with autoReload=true and env ref (no volume) - deploy := createTestDeployment("test", "default", nil) + deploy := testutil.NewDeployment("test", "default", nil) deploy.Spec.Template.Spec.Containers = []corev1.Container{ { Name: "sidecar", @@ -1176,7 +1176,7 @@ func TestService_findTargetContainer_AutoReload_InitContainer(t *testing.T) { svc := NewService(cfg) // Test with autoReload=true where init container uses the volume - deploy := createTestDeployment("test", "default", nil) + deploy := testutil.NewDeployment("test", "default", nil) deploy.Spec.Template.Spec.Volumes = []corev1.Volume{ { Name: "config-vol", @@ -1219,7 +1219,7 @@ func TestService_findTargetContainer_AutoReload_InitContainerEnvRef(t *testing.T svc := NewService(cfg) // Test with autoReload=true where init container has env ref - deploy := createTestDeployment("test", "default", nil) + deploy := testutil.NewDeployment("test", "default", nil) deploy.Spec.Template.Spec.InitContainers = []corev1.Container{ { Name: "init", @@ -1259,7 +1259,7 @@ func TestService_findTargetContainer_NoContainers(t *testing.T) { cfg := config.NewDefault() svc := NewService(cfg) - deploy := createTestDeployment("test", "default", nil) + deploy := testutil.NewDeployment("test", "default", nil) deploy.Spec.Template.Spec.Containers = []corev1.Container{} accessor := workload.NewDeploymentWorkload(deploy) @@ -1273,7 +1273,7 @@ func TestService_findTargetContainer_NonAutoReload(t *testing.T) { cfg := config.NewDefault() svc := NewService(cfg) - deploy := createTestDeployment("test", "default", nil) + deploy := testutil.NewDeployment("test", "default", nil) deploy.Spec.Template.Spec.Containers = []corev1.Container{ {Name: "first", Image: "nginx"}, {Name: "second", Image: "busybox"}, @@ -1295,7 +1295,7 @@ func TestService_findTargetContainer_AutoReload_FallbackToFirst(t *testing.T) { svc := NewService(cfg) // autoReload=true but no matching volume or env ref - should fallback to first container - deploy := createTestDeployment("test", "default", nil) + deploy := testutil.NewDeployment("test", "default", nil) deploy.Spec.Template.Spec.Containers = []corev1.Container{ {Name: "first", Image: "nginx"}, {Name: "second", Image: "busybox"}, @@ -1315,7 +1315,7 @@ func TestService_ProcessNilChange(t *testing.T) { cfg := config.NewDefault() svc := NewService(cfg) - deploy := createTestDeployment("test", "default", nil) + deploy := testutil.NewDeployment("test", "default", nil) workloads := []workload.WorkloadAccessor{workload.NewDeploymentWorkload(deploy)} // Test with nil ConfigMap @@ -1335,7 +1335,7 @@ func TestService_ProcessCreateEventDisabled(t *testing.T) { cfg.ReloadOnCreate = false svc := NewService(cfg) - deploy := createTestDeployment( + deploy := testutil.NewDeployment( "test", "default", map[string]string{ "reloader.stakater.com/auto": "true", }, @@ -1357,35 +1357,3 @@ func TestService_ProcessCreateEventDisabled(t *testing.T) { t.Errorf("Expected nil decisions when create events disabled, got %v", decisions) } } - -// Helper function to create a test deployment -func createTestDeployment(name, namespace string, annotations map[string]string) *appsv1.Deployment { - replicas := int32(1) - return &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - Annotations: annotations, - }, - Spec: appsv1.DeploymentSpec{ - Replicas: &replicas, - Selector: &metav1.LabelSelector{ - MatchLabels: map[string]string{"app": name}, - }, - Template: corev1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: map[string]string{"app": name}, - Annotations: map[string]string{}, - }, - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Name: "main", - Image: "nginx:latest", - }, - }, - }, - }, - }, - } -} diff --git a/internal/pkg/testutil/fixtures.go b/internal/pkg/testutil/fixtures.go new file mode 100644 index 00000000..1deb85a1 --- /dev/null +++ b/internal/pkg/testutil/fixtures.go @@ -0,0 +1,286 @@ +package testutil + +import ( + appsv1 "k8s.io/api/apps/v1" + batchv1 "k8s.io/api/batch/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +// NewScheme creates a scheme with common types for testing. +func NewScheme() *runtime.Scheme { + scheme := runtime.NewScheme() + _ = corev1.AddToScheme(scheme) + _ = appsv1.AddToScheme(scheme) + _ = batchv1.AddToScheme(scheme) + return scheme +} + +// NewDeployment creates a minimal Deployment for unit testing. +func NewDeployment(name, namespace string, annotations map[string]string) *appsv1.Deployment { + return &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + Annotations: annotations, + }, + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": name}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{"app": name}, + Annotations: map[string]string{}, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{{ + Name: "main", + Image: "nginx", + }}, + }, + }, + }, + } +} + +// NewDeploymentWithEnvFrom creates a Deployment with EnvFrom referencing a ConfigMap or Secret. +func NewDeploymentWithEnvFrom(name, namespace string, configMapName, secretName string) *appsv1.Deployment { + d := NewDeployment(name, namespace, nil) + if configMapName != "" { + d.Spec.Template.Spec.Containers[0].EnvFrom = append( + d.Spec.Template.Spec.Containers[0].EnvFrom, + corev1.EnvFromSource{ + ConfigMapRef: &corev1.ConfigMapEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{Name: configMapName}, + }, + }, + ) + } + if secretName != "" { + d.Spec.Template.Spec.Containers[0].EnvFrom = append( + d.Spec.Template.Spec.Containers[0].EnvFrom, + corev1.EnvFromSource{ + SecretRef: &corev1.SecretEnvSource{ + LocalObjectReference: corev1.LocalObjectReference{Name: secretName}, + }, + }, + ) + } + return d +} + +// NewDeploymentWithVolume creates a Deployment with a volume from ConfigMap or Secret. +func NewDeploymentWithVolume(name, namespace string, configMapName, secretName string) *appsv1.Deployment { + d := NewDeployment(name, namespace, nil) + d.Spec.Template.Spec.Containers[0].VolumeMounts = []corev1.VolumeMount{{ + Name: "config", + MountPath: "/etc/config", + }} + + if configMapName != "" { + d.Spec.Template.Spec.Volumes = []corev1.Volume{{ + Name: "config", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{Name: configMapName}, + }, + }, + }} + } + if secretName != "" { + d.Spec.Template.Spec.Volumes = []corev1.Volume{{ + Name: "config", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: secretName, + }, + }, + }} + } + return d +} + +// NewDeploymentWithProjectedVolume creates a Deployment with a projected volume. +func NewDeploymentWithProjectedVolume(name, namespace string, configMapName, secretName string) *appsv1.Deployment { + d := NewDeployment(name, namespace, nil) + d.Spec.Template.Spec.Containers[0].VolumeMounts = []corev1.VolumeMount{{ + Name: "config", + MountPath: "/etc/config", + }} + + sources := []corev1.VolumeProjection{} + if configMapName != "" { + sources = append(sources, corev1.VolumeProjection{ + ConfigMap: &corev1.ConfigMapProjection{ + LocalObjectReference: corev1.LocalObjectReference{Name: configMapName}, + }, + }) + } + if secretName != "" { + sources = append(sources, corev1.VolumeProjection{ + Secret: &corev1.SecretProjection{ + LocalObjectReference: corev1.LocalObjectReference{Name: secretName}, + }, + }) + } + + d.Spec.Template.Spec.Volumes = []corev1.Volume{{ + Name: "config", + VolumeSource: corev1.VolumeSource{ + Projected: &corev1.ProjectedVolumeSource{Sources: sources}, + }, + }} + return d +} + +// NewDaemonSet creates a minimal DaemonSet for unit testing. +func NewDaemonSet(name, namespace string, annotations map[string]string) *appsv1.DaemonSet { + return &appsv1.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + Annotations: annotations, + }, + Spec: appsv1.DaemonSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": name}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{"app": name}, + Annotations: map[string]string{}, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{{ + Name: "main", + Image: "nginx", + }}, + }, + }, + }, + } +} + +// NewStatefulSet creates a minimal StatefulSet for unit testing. +func NewStatefulSet(name, namespace string, annotations map[string]string) *appsv1.StatefulSet { + return &appsv1.StatefulSet{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + Annotations: annotations, + }, + Spec: appsv1.StatefulSetSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": name}, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{"app": name}, + Annotations: map[string]string{}, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{{ + Name: "main", + Image: "nginx", + }}, + }, + }, + }, + } +} + +// NewJob creates a minimal Job for unit testing. +func NewJob(name, namespace string) *batchv1.Job { + return &batchv1.Job{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Spec: batchv1.JobSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + RestartPolicy: corev1.RestartPolicyNever, + Containers: []corev1.Container{{ + Name: "main", + Image: "busybox", + }}, + }, + }, + }, + } +} + +// NewCronJob creates a minimal CronJob for unit testing. +func NewCronJob(name, namespace string) *batchv1.CronJob { + return &batchv1.CronJob{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + UID: "test-uid", + }, + Spec: batchv1.CronJobSpec{ + Schedule: "*/5 * * * *", + JobTemplate: batchv1.JobTemplateSpec{ + Spec: batchv1.JobSpec{ + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + RestartPolicy: corev1.RestartPolicyNever, + Containers: []corev1.Container{{ + Name: "main", + Image: "busybox", + }}, + }, + }, + }, + }, + }, + } +} + +// NewConfigMap creates a ConfigMap for unit testing. +func NewConfigMap(name, namespace string) *corev1.ConfigMap { + return &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Data: map[string]string{"key": "value"}, + } +} + +// NewConfigMapWithAnnotations creates a ConfigMap with annotations. +func NewConfigMapWithAnnotations(name, namespace string, annotations map[string]string) *corev1.ConfigMap { + cm := NewConfigMap(name, namespace) + cm.Annotations = annotations + return cm +} + +// NewSecret creates a Secret for unit testing. +func NewSecret(name, namespace string) *corev1.Secret { + return &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Namespace: namespace, + }, + Data: map[string][]byte{"key": []byte("value")}, + } +} + +// NewSecretWithAnnotations creates a Secret with annotations. +func NewSecretWithAnnotations(name, namespace string, annotations map[string]string) *corev1.Secret { + secret := NewSecret(name, namespace) + secret.Annotations = annotations + return secret +} + +// NewNamespace creates a Namespace with optional labels. +func NewNamespace(name string, labels map[string]string) *corev1.Namespace { + return &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Labels: labels, + }, + } +} diff --git a/internal/pkg/testutil/testutil.go b/internal/pkg/testutil/testutil.go index 9dcde17e..b7f7e0dd 100644 --- a/internal/pkg/testutil/testutil.go +++ b/internal/pkg/testutil/testutil.go @@ -134,56 +134,16 @@ func DeleteSecret(client kubernetes.Interface, namespace, name string) error { // CreateDeployment creates a Deployment that references a ConfigMap/Secret. func CreateDeployment(client kubernetes.Interface, name, namespace string, useConfigMap bool, annotations map[string]string) (*appsv1.Deployment, error) { - replicas := int32(1) - deployment := &appsv1.Deployment{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - Annotations: annotations, - }, - Spec: appsv1.DeploymentSpec{ - Replicas: &replicas, - Selector: &metav1.LabelSelector{ - MatchLabels: map[string]string{"app": name}, - }, - Template: corev1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: map[string]string{"app": name}, - }, - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Name: "main", - Image: "busybox:1.36", - Command: []string{"sh", "-c", "while true; do sleep 3600; done"}, - }, - }, - }, - }, - }, - } - + var deployment *appsv1.Deployment if useConfigMap { - deployment.Spec.Template.Spec.Containers[0].EnvFrom = []corev1.EnvFromSource{ - { - ConfigMapRef: &corev1.ConfigMapEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: name, - }, - }, - }, - } + deployment = NewDeploymentWithEnvFrom(name, namespace, name, "") } else { - deployment.Spec.Template.Spec.Containers[0].EnvFrom = []corev1.EnvFromSource{ - { - SecretRef: &corev1.SecretEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: name, - }, - }, - }, - } + deployment = NewDeploymentWithEnvFrom(name, namespace, "", name) } + deployment.Annotations = annotations + // Override image for integration tests + deployment.Spec.Template.Spec.Containers[0].Image = "busybox:1.36" + deployment.Spec.Template.Spec.Containers[0].Command = []string{"sh", "-c", "while true; do sleep 3600; done"} return client.AppsV1().Deployments(namespace).Create(context.Background(), deployment, metav1.CreateOptions{}) } @@ -195,40 +155,16 @@ func DeleteDeployment(client kubernetes.Interface, namespace, name string) error // CreateDaemonSet creates a DaemonSet that references a ConfigMap/Secret. func CreateDaemonSet(client kubernetes.Interface, name, namespace string, useConfigMap bool, annotations map[string]string) (*appsv1.DaemonSet, error) { - daemonset := &appsv1.DaemonSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - Annotations: annotations, - }, - Spec: appsv1.DaemonSetSpec{ - Selector: &metav1.LabelSelector{ - MatchLabels: map[string]string{"app": name}, - }, - Template: corev1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: map[string]string{"app": name}, - }, - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Name: "main", - Image: "busybox:1.36", - Command: []string{"sh", "-c", "while true; do sleep 3600; done"}, - }, - }, - }, - }, - }, - } + daemonset := NewDaemonSet(name, namespace, annotations) + // Override image for integration tests + daemonset.Spec.Template.Spec.Containers[0].Image = "busybox:1.36" + daemonset.Spec.Template.Spec.Containers[0].Command = []string{"sh", "-c", "while true; do sleep 3600; done"} if useConfigMap { daemonset.Spec.Template.Spec.Containers[0].EnvFrom = []corev1.EnvFromSource{ { ConfigMapRef: &corev1.ConfigMapEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: name, - }, + LocalObjectReference: corev1.LocalObjectReference{Name: name}, }, }, } @@ -236,9 +172,7 @@ func CreateDaemonSet(client kubernetes.Interface, name, namespace string, useCon daemonset.Spec.Template.Spec.Containers[0].EnvFrom = []corev1.EnvFromSource{ { SecretRef: &corev1.SecretEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: name, - }, + LocalObjectReference: corev1.LocalObjectReference{Name: name}, }, }, } @@ -254,43 +188,17 @@ func DeleteDaemonSet(client kubernetes.Interface, namespace, name string) error // CreateStatefulSet creates a StatefulSet that references a ConfigMap/Secret. func CreateStatefulSet(client kubernetes.Interface, name, namespace string, useConfigMap bool, annotations map[string]string) (*appsv1.StatefulSet, error) { - replicas := int32(1) - statefulset := &appsv1.StatefulSet{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - Annotations: annotations, - }, - Spec: appsv1.StatefulSetSpec{ - Replicas: &replicas, - Selector: &metav1.LabelSelector{ - MatchLabels: map[string]string{"app": name}, - }, - ServiceName: name, - Template: corev1.PodTemplateSpec{ - ObjectMeta: metav1.ObjectMeta{ - Labels: map[string]string{"app": name}, - }, - Spec: corev1.PodSpec{ - Containers: []corev1.Container{ - { - Name: "main", - Image: "busybox:1.36", - Command: []string{"sh", "-c", "while true; do sleep 3600; done"}, - }, - }, - }, - }, - }, - } + statefulset := NewStatefulSet(name, namespace, annotations) + statefulset.Spec.ServiceName = name + // Override image for integration tests + statefulset.Spec.Template.Spec.Containers[0].Image = "busybox:1.36" + statefulset.Spec.Template.Spec.Containers[0].Command = []string{"sh", "-c", "while true; do sleep 3600; done"} if useConfigMap { statefulset.Spec.Template.Spec.Containers[0].EnvFrom = []corev1.EnvFromSource{ { ConfigMapRef: &corev1.ConfigMapEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: name, - }, + LocalObjectReference: corev1.LocalObjectReference{Name: name}, }, }, } @@ -298,9 +206,7 @@ func CreateStatefulSet(client kubernetes.Interface, name, namespace string, useC statefulset.Spec.Template.Spec.Containers[0].EnvFrom = []corev1.EnvFromSource{ { SecretRef: &corev1.SecretEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: name, - }, + LocalObjectReference: corev1.LocalObjectReference{Name: name}, }, }, } @@ -316,40 +222,18 @@ func DeleteStatefulSet(client kubernetes.Interface, namespace, name string) erro // CreateCronJob creates a CronJob that references a ConfigMap/Secret. func CreateCronJob(client kubernetes.Interface, name, namespace string, useConfigMap bool, annotations map[string]string) (*batchv1.CronJob, error) { - cronjob := &batchv1.CronJob{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - Annotations: annotations, - }, - Spec: batchv1.CronJobSpec{ - Schedule: "*/5 * * * *", - JobTemplate: batchv1.JobTemplateSpec{ - Spec: batchv1.JobSpec{ - Template: corev1.PodTemplateSpec{ - Spec: corev1.PodSpec{ - RestartPolicy: corev1.RestartPolicyOnFailure, - Containers: []corev1.Container{ - { - Name: "main", - Image: "busybox:1.36", - Command: []string{"sh", "-c", "echo hello"}, - }, - }, - }, - }, - }, - }, - }, - } + cronjob := NewCronJob(name, namespace) + cronjob.Annotations = annotations + // Override image for integration tests + cronjob.Spec.JobTemplate.Spec.Template.Spec.Containers[0].Image = "busybox:1.36" + cronjob.Spec.JobTemplate.Spec.Template.Spec.Containers[0].Command = []string{"sh", "-c", "echo hello"} + cronjob.Spec.JobTemplate.Spec.Template.Spec.RestartPolicy = corev1.RestartPolicyOnFailure if useConfigMap { cronjob.Spec.JobTemplate.Spec.Template.Spec.Containers[0].EnvFrom = []corev1.EnvFromSource{ { ConfigMapRef: &corev1.ConfigMapEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: name, - }, + LocalObjectReference: corev1.LocalObjectReference{Name: name}, }, }, } @@ -357,9 +241,7 @@ func CreateCronJob(client kubernetes.Interface, name, namespace string, useConfi cronjob.Spec.JobTemplate.Spec.Template.Spec.Containers[0].EnvFrom = []corev1.EnvFromSource{ { SecretRef: &corev1.SecretEnvSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: name, - }, + LocalObjectReference: corev1.LocalObjectReference{Name: name}, }, }, } diff --git a/internal/pkg/workload/registry_test.go b/internal/pkg/workload/registry_test.go index 4ebfb870..e681438d 100644 --- a/internal/pkg/workload/registry_test.go +++ b/internal/pkg/workload/registry_test.go @@ -18,14 +18,12 @@ func TestNewRegistry_WithoutArgoRollouts(t *testing.T) { t.Errorf("SupportedKinds() = %d kinds, want 5", len(kinds)) } - // Should not include ArgoRollout for _, k := range kinds { if k == KindArgoRollout { t.Error("SupportedKinds() should not include ArgoRollout when disabled") } } - // ListerFor should return nil for ArgoRollout if r.ListerFor(KindArgoRollout) != nil { t.Error("ListerFor(KindArgoRollout) should return nil when disabled") } @@ -39,7 +37,6 @@ func TestNewRegistry_WithArgoRollouts(t *testing.T) { t.Errorf("SupportedKinds() = %d kinds, want 6", len(kinds)) } - // Should include ArgoRollout found := false for _, k := range kinds { if k == KindArgoRollout { @@ -51,7 +48,6 @@ func TestNewRegistry_WithArgoRollouts(t *testing.T) { t.Error("SupportedKinds() should include ArgoRollout when enabled") } - // ListerFor should return a function for ArgoRollout if r.ListerFor(KindArgoRollout) == nil { t.Error("ListerFor(KindArgoRollout) should return a function when enabled") } diff --git a/test/e2e/e2e_test.go b/test/e2e/e2e_test.go index 32106d49..6d3dcc4c 100644 --- a/test/e2e/e2e_test.go +++ b/test/e2e/e2e_test.go @@ -1,13 +1,4 @@ // Package e2e contains end-to-end tests for Reloader. -// These tests run against a real Kubernetes cluster (or envtest). -// -// To run these tests against a real cluster: -// -// KUBECONFIG=~/.kube/config go test -v ./test/e2e/... -count=1 -// -// To skip these tests when running unit tests: -// -// go test -v ./... -short package e2e import ( @@ -237,7 +228,6 @@ func TestMain(m *testing.M) { os.Exit(0) } - // Set up zerolog as the controller-runtime logger zl := zerolog.New(zerolog.ConsoleWriter{Out: os.Stderr, TimeFormat: time.RFC3339}). Level(zerolog.WarnLevel). With(). @@ -301,9 +291,11 @@ func TestConfigMapUpdate(t *testing.T) { defer f.cleanup() f.createConfigMap(f.name, "initial-data") - f.createDeployment(f.name, true, map[string]string{ - cfg.Annotations.ConfigmapReload: f.name, - }) + f.createDeployment( + f.name, true, map[string]string{ + cfg.Annotations.ConfigmapReload: f.name, + }, + ) f.waitForReady() f.updateConfigMap(f.name, "updated-data") @@ -316,9 +308,11 @@ func TestSecretUpdate(t *testing.T) { defer f.cleanup() f.createSecret(f.name, "initial-secret") - f.createDeployment(f.name, false, map[string]string{ - cfg.Annotations.SecretReload: f.name, - }) + f.createDeployment( + f.name, false, map[string]string{ + cfg.Annotations.SecretReload: f.name, + }, + ) f.waitForReady() f.updateSecret(f.name, "updated-secret") @@ -331,9 +325,11 @@ func TestAutoReloadAll(t *testing.T) { defer f.cleanup() f.createConfigMap(f.name, "initial-data") - f.createDeployment(f.name, true, map[string]string{ - cfg.Annotations.Auto: "true", - }) + f.createDeployment( + f.name, true, map[string]string{ + cfg.Annotations.Auto: "true", + }, + ) f.waitForReady() f.updateConfigMap(f.name, "updated-data") @@ -346,9 +342,11 @@ func TestDaemonSetReload(t *testing.T) { defer f.cleanup() f.createConfigMap(f.name, "initial-data") - f.createDaemonSet(f.name, true, map[string]string{ - cfg.Annotations.ConfigmapReload: f.name, - }) + f.createDaemonSet( + f.name, true, map[string]string{ + cfg.Annotations.ConfigmapReload: f.name, + }, + ) f.waitForReady() f.updateConfigMap(f.name, "updated-data") @@ -361,9 +359,11 @@ func TestStatefulSetReload(t *testing.T) { defer f.cleanup() f.createSecret(f.name, "initial-secret") - f.createStatefulSet(f.name, false, map[string]string{ - cfg.Annotations.SecretReload: f.name, - }) + f.createStatefulSet( + f.name, false, map[string]string{ + cfg.Annotations.SecretReload: f.name, + }, + ) f.waitForReady() f.updateSecret(f.name, "updated-secret") @@ -376,9 +376,11 @@ func TestLabelOnlyChange(t *testing.T) { defer f.cleanup() f.createConfigMap(f.name, "initial-data") - f.createDeployment(f.name, true, map[string]string{ - cfg.Annotations.ConfigmapReload: f.name, - }) + f.createDeployment( + f.name, true, map[string]string{ + cfg.Annotations.ConfigmapReload: f.name, + }, + ) f.waitForReady() f.updateConfigMapLabel(f.name, "new-label") @@ -395,9 +397,11 @@ func TestMultipleConfigMaps(t *testing.T) { f.createConfigMap(cm1, "data-a") f.createConfigMap(cm2, "data-b") - f.createDeployment(f.name, true, map[string]string{ - cfg.Annotations.ConfigmapReload: cm1 + "," + cm2, - }) + f.createDeployment( + f.name, true, map[string]string{ + cfg.Annotations.ConfigmapReload: cm1 + "," + cm2, + }, + ) f.waitForReady() f.updateConfigMap(cm1, "updated-data-a") @@ -413,9 +417,11 @@ func TestAutoAnnotationDisabled(t *testing.T) { testCfg.AutoReloadAll = true f.createConfigMap(f.name, "initial-data") - f.createDeployment(f.name, true, map[string]string{ - testCfg.Annotations.Auto: "false", - }) + f.createDeployment( + f.name, true, map[string]string{ + testCfg.Annotations.Auto: "false", + }, + ) f.waitForReady() f.updateConfigMap(f.name, "updated-data") @@ -433,13 +439,14 @@ func TestAutoWithExplicitConfigMapAnnotation(t *testing.T) { f.createConfigMap(referencedCM, "referenced-data") f.createConfigMap(explicitCM, "explicit-data") - f.createDeployment(referencedCM, true, map[string]string{ - cfg.Annotations.Auto: "true", - cfg.Annotations.ConfigmapReload: explicitCM, - }) + f.createDeployment( + referencedCM, true, map[string]string{ + cfg.Annotations.Auto: "true", + cfg.Annotations.ConfigmapReload: explicitCM, + }, + ) f.waitForReady() - // Update the EXPLICIT ConfigMap (not the referenced one) f.updateConfigMap(explicitCM, "updated-explicit-data") f.assertDeploymentReloaded(referencedCM, nil) } @@ -455,13 +462,14 @@ func TestAutoWithExplicitSecretAnnotation(t *testing.T) { f.createSecret(referencedSecret, "referenced-secret") f.createSecret(explicitSecret, "explicit-secret") - f.createDeployment(referencedSecret, false, map[string]string{ - cfg.Annotations.Auto: "true", - cfg.Annotations.SecretReload: explicitSecret, - }) + f.createDeployment( + referencedSecret, false, map[string]string{ + cfg.Annotations.Auto: "true", + cfg.Annotations.SecretReload: explicitSecret, + }, + ) f.waitForReady() - // Update the EXPLICIT Secret (not the referenced one) f.updateSecret(explicitSecret, "updated-explicit-secret") f.assertDeploymentReloaded(referencedSecret, nil) } @@ -477,13 +485,14 @@ func TestAutoWithBothExplicitAndReferencedChange(t *testing.T) { f.createConfigMap(referencedCM, "referenced-data") f.createConfigMap(explicitCM, "explicit-data") - f.createDeployment(referencedCM, true, map[string]string{ - cfg.Annotations.Auto: "true", - cfg.Annotations.ConfigmapReload: explicitCM, - }) + f.createDeployment( + referencedCM, true, map[string]string{ + cfg.Annotations.Auto: "true", + cfg.Annotations.ConfigmapReload: explicitCM, + }, + ) f.waitForReady() - // Update the REFERENCED ConfigMap - should trigger reload via auto f.updateConfigMap(referencedCM, "updated-referenced-data") f.assertDeploymentReloaded(referencedCM, nil) }