From a80c376950facc77ecd587a712bc64d14740892f Mon Sep 17 00:00:00 2001 From: hsiegeln <37154749+hsiegeln@users.noreply.github.com> Date: Sun, 19 Apr 2026 18:32:35 +0200 Subject: [PATCH] fix(alerting): harden V12 migration IT against shared container state - Replace hard-coded 'u1' user_id with per-test UUID to prevent PK collision on re-runs - Add @AfterEach null-safe cleanup for environments and users rows - Use containsExactlyInAnyOrder for enum assertions to catch misspelled names - Slug suffix on environment insert avoids slug uniqueness conflicts on re-runs Co-Authored-By: Claude Sonnet 4.6 --- .../app/alerting/storage/V12MigrationIT.java | 41 ++++++++++++++----- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/cameleer-server-app/src/test/java/com/cameleer/server/app/alerting/storage/V12MigrationIT.java b/cameleer-server-app/src/test/java/com/cameleer/server/app/alerting/storage/V12MigrationIT.java index 11e4b62d..babcebe7 100644 --- a/cameleer-server-app/src/test/java/com/cameleer/server/app/alerting/storage/V12MigrationIT.java +++ b/cameleer-server-app/src/test/java/com/cameleer/server/app/alerting/storage/V12MigrationIT.java @@ -1,11 +1,21 @@ package com.cameleer.server.app.alerting.storage; import com.cameleer.server.app.AbstractPostgresIT; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; class V12MigrationIT extends AbstractPostgresIT { + private java.util.UUID testEnvId; + private String testUserId; + + @AfterEach + void cleanup() { + if (testEnvId != null) jdbcTemplate.update("DELETE FROM environments WHERE id = ?", testEnvId); + if (testUserId != null) jdbcTemplate.update("DELETE FROM users WHERE user_id = ?", testUserId); + } + @Test void allAlertingTablesAndEnumsExist() { var tables = jdbcTemplate.queryForList( @@ -22,38 +32,47 @@ class V12MigrationIT extends AbstractPostgresIT { "('severity_enum','condition_kind_enum','alert_state_enum'," + "'target_kind_enum','notification_status_enum')", String.class); - assertThat(enums).hasSize(5); + assertThat(enums).containsExactlyInAnyOrder( + "severity_enum", "condition_kind_enum", "alert_state_enum", + "target_kind_enum", "notification_status_enum"); } @Test void deletingEnvironmentCascadesAlertingRows() { - var envId = java.util.UUID.randomUUID(); + testEnvId = java.util.UUID.randomUUID(); + testUserId = java.util.UUID.randomUUID().toString(); + jdbcTemplate.update( "INSERT INTO environments (id, slug, display_name) VALUES (?, ?, ?)", - envId, "test-cascade-env", "Test Cascade Env"); + testEnvId, "test-cascade-env-" + testEnvId, "Test Cascade Env"); jdbcTemplate.update( - "INSERT INTO users (user_id, provider, email) " + - "VALUES (?, ?, ?)", "u1", "local", "a@b.test"); + "INSERT INTO users (user_id, provider, email) VALUES (?, ?, ?)", + testUserId, "local", "test@example.com"); + var ruleId = java.util.UUID.randomUUID(); jdbcTemplate.update( "INSERT INTO alert_rules (id, environment_id, name, severity, condition_kind, condition, " + "notification_title_tmpl, notification_message_tmpl, created_by, updated_by) " + - "VALUES (?, ?, 'r', 'WARNING', 'AGENT_STATE', '{}'::jsonb, 't', 'm', 'u1', 'u1')", - ruleId, envId); + "VALUES (?, ?, 'r', 'WARNING', 'AGENT_STATE', '{}'::jsonb, 't', 'm', ?, ?)", + ruleId, testEnvId, testUserId, testUserId); + var instanceId = java.util.UUID.randomUUID(); jdbcTemplate.update( "INSERT INTO alert_instances (id, rule_id, rule_snapshot, environment_id, state, severity, " + "fired_at, context, title, message) VALUES (?, ?, '{}'::jsonb, ?, 'FIRING', 'WARNING', " + "now(), '{}'::jsonb, 't', 'm')", - instanceId, ruleId, envId); + instanceId, ruleId, testEnvId); - jdbcTemplate.update("DELETE FROM environments WHERE id = ?", envId); + jdbcTemplate.update("DELETE FROM environments WHERE id = ?", testEnvId); assertThat(jdbcTemplate.queryForObject( "SELECT count(*) FROM alert_rules WHERE environment_id = ?", - Integer.class, envId)).isZero(); + Integer.class, testEnvId)).isZero(); assertThat(jdbcTemplate.queryForObject( "SELECT count(*) FROM alert_instances WHERE environment_id = ?", - Integer.class, envId)).isZero(); + Integer.class, testEnvId)).isZero(); + + // testEnvId already deleted; null it so @AfterEach doesn't attempt a no-op delete + testEnvId = null; } }