From 0d56a17068985d71462daa8a5af7b2fe5c8451b9 Mon Sep 17 00:00:00 2001 From: James Greenhill Date: Fri, 5 Jun 2026 08:59:12 -0700 Subject: [PATCH] Use neutral tenant fixtures --- controlplane/admin/api_test.go | 24 ++++++++-------- controlplane/configstore/store_test.go | 28 +++++++++--------- controlplane/k8s_pool_test.go | 2 +- duckdbservice/arrow_helpers.go | 2 +- duckdbservice/progress.go | 2 +- repository_hygiene_test.go | 39 ++++++++++++++++++++++++++ server/conn_test.go | 2 +- transpiler/create_or_replace.go | 4 +-- transpiler/transpiler_test.go | 32 ++++++++++----------- 9 files changed, 87 insertions(+), 48 deletions(-) create mode 100644 repository_hygiene_test.go diff --git a/controlplane/admin/api_test.go b/controlplane/admin/api_test.go index 1a64c16e..d115139c 100644 --- a/controlplane/admin/api_test.go +++ b/controlplane/admin/api_test.go @@ -1261,7 +1261,7 @@ func TestCreateOrgPersistsHostnameAlias(t *testing.T) { store := newFakeAPIStore() router := newTestAPIRouter(store) - body := []byte(`{"name":"portola-uuid","database_name":"portola","hostname_alias":"entirely-chief-wildcat"}`) + body := []byte(`{"name":"tenant-alpha-id","database_name":"tenant_alpha","hostname_alias":"entirely-chief-wildcat"}`) req := httptest.NewRequest(http.MethodPost, "/api/v1/orgs", bytes.NewReader(body)) req.Header.Set("Content-Type", "application/json") rec := httptest.NewRecorder() @@ -1270,7 +1270,7 @@ func TestCreateOrgPersistsHostnameAlias(t *testing.T) { if rec.Code != http.StatusCreated { t.Fatalf("status = %d, want %d: %s", rec.Code, http.StatusCreated, rec.Body.String()) } - stored := store.orgs["portola-uuid"] + stored := store.orgs["tenant-alpha-id"] if stored == nil { t.Fatal("org not stored") } @@ -1304,15 +1304,15 @@ func TestCreateOrgEmptyHostnameAliasIsTreatedAsNone(t *testing.T) { func TestUpdateOrgClearsHostnameAliasWithEmptyString(t *testing.T) { store := newFakeAPIStore() alias := "entirely-chief-wildcat" - store.orgs["portola-uuid"] = &configstore.Org{ - Name: "portola-uuid", - DatabaseName: "portola", + store.orgs["tenant-alpha-id"] = &configstore.Org{ + Name: "tenant-alpha-id", + DatabaseName: "tenant_alpha", HostnameAlias: &alias, } router := newTestAPIRouter(store) body := []byte(`{"hostname_alias":""}`) - req := httptest.NewRequest(http.MethodPut, "/api/v1/orgs/portola-uuid", bytes.NewReader(body)) + req := httptest.NewRequest(http.MethodPut, "/api/v1/orgs/tenant-alpha-id", bytes.NewReader(body)) req.Header.Set("Content-Type", "application/json") rec := httptest.NewRecorder() router.ServeHTTP(rec, req) @@ -1320,7 +1320,7 @@ func TestUpdateOrgClearsHostnameAliasWithEmptyString(t *testing.T) { if rec.Code != http.StatusOK { t.Fatalf("status = %d, want %d: %s", rec.Code, http.StatusOK, rec.Body.String()) } - stored := store.orgs["portola-uuid"] + stored := store.orgs["tenant-alpha-id"] if stored.HostnameAlias != nil { t.Errorf("HostnameAlias not cleared: %v", stored.HostnameAlias) } @@ -1398,15 +1398,15 @@ func TestCreateOrgRejectsHostnameAliasOver63Chars(t *testing.T) { func TestUpdateOrgOmittingHostnameAliasPreservesIt(t *testing.T) { store := newFakeAPIStore() alias := "entirely-chief-wildcat" - store.orgs["portola-uuid"] = &configstore.Org{ - Name: "portola-uuid", - DatabaseName: "portola", + store.orgs["tenant-alpha-id"] = &configstore.Org{ + Name: "tenant-alpha-id", + DatabaseName: "tenant_alpha", HostnameAlias: &alias, } router := newTestAPIRouter(store) body := []byte(`{"max_workers":8}`) - req := httptest.NewRequest(http.MethodPut, "/api/v1/orgs/portola-uuid", bytes.NewReader(body)) + req := httptest.NewRequest(http.MethodPut, "/api/v1/orgs/tenant-alpha-id", bytes.NewReader(body)) req.Header.Set("Content-Type", "application/json") rec := httptest.NewRecorder() router.ServeHTTP(rec, req) @@ -1414,7 +1414,7 @@ func TestUpdateOrgOmittingHostnameAliasPreservesIt(t *testing.T) { if rec.Code != http.StatusOK { t.Fatalf("status = %d, want %d: %s", rec.Code, http.StatusOK, rec.Body.String()) } - stored := store.orgs["portola-uuid"] + stored := store.orgs["tenant-alpha-id"] if stored.HostnameAlias == nil || *stored.HostnameAlias != "entirely-chief-wildcat" { t.Errorf("HostnameAlias not preserved: %v", stored.HostnameAlias) } diff --git a/controlplane/configstore/store_test.go b/controlplane/configstore/store_test.go index 5d1e0bf4..7397aad5 100644 --- a/controlplane/configstore/store_test.go +++ b/controlplane/configstore/store_test.go @@ -181,22 +181,22 @@ func TestDatabaseNameForSNIPrefix(t *testing.T) { cs := &ConfigStore{ snapshot: &Snapshot{ Orgs: map[string]*OrgConfig{ - "portola-uuid": {Name: "portola-uuid", DatabaseName: "portola"}, - "acme": {Name: "acme", DatabaseName: "acme"}, + "tenant-alpha-uuid": {Name: "tenant-alpha-uuid", DatabaseName: "tenant_alpha"}, + "acme": {Name: "acme", DatabaseName: "acme"}, }, DatabaseOrg: map[string]string{ - "portola": "portola-uuid", - "acme": "acme", + "tenant_alpha": "tenant-alpha-uuid", + "acme": "acme", }, HostnameAliasOrg: map[string]string{ - "entirely-chief-wildcat": "portola-uuid", + "entirely-chief-wildcat": "tenant-alpha-uuid", }, }, } // Alias resolves to the org's database_name (the security-through-obscurity case). - if got := cs.DatabaseNameForSNIPrefix("entirely-chief-wildcat"); got != "portola" { - t.Errorf("DatabaseNameForSNIPrefix(alias) = %q, want %q", got, "portola") + if got := cs.DatabaseNameForSNIPrefix("entirely-chief-wildcat"); got != "tenant_alpha" { + t.Errorf("DatabaseNameForSNIPrefix(alias) = %q, want %q", got, "tenant_alpha") } // Plain prefix passes through unchanged so legacy tenants (no alias) keep working. if got := cs.DatabaseNameForSNIPrefix("acme"); got != "acme" { @@ -221,19 +221,19 @@ func TestResolveSNIPrefix(t *testing.T) { cs := &ConfigStore{ snapshot: &Snapshot{ Orgs: map[string]*OrgConfig{ - "portola-uuid": {Name: "portola-uuid", DatabaseName: "portola"}, + "tenant-alpha-id": {Name: "tenant-alpha-id", DatabaseName: "tenant_alpha"}, "team-hyphen": {Name: "team-hyphen", DatabaseName: "team_hyphen"}, "team_underscore": {Name: "team_underscore", DatabaseName: "teamdb"}, "acme": {Name: "acme", DatabaseName: "acme"}, }, DatabaseOrg: map[string]string{ - "portola": "portola-uuid", - "team_hyphen": "team-hyphen", - "teamdb": "team_underscore", - "acme": "acme", + "tenant_alpha": "tenant-alpha-id", + "team_hyphen": "team-hyphen", + "teamdb": "team_underscore", + "acme": "acme", }, HostnameAliasOrg: map[string]string{ - "entirely-chief-wildcat": "portola-uuid", + "entirely-chief-wildcat": "tenant-alpha-id", }, }, } @@ -244,7 +244,7 @@ func TestResolveSNIPrefix(t *testing.T) { wantOrg string wantDB string }{ - {"hostname alias", "entirely-chief-wildcat", "portola-uuid", "portola"}, + {"hostname alias", "entirely-chief-wildcat", "tenant-alpha-id", "tenant_alpha"}, {"database name", "acme", "acme", "acme"}, {"hyphenated org name", "team-hyphen", "team-hyphen", "team_hyphen"}, {"non DNS-safe org name", "team_underscore", "", ""}, diff --git a/controlplane/k8s_pool_test.go b/controlplane/k8s_pool_test.go index c1d39415..35fae68d 100644 --- a/controlplane/k8s_pool_test.go +++ b/controlplane/k8s_pool_test.go @@ -1789,7 +1789,7 @@ func TestK8sPoolReserveSharedWorkerSkipsWarmWorkerWithMismatchedImageWithoutRunt } worker, err := pool.ReserveSharedWorker(context.Background(), &WorkerAssignment{ - OrgID: "portola", + OrgID: "tenant-alpha", Image: pinnedImage, MaxWorkers: 2, }) diff --git a/duckdbservice/arrow_helpers.go b/duckdbservice/arrow_helpers.go index 34de2360..44e2273e 100644 --- a/duckdbservice/arrow_helpers.go +++ b/duckdbservice/arrow_helpers.go @@ -81,7 +81,7 @@ func isNil(i contextQueryer) bool { return true } v := reflect.ValueOf(i) - return v.Kind() == reflect.Ptr && v.IsNil() + return v.Kind() == reflect.Pointer && v.IsNil() } // GetQuerySchema executes a query with LIMIT 0 to discover the result schema. diff --git a/duckdbservice/progress.go b/duckdbservice/progress.go index 9dc78920..cbd4363a 100644 --- a/duckdbservice/progress.go +++ b/duckdbservice/progress.go @@ -58,7 +58,7 @@ func extractDuckDBConnection(sqlConn *sql.Conn) (bindings.Connection, error) { var duckConn bindings.Connection err := sqlConn.Raw(func(driverConn interface{}) error { v := reflect.ValueOf(driverConn) - if v.Kind() == reflect.Ptr { + if v.Kind() == reflect.Pointer { v = v.Elem() } if v.Kind() != reflect.Struct { diff --git a/repository_hygiene_test.go b/repository_hygiene_test.go new file mode 100644 index 00000000..b37c0aec --- /dev/null +++ b/repository_hygiene_test.go @@ -0,0 +1,39 @@ +package main + +import ( + "bytes" + "os" + "os/exec" + "strings" + "testing" +) + +func TestRepositoryDoesNotContainForbiddenToken(t *testing.T) { + token := os.Getenv("DUCKGRES_FORBIDDEN_REPO_TOKEN") + if token == "" { + t.Skip("DUCKGRES_FORBIDDEN_REPO_TOKEN is unset") + } + + var matches []string + files, err := exec.Command("git", "ls-files", "-z").Output() + if err != nil { + t.Fatalf("list tracked files: %v", err) + } + + for _, file := range bytes.Split(files, []byte{0}) { + if len(file) == 0 { + continue + } + path := string(file) + content, err := os.ReadFile(path) + if err != nil { + t.Fatal(err) + } + if bytes.Contains(bytes.ToLower(content), []byte(strings.ToLower(token))) { + matches = append(matches, path) + } + } + if len(matches) > 0 { + t.Fatalf("forbidden repository token found in %s", strings.Join(matches, ", ")) + } +} diff --git a/server/conn_test.go b/server/conn_test.go index 7d058c53..e2b16943 100644 --- a/server/conn_test.go +++ b/server/conn_test.go @@ -37,7 +37,7 @@ func TestIsDuckDBUtilityCommand(t *testing.T) { // they fell through to pg_query and failed with a syntax error on the // PERSISTENT/TEMPORARY keyword. {"drop persistent secret", `DROP PERSISTENT SECRET foo`, true}, - {"drop persistent secret if exists quoted", `DROP PERSISTENT SECRET IF EXISTS "portola_warehouse_prod_s3"`, true}, + {"drop persistent secret if exists quoted", `DROP PERSISTENT SECRET IF EXISTS "tenant_alpha_warehouse_prod_s3"`, true}, {"drop temporary secret", `DROP TEMPORARY SECRET foo`, true}, {"drop temporary secret if exists", `DROP TEMPORARY SECRET IF EXISTS foo`, true}, {"case insensitive", `drop persistent secret foo`, true}, diff --git a/transpiler/create_or_replace.go b/transpiler/create_or_replace.go index 4f00ddfb..47c0082e 100644 --- a/transpiler/create_or_replace.go +++ b/transpiler/create_or_replace.go @@ -10,9 +10,9 @@ import "regexp" // pg_query cannot parse this DuckDB-specific form. Without interception the // transpiler would set FallbackToNative and conn.go would forward the SQL // raw — skipping every transform, including the logical-catalog rewrite -// (logical database name -> physical catalog, e.g. `portola` -> `ducklake`). +// (logical database name -> physical catalog, e.g. `analytics` -> `ducklake`). // On a multi-tenant worker the physical catalog is `ducklake`, so the -// un-rewritten logical name fails to bind ("Catalog \"portola\" does not +// un-rewritten logical name fails to bind ("Catalog \"analytics\" does not // exist"). dbt-duckdb and SQLMesh both materialize tables with // `CREATE OR REPLACE TABLE ... AS ...`, so this hit real tenants. // diff --git a/transpiler/transpiler_test.go b/transpiler/transpiler_test.go index 8c5a73e4..e7d99461 100644 --- a/transpiler/transpiler_test.go +++ b/transpiler/transpiler_test.go @@ -450,7 +450,7 @@ func TestTranspile_CreateOrReplaceTable_LogicalCatalog(t *testing.T) { // OR REPLACE for TABLE). Before the pre-parse interceptor this fell back // to native and was forwarded raw, so the logical catalog name was never // rewritten to the physical catalog — breaking multi-tenant dbt/SQLMesh - // table materializations with "Catalog \"portola\" does not exist". + // table materializations with "Catalog \"analytics\" does not exist". tests := []struct { name string input string @@ -459,37 +459,37 @@ func TestTranspile_CreateOrReplaceTable_LogicalCatalog(t *testing.T) { }{ { name: "CTAS target and source both rewritten, OR REPLACE preserved", - input: `CREATE OR REPLACE TABLE "portola"."core"."payment_events" AS SELECT * FROM "portola"."core"."raw_payments"`, + input: `CREATE OR REPLACE TABLE "analytics"."core"."payment_events" AS SELECT * FROM "analytics"."core"."raw_payments"`, contains: []string{"CREATE OR REPLACE TABLE", "ducklake.core.payment_events", "ducklake.core.raw_payments"}, - excludes: "portola", + excludes: "analytics", }, { name: "public schema maps to main; OR REPLACE preserved", - input: `CREATE OR REPLACE TABLE portola.public.t AS SELECT 1 AS x`, + input: `CREATE OR REPLACE TABLE analytics.public.t AS SELECT 1 AS x`, contains: []string{"CREATE OR REPLACE TABLE", "ducklake.main.t"}, - excludes: "portola", + excludes: "analytics", }, { name: "multi-line AS SELECT body still rewritten", - input: "CREATE OR REPLACE TABLE portola.core.t AS\nSELECT a\nFROM portola.core.src\nWHERE a > 0", + input: "CREATE OR REPLACE TABLE analytics.core.t AS\nSELECT a\nFROM analytics.core.src\nWHERE a > 0", contains: []string{"CREATE OR REPLACE TABLE", "ducklake.core.t", "ducklake.core.src"}, - excludes: "portola", + excludes: "analytics", }, { name: "TEMP variant preserves OR REPLACE and TEMP", - input: `CREATE OR REPLACE TEMP TABLE t AS SELECT * FROM portola.core.src`, + input: `CREATE OR REPLACE TEMP TABLE t AS SELECT * FROM analytics.core.src`, contains: []string{"OR REPLACE", "TEMP", "ducklake.core.src"}, - excludes: "portola.core.src", + excludes: "analytics.core.src", }, { name: "plain column-def form (no AS) rewrites target", - input: `CREATE OR REPLACE TABLE portola.core.t (id INTEGER)`, + input: `CREATE OR REPLACE TABLE analytics.core.t (id INTEGER)`, contains: []string{"CREATE OR REPLACE TABLE", "ducklake.core.t"}, - excludes: "portola", + excludes: "analytics", }, } - tr := New(Config{DuckLakeMode: true, LogicalDatabaseName: "portola", PhysicalCatalogName: "ducklake"}) + tr := New(Config{DuckLakeMode: true, LogicalDatabaseName: "analytics", PhysicalCatalogName: "ducklake"}) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -515,8 +515,8 @@ func TestTranspile_CreateOrReplaceTable_LogicalCatalog(t *testing.T) { // CREATE OR REPLACE VIEW is valid PostgreSQL and must NOT be touched by the // CREATE OR REPLACE TABLE interceptor. func TestTranspile_CreateOrReplaceView_Unaffected(t *testing.T) { - tr := New(Config{DuckLakeMode: true, LogicalDatabaseName: "portola", PhysicalCatalogName: "ducklake"}) - result, err := tr.Transpile(`CREATE OR REPLACE VIEW portola.core.v AS SELECT * FROM portola.core.t`) + tr := New(Config{DuckLakeMode: true, LogicalDatabaseName: "analytics", PhysicalCatalogName: "ducklake"}) + result, err := tr.Transpile(`CREATE OR REPLACE VIEW analytics.core.v AS SELECT * FROM analytics.core.t`) if err != nil { t.Fatalf("Transpile error: %v", err) } @@ -526,8 +526,8 @@ func TestTranspile_CreateOrReplaceView_Unaffected(t *testing.T) { if !strings.Contains(result.SQL, "ducklake.core.v") || !strings.Contains(result.SQL, "ducklake.core.t") { t.Errorf("view logical catalog not rewritten: %q", result.SQL) } - if strings.Contains(result.SQL, "portola") { - t.Errorf("portola should have been rewritten away: %q", result.SQL) + if strings.Contains(result.SQL, "analytics") { + t.Errorf("logical catalog should have been rewritten away: %q", result.SQL) } }