Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit99ca13b

Browse files
committed
tests: refactor dbtestutil to record database creation
1 parentf5fac29 commit99ca13b

File tree

3 files changed

+254
-133
lines changed

3 files changed

+254
-133
lines changed
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
package dbtestutil
2+
3+
import (
4+
"database/sql"
5+
_"embed"
6+
"fmt"
7+
"os"
8+
"sync"
9+
"time"
10+
11+
"github.com/lib/pq"
12+
"golang.org/x/xerrors"
13+
14+
"github.com/coder/coder/v2/cryptorand"
15+
"github.com/google/uuid"
16+
)
17+
18+
constCoderTestingDBName="coder_testing"
19+
20+
//go:embed coder_testing.sql
21+
varcoderTestingSQLInitstring
22+
23+
typeBrokerstruct {
24+
sync.Mutex
25+
uuid uuid.UUID
26+
coderTestingDB*sql.DB
27+
refCountint
28+
}
29+
30+
func (b*Broker)Create(tTBSubset,opts...OpenOption) (ConnectionParams,error) {
31+
iferr:=b.init(t);err!=nil {
32+
returnConnectionParams{},err
33+
}
34+
openOptions:=OpenOptions{}
35+
for_,opt:=rangeopts {
36+
opt(&openOptions)
37+
}
38+
39+
var (
40+
username=defaultConnectionParams.Username
41+
password=defaultConnectionParams.Password
42+
host=defaultConnectionParams.Host
43+
port=defaultConnectionParams.Port
44+
)
45+
46+
// Use a time-based prefix to make it easier to find the database
47+
// when debugging.
48+
now:=time.Now().Format("test_2006_01_02_15_04_05")
49+
dbSuffix,err:=cryptorand.StringCharset(cryptorand.Lower,10)
50+
iferr!=nil {
51+
returnConnectionParams{},xerrors.Errorf("generate db suffix: %w",err)
52+
}
53+
dbName:=now+"_"+dbSuffix
54+
55+
// TODO: add package and test name
56+
_,err=b.coderTestingDB.Exec(
57+
"INSERT INTO test_databases (name, process_uuid) VALUES ($1, $2)",dbName,b.uuid)
58+
iferr!=nil {
59+
returnConnectionParams{},xerrors.Errorf("insert test_database row: %w",err)
60+
}
61+
62+
// if empty createDatabaseFromTemplate will create a new template db
63+
templateDBName:=os.Getenv("DB_FROM")
64+
ifopenOptions.DBFrom!=nil {
65+
templateDBName=*openOptions.DBFrom
66+
}
67+
iferr=createDatabaseFromTemplate(t,defaultConnectionParams,b.coderTestingDB,dbName,templateDBName);err!=nil {
68+
returnConnectionParams{},xerrors.Errorf("create database: %w",err)
69+
}
70+
71+
testDBParams:=ConnectionParams{
72+
Username:username,
73+
Password:password,
74+
Host:host,
75+
Port:port,
76+
DBName:dbName,
77+
}
78+
79+
// Optionally log the DSN to help connect to the test database.
80+
ifopenOptions.LogDSN {
81+
_,_=fmt.Fprintf(os.Stderr,"Connect to the database for %s using: psql '%s'\n",t.Name(),testDBParams.DSN())
82+
}
83+
t.Cleanup(b.clean(t,dbName))
84+
returntestDBParams,nil
85+
}
86+
87+
func (b*Broker)clean(tTBSubset,dbNamestring)func() {
88+
returnfunc() {
89+
_,err:=b.coderTestingDB.Exec("DROP DATABASE "+dbName+";")
90+
iferr!=nil {
91+
t.Logf("failed to clean up database %q: %s\n",dbName,err.Error())
92+
return
93+
}
94+
_,err=b.coderTestingDB.Exec("UPDATE test_databases SET dropped_at = CURRENT_TIMESTAMP WHERE name = $1",dbName)
95+
iferr!=nil {
96+
t.Logf("failed to mark test database '%s' dropped: %s\n",dbName,err.Error())
97+
}
98+
}
99+
}
100+
101+
func (b*Broker)init(tTBSubset)error {
102+
b.Lock()
103+
deferb.Unlock()
104+
b.refCount++
105+
t.Cleanup(b.decRef)
106+
ifb.coderTestingDB!=nil {
107+
// already initialized
108+
returnnil
109+
}
110+
111+
connectionParamsInitOnce.Do(func() {
112+
errDefaultConnectionParamsInit=initDefaultConnection(t)
113+
})
114+
iferrDefaultConnectionParamsInit!=nil {
115+
returnxerrors.Errorf("init default connection params: %w",errDefaultConnectionParamsInit)
116+
}
117+
coderTestingParams:=defaultConnectionParams
118+
coderTestingParams.DBName=CoderTestingDBName
119+
coderTestingDB,err:=sql.Open("postgres",coderTestingParams.DSN())
120+
iferr!=nil {
121+
returnxerrors.Errorf("open postgres connection: %w",err)
122+
}
123+
124+
// creating the db can succeed even if the database doesn't exist. Ping it to find out.
125+
err=coderTestingDB.Ping()
126+
varpqErr*pq.Error
127+
ifxerrors.As(err,&pqErr)&&pqErr.Code=="3D000" {
128+
// database does not exist.
129+
err=b.createCoderTestingDB(t)
130+
iferr!=nil {
131+
returnxerrors.Errorf("create coder testing db: %w",err)
132+
}
133+
coderTestingDB,err=sql.Open("postgres",coderTestingParams.DSN())
134+
iferr!=nil {
135+
returnxerrors.Errorf("open postgres connection: %w",err)
136+
}
137+
}elseiferr!=nil {
138+
returnxerrors.Errorf("ping '%s' database: %w",CoderTestingDBName,err)
139+
}
140+
b.coderTestingDB=coderTestingDB
141+
b.uuid=uuid.New()
142+
returnnil
143+
}
144+
145+
func (b*Broker)createCoderTestingDB(tTBSubset)error {
146+
db,err:=sql.Open("postgres",defaultConnectionParams.DSN())
147+
iferr!=nil {
148+
returnxerrors.Errorf("open postgres connection: %w",err)
149+
}
150+
deferfunc() {
151+
_=db.Close()
152+
}()
153+
err=createAndInitDatabase(t,defaultConnectionParams,db,CoderTestingDBName,func(testDB*sql.DB)error {
154+
_,err:=testDB.Exec(coderTestingSQLInit)
155+
returnerr
156+
})
157+
iferr!=nil {
158+
returnxerrors.Errorf("create coder testing db: %w",err)
159+
}
160+
returnnil
161+
}
162+
163+
func (b*Broker)decRef() {
164+
b.Lock()
165+
deferb.Unlock()
166+
b.refCount--
167+
ifb.refCount==0 {
168+
// ensures we don't leave go routines around for GoLeak to find.
169+
_=b.coderTestingDB.Close()
170+
b.coderTestingDB=nil
171+
}
172+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
CREATETABLEIF NOT EXISTS test_databases (
2+
nametextPRIMARY KEY,
3+
created_attimestamp with time zoneNOT NULL DEFAULTCURRENT_TIMESTAMP,
4+
dropped_attimestamp with time zone,-- null means it hasn't been dropped
5+
process_uuid uuidNOT NULL,
6+
-- these are both unused for now, but we'd like to include them for statistics later
7+
test_packagetext,
8+
test_nametext
9+
);
10+
11+
CREATEINDEXIF NOT EXISTS test_databases_process_uuidON test_databases (process_uuid, dropped_at);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp