-
Notifications
You must be signed in to change notification settings - Fork 381
Expand file tree
/
Copy pathtest.go
More file actions
120 lines (114 loc) · 3.14 KB
/
test.go
File metadata and controls
120 lines (114 loc) · 3.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
package test
import (
"context"
_ "embed"
"fmt"
"os"
"path"
"path/filepath"
"sort"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
"github.com/go-errors/errors"
"github.com/jackc/pgconn"
"github.com/jackc/pgerrcode"
"github.com/jackc/pgx/v4"
"github.com/spf13/afero"
"github.com/spf13/viper"
"github.com/supabase/cli/internal/utils"
cliConfig "github.com/supabase/cli/pkg/config"
)
const (
ENABLE_PGTAP = "create extension if not exists pgtap with schema extensions"
DISABLE_PGTAP = "drop extension if exists pgtap"
)
func Run(ctx context.Context, testFiles []string, config pgconn.Config, fsys afero.Fs, options ...func(*pgx.ConnConfig)) error {
// Build test command
if len(testFiles) == 0 {
absTestsDir, err := filepath.Abs(utils.DbTestsDir)
if err != nil {
return errors.Errorf("failed to resolve tests dir: %w", err)
}
testFiles = append(testFiles, absTestsDir)
}
bindsSet := map[string]struct{}{}
cmd := []string{"pg_prove", "--ext", ".pg", "--ext", ".sql", "-r"}
var workingDir string
for _, fp := range testFiles {
if !filepath.IsAbs(fp) {
fp = filepath.Join(utils.CurrentDirAbs, fp)
}
dockerPath := utils.ToDockerPath(fp)
cmd = append(cmd, dockerPath)
hostDir := fp
dockerDir := dockerPath
if path.Ext(dockerPath) != "" {
hostDir = filepath.Dir(fp)
dockerDir = path.Dir(dockerPath)
}
bindsSet[fmt.Sprintf("%s:%s:ro", hostDir, dockerDir)] = struct{}{}
if workingDir == "" {
workingDir = dockerDir
}
}
binds := make([]string, 0, len(bindsSet))
for b := range bindsSet {
binds = append(binds, b)
}
sort.Strings(binds)
if viper.GetBool("DEBUG") {
cmd = append(cmd, "--verbose")
}
// Enable pgTAP if not already exists
alreadyExists := false
options = append(options, func(cc *pgx.ConnConfig) {
cc.OnNotice = func(pc *pgconn.PgConn, n *pgconn.Notice) {
alreadyExists = n.Code == pgerrcode.DuplicateObject
}
})
conn, err := utils.ConnectByConfig(ctx, config, options...)
if err != nil {
return err
}
defer conn.Close(context.Background())
if _, err := conn.Exec(ctx, ENABLE_PGTAP); err != nil {
return errors.Errorf("failed to enable pgTAP: %w", err)
}
if !alreadyExists {
defer func() {
if _, err := conn.Exec(ctx, DISABLE_PGTAP); err != nil {
fmt.Fprintln(os.Stderr, "failed to disable pgTAP:", err)
}
}()
}
// Use custom network when connecting to local database
// disable selinux via security-opt to allow pg-tap to work properly
hostConfig := container.HostConfig{Binds: binds, SecurityOpt: []string{"label:disable"}}
if utils.IsLocalDatabase(config) {
config.Host = utils.DbAliases[0]
config.Port = 5432
} else {
hostConfig.NetworkMode = network.NetworkHost
}
// Run pg_prove on volume mount
return utils.DockerRunOnceWithConfig(
ctx,
container.Config{
Image: cliConfig.Images.PgProve,
Env: []string{
"PGHOST=" + config.Host,
fmt.Sprintf("PGPORT=%d", config.Port),
"PGUSER=" + config.User,
"PGPASSWORD=" + config.Password,
"PGDATABASE=" + config.Database,
},
Cmd: cmd,
WorkingDir: workingDir,
},
hostConfig,
network.NetworkingConfig{},
"",
os.Stdout,
os.Stderr,
)
}