Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
read only
  • Loading branch information
kyleconroy committed Apr 4, 2024
commit 945e2513879dff21912a414ccb8fd83cd2616c30
9 changes: 1 addition & 8 deletions internal/endtoend/endtoend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,6 @@ func TestReplay(t *testing.T) {
"managed-db": {
Mutate: func(t *testing.T, path string) func(*config.Config) {
return func(c *config.Config) {
c.Cloud.Project = "01HAQMMECEYQYKFJN8MP16QC41" // TODO: Read from environment
for i := range c.SQL {
files := []string{}
for _, s := range c.SQL[i].Schema {
Expand All @@ -138,18 +137,12 @@ func TestReplay(t *testing.T) {
// URI: uri,
// }
default:
c.SQL[i].Database = &config.Database{
Managed: true,
}
// pass
}
}
}
},
Enabled: func() bool {
// Return false if no auth token exists
if len(os.Getenv("SQLC_AUTH_TOKEN")) == 0 {
return false
}
if len(os.Getenv("POSTGRESQL_SERVER_URI")) == 0 {
return false
}
Expand Down
88 changes: 52 additions & 36 deletions internal/sqltest/local/postgres.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,21 @@ package local
import (
"context"
"fmt"
"hash/fnv"
"net/url"
"os"
"strings"
"sync"
"testing"

"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgxpool"
"golang.org/x/sync/singleflight"

migrate "github.com/sqlc-dev/sqlc/internal/migrations"
"github.com/sqlc-dev/sqlc/internal/pgx/poolcache"
"github.com/sqlc-dev/sqlc/internal/sql/sqlpath"
)

var postgresPool *pgxpool.Pool
var postgresSync sync.Once
var flight singleflight.Group

func PostgreSQL(t *testing.T, migrations []string) string {
ctx := context.Background()
Expand All @@ -28,65 +28,81 @@ func PostgreSQL(t *testing.T, migrations []string) string {
t.Skip("POSTGRESQL_SERVER_URI is empty")
}

postgresSync.Do(func() {
pool, err := pgxpool.New(ctx, dburi)
if err != nil {
t.Fatal(err)
}
postgresPool = pool
})

if postgresPool == nil {
t.Fatalf("PostgreSQL pool creation failed")
postgresPool, err := poolcache.New(ctx, dburi)
if err != nil {
t.Fatalf("PostgreSQL pool creation failed: %s", err)
}

var seed []string
files, err := sqlpath.Glob(migrations)
if err != nil {
t.Fatal(err)
}

h := fnv.New64()
for _, f := range files {
blob, err := os.ReadFile(f)
if err != nil {
t.Fatal(err)
}
h.Write(blob)
seed = append(seed, migrate.RemoveRollbackStatements(string(blob)))
}

name := fmt.Sprintf("sqlc_test_%x", h.Sum(nil))

uri, err := url.Parse(dburi)
if err != nil {
t.Fatal(err)
}
uri.Path = name

name := fmt.Sprintf("sqlc_test_%s", id())
key := uri.String()

if _, err := postgresPool.Exec(ctx, fmt.Sprintf(`CREATE DATABASE "%s"`, name)); err != nil {
t.Fatal(err)
}
_, err, _ = flight.Do(key, func() (interface{}, error) {
row := postgresPool.QueryRow(ctx,
fmt.Sprintf(`SELECT datname FROM pg_database WHERE datname = '%s'`, name))

uri.Path = name
dropQuery := fmt.Sprintf(`DROP DATABASE IF EXISTS "%s" WITH (FORCE)`, name)
var datname string
if err := row.Scan(&datname); err == nil {
fmt.Println("database already exists", name)
// Database already exists
return nil, nil
}

t.Cleanup(func() {
if _, err := postgresPool.Exec(ctx, dropQuery); err != nil {
t.Fatal(err)
fmt.Println("creating database name", name)
if _, err := postgresPool.Exec(ctx, fmt.Sprintf(`CREATE DATABASE "%s"`, name)); err != nil {
return nil, err
}
})

conn, err := pgx.Connect(ctx, uri.String())
if err != nil {
t.Fatalf("connect %s: %s", name, err)
}
defer conn.Close(ctx)
dropQuery := fmt.Sprintf(`DROP DATABASE IF EXISTS "%s" WITH (FORCE)`, name)

for _, q := range seed {
if len(strings.TrimSpace(q)) == 0 {
continue
cleanup := func() {
if _, err := postgresPool.Exec(ctx, dropQuery); err != nil {
t.Logf("failed cleaning up: %s", err)
}
}
if _, err := conn.Exec(ctx, q); err != nil {
t.Fatalf("%s: %s", q, err)

conn, err := pgx.Connect(ctx, uri.String())
if err != nil {
cleanup()
return nil, fmt.Errorf("connect %s: %s", name, err)
}
defer conn.Close(ctx)

for _, q := range seed {
if len(strings.TrimSpace(q)) == 0 {
continue
}
if _, err := conn.Exec(ctx, q); err != nil {
cleanup()
return nil, fmt.Errorf("%s: %s", q, err)
}
}
return nil, nil
})
if err != nil {
t.Fatalf("create db: %s", err)
}

return uri.String()
return key
}