github.com/supabase/cli@v1.168.1/internal/db/test/test.go (about) 1 package test 2 3 import ( 4 "context" 5 _ "embed" 6 "fmt" 7 "os" 8 "path/filepath" 9 10 "github.com/docker/docker/api/types/container" 11 "github.com/docker/docker/api/types/network" 12 "github.com/go-errors/errors" 13 "github.com/jackc/pgconn" 14 "github.com/jackc/pgerrcode" 15 "github.com/jackc/pgx/v4" 16 "github.com/spf13/afero" 17 "github.com/spf13/viper" 18 "github.com/supabase/cli/internal/utils" 19 ) 20 21 const ( 22 ENABLE_PGTAP = "create extension if not exists pgtap with schema extensions" 23 DISABLE_PGTAP = "drop extension if exists pgtap" 24 ) 25 26 func Run(ctx context.Context, testFiles []string, config pgconn.Config, fsys afero.Fs, options ...func(*pgx.ConnConfig)) error { 27 // Build test command 28 cmd := []string{"pg_prove", "--ext", ".pg", "--ext", ".sql", "-r"} 29 for _, fp := range testFiles { 30 relPath, err := filepath.Rel(utils.DbTestsDir, fp) 31 if err != nil { 32 return errors.Errorf("failed to resolve relative path: %w", err) 33 } 34 cmd = append(cmd, relPath) 35 } 36 if viper.GetBool("DEBUG") { 37 cmd = append(cmd, "--verbose") 38 } 39 // Mount tests directory into container as working directory 40 srcPath, err := filepath.Abs(utils.DbTestsDir) 41 if err != nil { 42 return errors.Errorf("failed to resolve absolute path: %w", err) 43 } 44 dstPath := "/tmp" 45 binds := []string{fmt.Sprintf("%s:%s:ro,z", srcPath, dstPath)} 46 // Enable pgTAP if not already exists 47 alreadyExists := false 48 options = append(options, func(cc *pgx.ConnConfig) { 49 cc.OnNotice = func(pc *pgconn.PgConn, n *pgconn.Notice) { 50 alreadyExists = n.Code == pgerrcode.DuplicateObject 51 } 52 }) 53 conn, err := utils.ConnectByConfig(ctx, config, options...) 54 if err != nil { 55 return err 56 } 57 defer conn.Close(context.Background()) 58 if _, err := conn.Exec(ctx, ENABLE_PGTAP); err != nil { 59 return errors.Errorf("failed to enable pgTAP: %w", err) 60 } 61 if !alreadyExists { 62 defer func() { 63 if _, err := conn.Exec(ctx, DISABLE_PGTAP); err != nil { 64 fmt.Fprintln(os.Stderr, "failed to disable pgTAP:", err) 65 } 66 }() 67 } 68 // Use custom network when connecting to local database 69 networkID := "host" 70 if utils.IsLocalDatabase(config) { 71 config.Host = utils.DbAliases[0] 72 config.Port = 5432 73 networkID = utils.NetId 74 } 75 // Run pg_prove on volume mount 76 return utils.DockerRunOnceWithConfig( 77 ctx, 78 container.Config{ 79 Image: utils.PgProveImage, 80 Env: []string{ 81 "PGHOST=" + config.Host, 82 fmt.Sprintf("PGPORT=%d", config.Port), 83 "PGUSER=" + config.User, 84 "PGPASSWORD=" + config.Password, 85 "PGDATABASE=" + config.Database, 86 }, 87 Cmd: cmd, 88 WorkingDir: dstPath, 89 }, 90 container.HostConfig{ 91 NetworkMode: container.NetworkMode(networkID), 92 Binds: binds, 93 }, 94 network.NetworkingConfig{}, 95 "", 96 os.Stdout, 97 os.Stderr, 98 ) 99 }