From dd0a792438bb6ef88863e404b3391ab890590636 Mon Sep 17 00:00:00 2001 From: Simon Pasquier Date: Fri, 30 Jan 2026 16:06:25 +0100 Subject: [PATCH] Add end-to-end tests for Alertmanager and ThanosRuler Signed-off-by: Simon Pasquier --- test/e2e/alertmanager_test.go | 31 +++++++++++++++++++++++++++++++ test/e2e/main_test.go | 2 ++ test/e2e/thanosruler_test.go | 30 ++++++++++++++++++++++++++++++ test/framework/thanosruler.go | 11 +++++++++++ 4 files changed, 74 insertions(+) diff --git a/test/e2e/alertmanager_test.go b/test/e2e/alertmanager_test.go index 476e72227..983b1691c 100644 --- a/test/e2e/alertmanager_test.go +++ b/test/e2e/alertmanager_test.go @@ -2729,3 +2729,34 @@ func testAlertManagerServiceName(t *testing.T) { require.Len(t, svcList.Items, 1) require.Equal(t, svcList.Items[0].Name, svc.Name) } + +func testAMScaleUpWithoutLabels(t *testing.T) { + // Don't run Alertmanager tests in parallel. See + // https://github.com/prometheus/alertmanager/issues/1835 for details. + ctx := context.Background() + testCtx := framework.NewTestCtx(t) + defer testCtx.Cleanup(t) + ns := framework.CreateNamespace(ctx, t, testCtx) + framework.SetupPrometheusRBAC(ctx, t, testCtx, ns) + + name := "test" + + // Create an Alertmanager resource with 1 replica + am, err := framework.CreateAlertmanagerAndWaitUntilReady(ctx, framework.MakeBasicAlertmanager(ns, name, 1)) + require.NoError(t, err) + + // Remove all labels on the StatefulSet using Patch + stsName := fmt.Sprintf("alertmanager-%s", name) + err = framework.RemoveAllLabelsFromStatefulSet(ctx, stsName, ns) + require.NoError(t, err) + + // Scale up the Alertmanager resource to 2 replicas + _, err = framework.UpdateAlertmanagerReplicasAndWaitUntilReady(ctx, am.Name, ns, 2) + require.NoError(t, err) + + // Verify the StatefulSet now has labels again (restored by the operator) + stsClient := framework.KubeClient.AppsV1().StatefulSets(ns) + sts, err := stsClient.Get(ctx, stsName, metav1.GetOptions{}) + require.NoError(t, err) + require.NotEmpty(t, sts.GetLabels(), "expected labels to be restored on the StatefulSet by the operator") +} diff --git a/test/e2e/main_test.go b/test/e2e/main_test.go index 9fb5f6ebd..899425963 100644 --- a/test/e2e/main_test.go +++ b/test/e2e/main_test.go @@ -251,6 +251,7 @@ func testAllNSAlertmanager(t *testing.T) { "AMTemplateReloadConfig": testAMTmplateReloadConfig, "AMStatusScale": testAlertmanagerStatusScale, "AMServiceName": testAlertManagerServiceName, + "AMScaleUpWithoutLabels": testAMScaleUpWithoutLabels, } for name, f := range testFuncs { @@ -342,6 +343,7 @@ func testAllNSThanosRuler(t *testing.T) { "ThanosRulerCheckStorageClass": testTRCheckStorageClass, "ThanosRulerServiceName": testThanosRulerServiceName, "ThanosRulerStateless": testThanosRulerStateless, + "ThanosRulerScaleUpWithoutLabels": testThanosRulerScaleUpWithoutLabels, } for name, f := range testFuncs { t.Run(name, f) diff --git a/test/e2e/thanosruler_test.go b/test/e2e/thanosruler_test.go index 8538f5586..1d4fa10d0 100644 --- a/test/e2e/thanosruler_test.go +++ b/test/e2e/thanosruler_test.go @@ -636,3 +636,33 @@ func testThanosRulerStateless(t *testing.T) { err = framework.WaitForPrometheusFiringAlert(context.Background(), ns, promSVC.Name, testAlert) require.NoError(t, err) } + +func testThanosRulerScaleUpWithoutLabels(t *testing.T) { + t.Parallel() + ctx := context.Background() + testCtx := framework.NewTestCtx(t) + defer testCtx.Cleanup(t) + ns := framework.CreateNamespace(ctx, t, testCtx) + framework.SetupPrometheusRBAC(ctx, t, testCtx, ns) + + name := "test" + + // Create a ThanosRuler resource with 1 replica + tr, err := framework.CreateThanosRulerAndWaitUntilReady(ctx, ns, framework.MakeBasicThanosRuler(name, 1, "http://test.example.com")) + require.NoError(t, err) + + // Remove all labels on the StatefulSet using Patch + stsName := fmt.Sprintf("thanos-ruler-%s", name) + err = framework.RemoveAllLabelsFromStatefulSet(ctx, stsName, ns) + require.NoError(t, err) + + // Scale up the ThanosRuler resource to 2 replicas + _, err = framework.UpdateThanosRulerReplicasAndWaitUntilReady(ctx, tr.Name, ns, 2) + require.NoError(t, err) + + // Verify the StatefulSet now has labels again (restored by the operator) + stsClient := framework.KubeClient.AppsV1().StatefulSets(ns) + sts, err := stsClient.Get(ctx, stsName, metav1.GetOptions{}) + require.NoError(t, err) + require.NotEmpty(t, sts.GetLabels(), "expected labels to be restored on the StatefulSet by the operator") +} diff --git a/test/framework/thanosruler.go b/test/framework/thanosruler.go index a1ddb9081..91d27f073 100644 --- a/test/framework/thanosruler.go +++ b/test/framework/thanosruler.go @@ -108,6 +108,17 @@ func (f *Framework) PatchThanosRuler(ctx context.Context, name, ns string, spec return tr, nil } +func (f *Framework) UpdateThanosRulerReplicasAndWaitUntilReady(ctx context.Context, name, ns string, replicas int32) (*monitoringv1.ThanosRuler, error) { + return f.PatchThanosRulerAndWaitUntilReady( + ctx, + name, + ns, + monitoringv1.ThanosRulerSpec{ + Replicas: ptr.To(replicas), + }, + ) +} + func (f *Framework) WaitForThanosRulerReady(ctx context.Context, ns string, tr *monitoringv1.ThanosRuler, timeout time.Duration) error { expected := *tr.Spec.Replicas