Centralize Postgres test fixture in internal/test

Each package that exercises the database against a real Postgres
carried its own copy of the connection bootstrap and schema setup.
Those copies had already drifted: some keyed off PROBO_TEST_PG_ADDR
with hardcoded defaults, others off PROBO_TEST_PG_URL, and the
agentrun/coredata suites hand-applied individual agent_runs
migrations to ensure the table existed.

Introduce a single test.PGClient helper that parses PROBO_TEST_PG_URL
(falling back to the local compose database), runs the full coredata
migration set once per process, and skips when no database is
reachable so make test stays a pure unit-test run. Migrate the
agentrun, coredata, cookiebanner, iam, and thirdparty suites onto it
and delete the duplicated helpers so the bootstrap can no longer
diverge.

Signed-off-by: Bryan Frimin <bryan@probo.com>
This commit is contained in:
Bryan Frimin
2026-06-07 12:14:03 +02:00
parent 0a1b47607b
commit a8d4da3916
13 changed files with 233 additions and 513 deletions

View File

@@ -18,66 +18,18 @@ import (
"context"
"errors"
"io"
"net"
"net/url"
"os"
"testing"
"time"
"github.com/prometheus/client_golang/prometheus"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.gearno.de/kit/log"
"go.gearno.de/kit/pg"
"go.probo.inc/probo/internal/test"
"go.probo.inc/probo/pkg/coredata"
"go.probo.inc/probo/pkg/gid"
)
const testPgDSNEnvVar = "PROBO_TEST_PG_URL"
func newTestPgClient(t *testing.T) *pg.Client {
t.Helper()
dsn := os.Getenv(testPgDSNEnvVar)
if dsn == "" {
t.Skipf("skipping: %s not set (requires a migrated test database)", testPgDSNEnvVar)
}
u, err := url.Parse(dsn)
require.NoError(t, err, "invalid %s value", testPgDSNEnvVar)
opts := []pg.Option{pg.WithRegisterer(prometheus.NewRegistry())}
if u.Host != "" {
host := u.Host
if u.Port() == "" {
host = net.JoinHostPort(u.Hostname(), "5432")
}
opts = append(opts, pg.WithAddr(host))
}
if u.User != nil {
opts = append(opts, pg.WithUser(u.User.Username()))
if password, ok := u.User.Password(); ok {
opts = append(opts, pg.WithPassword(password))
}
}
if len(u.Path) > 1 {
opts = append(opts, pg.WithDatabase(u.Path[1:]))
}
client, err := pg.NewClient(opts...)
require.NoError(t, err)
t.Cleanup(func() {
client.Close()
})
return client
}
// workerFixture bootstraps the parent rows the worker's transaction
// needs: an organization, a cookie banner, an uncategorised category,
// and a normal category. Patterns/detected trackers are seeded
@@ -314,7 +266,7 @@ func seedThirdParty(t *testing.T, ctx context.Context, client *pg.Client, fx wor
func TestPatternAnalysisWorker_PromotesSourceOnExistingGlob(t *testing.T) {
t.Parallel()
client := newTestPgClient(t)
client := test.PGClient(t)
ctx := context.Background()
fx := seedWorkerFixture(t, ctx, client)
@@ -394,7 +346,7 @@ func TestPatternAnalysisWorker_PromotesSourceOnExistingGlob(t *testing.T) {
func TestPatternAnalysisWorker_AdoptionTriggersDraftVersion(t *testing.T) {
t.Parallel()
client := newTestPgClient(t)
client := test.PGClient(t)
ctx := context.Background()
fx := seedWorkerFixture(t, ctx, client)
@@ -480,7 +432,7 @@ func TestPatternAnalysisWorker_AdoptionTriggersDraftVersion(t *testing.T) {
func TestPatternAnalysisWorker_AdoptionPromotesSourceCrossCategory(t *testing.T) {
t.Parallel()
client := newTestPgClient(t)
client := test.PGClient(t)
ctx := context.Background()
fx := seedWorkerFixture(t, ctx, client)
@@ -563,7 +515,7 @@ func TestPatternAnalysisWorker_AdoptionPromotesSourceCrossCategory(t *testing.T)
func TestReportDetectedTrackers_PromotesSourceOnExistingGlob(t *testing.T) {
t.Parallel()
client := newTestPgClient(t)
client := test.PGClient(t)
ctx := context.Background()
fx := seedWorkerFixture(t, ctx, client)
@@ -628,7 +580,7 @@ func TestReportDetectedTrackers_PromotesSourceOnExistingGlob(t *testing.T) {
func TestPatternAnalysisWorker_MergeWithoutAdoptionSkipsDraftVersion(t *testing.T) {
t.Parallel()
client := newTestPgClient(t)
client := test.PGClient(t)
ctx := context.Background()
fx := seedWorkerFixture(t, ctx, client)
@@ -690,7 +642,7 @@ func TestPatternAnalysisWorker_MergeWithoutAdoptionSkipsDraftVersion(t *testing.
func TestPatternAnalysisWorker_GlobInheritsUnanimousMapping(t *testing.T) {
t.Parallel()
client := newTestPgClient(t)
client := test.PGClient(t)
ctx := context.Background()
fx := seedWorkerFixture(t, ctx, client)
@@ -749,7 +701,7 @@ func TestPatternAnalysisWorker_GlobInheritsUnanimousMapping(t *testing.T) {
func TestPatternAnalysisWorker_GlobSkipsConflictingMapping(t *testing.T) {
t.Parallel()
client := newTestPgClient(t)
client := test.PGClient(t)
ctx := context.Background()
fx := seedWorkerFixture(t, ctx, client)