Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions controlplane/admin/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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")
}
Expand Down Expand Up @@ -1304,23 +1304,23 @@ 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)

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)
}
Expand Down Expand Up @@ -1398,23 +1398,23 @@ 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)

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)
}
Expand Down
28 changes: 14 additions & 14 deletions controlplane/configstore/store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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" {
Expand All @@ -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",
},
},
}
Expand All @@ -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", "", ""},
Expand Down
2 changes: 1 addition & 1 deletion controlplane/k8s_pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1789,7 +1789,7 @@ func TestK8sPoolReserveSharedWorkerSkipsWarmWorkerWithMismatchedImageWithoutRunt
}

worker, err := pool.ReserveSharedWorker(context.Background(), &WorkerAssignment{
OrgID: "portola",
OrgID: "tenant-alpha",
Image: pinnedImage,
MaxWorkers: 2,
})
Expand Down
2 changes: 1 addition & 1 deletion duckdbservice/arrow_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion duckdbservice/progress.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
39 changes: 39 additions & 0 deletions repository_hygiene_test.go
Original file line number Diff line number Diff line change
@@ -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, ", "))
}
}
2 changes: 1 addition & 1 deletion server/conn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down
4 changes: 2 additions & 2 deletions transpiler/create_or_replace.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
//
Expand Down
32 changes: 16 additions & 16 deletions transpiler/transpiler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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) {
Expand All @@ -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)
}
Expand All @@ -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)
}
}

Expand Down
Loading