diff --git a/veza-backend-api/internal/testutils/main_test.go b/veza-backend-api/internal/testutils/main_test.go new file mode 100644 index 000000000..3253aa433 --- /dev/null +++ b/veza-backend-api/internal/testutils/main_test.go @@ -0,0 +1,21 @@ +package testutils + +import ( + "fmt" + "os" + "testing" +) + +// TestMain skips the entire testutils test suite when integration prerequisites +// (Docker daemon for testcontainers) are unavailable. The testutils package's own +// tests exercise SetupTestDB and CleanupDatabaseWithOptions which require a real +// Postgres container, so there is nothing meaningful to run without it. +// +// CI sets VEZA_SKIP_INTEGRATION=1 on runners without /var/run/docker.sock. +func TestMain(m *testing.M) { + if os.Getenv("VEZA_SKIP_INTEGRATION") == "1" { + fmt.Println("testutils: skipping package (VEZA_SKIP_INTEGRATION=1)") + os.Exit(0) + } + os.Exit(m.Run()) +} diff --git a/veza-backend-api/internal/testutils/setup.go b/veza-backend-api/internal/testutils/setup.go index e162c74a6..fefd02795 100644 --- a/veza-backend-api/internal/testutils/setup.go +++ b/veza-backend-api/internal/testutils/setup.go @@ -26,9 +26,17 @@ var ( // GetTestContainerDB ensures the postgres container is running and returns the DSN. // It uses a singleton pattern to start the container only once per test run. -// If DATABASE_URL is set (e.g. CI with real PostgreSQL), uses it instead of testcontainer. +// +// Resolution order: +// 1. VEZA_SKIP_INTEGRATION=1 → return an error immediately (CI runners w/o Docker) +// 2. DATABASE_URL set → use it directly (CI with a sidecar Postgres service) +// 3. Otherwise → start a postgres testcontainer (local dev / nightly job) func GetTestContainerDB(ctx context.Context) (string, error) { containerOnce.Do(func() { + if os.Getenv("VEZA_SKIP_INTEGRATION") == "1" { + pgErr = fmt.Errorf("integration tests skipped: VEZA_SKIP_INTEGRATION=1") + return + } if dsn := os.Getenv("DATABASE_URL"); dsn != "" { pgDSN = dsn pgErr = nil diff --git a/veza-backend-api/internal/testutils/skip.go b/veza-backend-api/internal/testutils/skip.go new file mode 100644 index 000000000..6546d566a --- /dev/null +++ b/veza-backend-api/internal/testutils/skip.go @@ -0,0 +1,23 @@ +package testutils + +import ( + "os" + "testing" +) + +// SkipIfNoIntegration skips the current test when integration prerequisites +// (notably a running Docker daemon for testcontainers-go) are unavailable. +// +// It honors: +// - `go test -short` (testing.Short()) +// - VEZA_SKIP_INTEGRATION=1 environment variable (set by CI runners +// without Docker socket access) +// +// Call this at the very top of any test helper that relies on +// GetTestContainerDB or otherwise spins up Postgres via testcontainers. +func SkipIfNoIntegration(t *testing.T) { + t.Helper() + if testing.Short() || os.Getenv("VEZA_SKIP_INTEGRATION") == "1" { + t.Skip("integration test requires Docker; skipped (-short or VEZA_SKIP_INTEGRATION=1)") + } +} diff --git a/veza-backend-api/tests/integration/main_test.go b/veza-backend-api/tests/integration/main_test.go new file mode 100644 index 000000000..eec63ff4b --- /dev/null +++ b/veza-backend-api/tests/integration/main_test.go @@ -0,0 +1,21 @@ +package integration + +import ( + "fmt" + "os" + "testing" +) + +// TestMain skips the entire integration test suite when Docker is unavailable +// (no /var/run/docker.sock). Integration tests rely on testcontainers for +// Postgres, Redis, etc., and have no meaningful behavior without them. +// +// Set by CI: VEZA_SKIP_INTEGRATION=1 on Forgejo runners that don't expose +// the Docker socket. Local dev / nightly jobs leave it unset. +func TestMain(m *testing.M) { + if os.Getenv("VEZA_SKIP_INTEGRATION") == "1" { + fmt.Println("integration: skipping package (VEZA_SKIP_INTEGRATION=1)") + os.Exit(0) + } + os.Exit(m.Run()) +} diff --git a/veza-backend-api/tests/transactions/main_test.go b/veza-backend-api/tests/transactions/main_test.go new file mode 100644 index 000000000..86e4117f8 --- /dev/null +++ b/veza-backend-api/tests/transactions/main_test.go @@ -0,0 +1,21 @@ +package transactions + +import ( + "fmt" + "os" + "testing" +) + +// TestMain skips the entire transactions test suite when Docker is unavailable. +// All tests in this package rely on testcontainers-go to spin up a real Postgres +// container so transactional rollback semantics can be validated. +// +// Set by CI: VEZA_SKIP_INTEGRATION=1 on Forgejo runners that don't expose +// the Docker socket. Local dev / nightly jobs leave it unset. +func TestMain(m *testing.M) { + if os.Getenv("VEZA_SKIP_INTEGRATION") == "1" { + fmt.Println("transactions: skipping package (VEZA_SKIP_INTEGRATION=1)") + os.Exit(0) + } + os.Exit(m.Run()) +} diff --git a/veza-backend-api/tests/transactions/playlist_duplicate_transaction_test.go b/veza-backend-api/tests/transactions/playlist_duplicate_transaction_test.go index 939076d34..7d0d254db 100644 --- a/veza-backend-api/tests/transactions/playlist_duplicate_transaction_test.go +++ b/veza-backend-api/tests/transactions/playlist_duplicate_transaction_test.go @@ -19,6 +19,7 @@ import ( // setupTestDB crée une DB de test avec testcontainers func setupTestDBForPlaylist(t *testing.T) *gorm.DB { + testutils.SkipIfNoIntegration(t) ctx := context.Background() dsn, err := testutils.GetTestContainerDB(ctx) require.NoError(t, err, "Failed to setup test database") diff --git a/veza-backend-api/tests/transactions/rbac_transaction_test.go b/veza-backend-api/tests/transactions/rbac_transaction_test.go index 37c220cd8..d89a4a170 100644 --- a/veza-backend-api/tests/transactions/rbac_transaction_test.go +++ b/veza-backend-api/tests/transactions/rbac_transaction_test.go @@ -19,6 +19,7 @@ import ( // setupTestDB crée une DB de test avec testcontainers func setupTestDB(t *testing.T) *gorm.DB { + testutils.SkipIfNoIntegration(t) ctx := context.Background() dsn, err := testutils.GetTestContainerDB(ctx) require.NoError(t, err, "Failed to setup test database") diff --git a/veza-backend-api/tests/transactions/social_transaction_test.go b/veza-backend-api/tests/transactions/social_transaction_test.go index 2ccdf3dba..bfe8c3b3e 100644 --- a/veza-backend-api/tests/transactions/social_transaction_test.go +++ b/veza-backend-api/tests/transactions/social_transaction_test.go @@ -18,6 +18,7 @@ import ( // setupTestDB crée une DB de test avec testcontainers func setupTestDBForSocial(t *testing.T) *gorm.DB { + testutils.SkipIfNoIntegration(t) ctx := context.Background() dsn, err := testutils.GetTestContainerDB(ctx) require.NoError(t, err, "Failed to setup test database")