Skip to content

Commit a113b67

Browse files
authored
feat(examples): Use hosted MySQL databases for tests (#2982)
* feat(examples): Use hosted MySQL databases for tests * Switch to managed mode for more examples
1 parent 66ada0a commit a113b67

File tree

14 files changed

+170
-68
lines changed

14 files changed

+170
-68
lines changed

.github/workflows/ci.yml

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,6 @@ jobs:
3131
name: test
3232
runs-on: ubuntu-latest
3333

34-
services:
35-
mysql:
36-
image: "mysql/mysql-server:8.0"
37-
env:
38-
MYSQL_DATABASE: mysql
39-
MYSQL_ROOT_HOST: '%'
40-
MYSQL_ROOT_PASSWORD: mysecretpassword
41-
ports:
42-
- 3306:3306
43-
4434
steps:
4535
- uses: actions/checkout@v4
4636
- uses: actions/setup-go@v4
@@ -64,10 +54,6 @@ jobs:
6454
- name: test ./...
6555
run: gotestsum --junitfile junit.xml -- --tags=examples -timeout 20m ./...
6656
env:
67-
MYSQL_DATABASE: mysql
68-
MYSQL_HOST: localhost
69-
MYSQL_PORT: ${{ job.services.mysql.ports['3306'] }}
70-
MYSQL_ROOT_PASSWORD: mysecretpassword
7157
CI_SQLC_PROJECT_ID: ${{ secrets.CI_SQLC_PROJECT_ID }}
7258
CI_SQLC_AUTH_TOKEN: ${{ secrets.CI_SQLC_AUTH_TOKEN }}
7359
SQLC_AUTH_TOKEN: ${{ secrets.CI_SQLC_AUTH_TOKEN }}

examples/authors/mysql/db_test.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,20 @@ import (
88
"database/sql"
99
"testing"
1010

11-
"github.com/sqlc-dev/sqlc/internal/sqltest"
11+
_ "github.com/go-sql-driver/mysql"
12+
13+
"github.com/sqlc-dev/sqlc/internal/sqltest/hosted"
1214
)
1315

1416
func TestAuthors(t *testing.T) {
15-
sdb, cleanup := sqltest.MySQL(t, []string{"schema.sql"})
16-
defer cleanup()
17-
1817
ctx := context.Background()
18+
uri := hosted.MySQL(t, []string{"schema.sql"})
19+
sdb, err := sql.Open("mysql", uri)
20+
if err != nil {
21+
t.Fatal(err)
22+
}
23+
defer sdb.Close()
24+
1925
db := New(sdb)
2026

2127
// list all authors

examples/authors/sqlc.yaml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ version: '2'
22
cloud:
33
project: "01HAQMMECEYQYKFJN8MP16QC41"
44
sql:
5-
- schema: postgresql/schema.sql
5+
- name: postgresql
6+
schema: postgresql/schema.sql
67
queries: postgresql/query.sql
78
engine: postgresql
89
database:
@@ -17,19 +18,21 @@ sql:
1718
package: authors
1819
sql_package: pgx/v5
1920
out: postgresql
20-
- schema: mysql/schema.sql
21+
- name: mysql
22+
schema: mysql/schema.sql
2123
queries: mysql/query.sql
2224
engine: mysql
2325
database:
24-
uri: root:${MYSQL_ROOT_PASSWORD}@tcp(${MYSQL_HOST}:${MYSQL_PORT})/authors?multiStatements=true&parseTime=true
26+
managed: true
2527
rules:
2628
- sqlc/db-prepare
2729
# - mysql-query-too-costly
2830
gen:
2931
go:
3032
package: authors
3133
out: mysql
32-
- schema: sqlite/schema.sql
34+
- name: sqlite
35+
schema: sqlite/schema.sql
3336
queries: sqlite/query.sql
3437
engine: sqlite
3538
database:

examples/booktest/mysql/db_test.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,24 @@ package booktest
55

66
import (
77
"context"
8+
"database/sql"
89
"testing"
910
"time"
1011

11-
"github.com/sqlc-dev/sqlc/internal/sqltest"
12+
_ "github.com/go-sql-driver/mysql"
13+
14+
"github.com/sqlc-dev/sqlc/internal/sqltest/hosted"
1215
)
1316

1417
func TestBooks(t *testing.T) {
15-
db, cleanup := sqltest.MySQL(t, []string{"schema.sql"})
16-
defer cleanup()
17-
1818
ctx := context.Background()
19+
uri := hosted.MySQL(t, []string{"schema.sql"})
20+
db, err := sql.Open("mysql", uri)
21+
if err != nil {
22+
t.Fatal(err)
23+
}
24+
defer db.Close()
25+
1926
dq := New(db)
2027

2128
// create an author

examples/booktest/sqlc.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
"queries": "mysql/query.sql",
2929
"engine": "mysql",
3030
"database": {
31-
"uri": "root:${MYSQL_ROOT_PASSWORD}@tcp(${MYSQL_HOST}:${MYSQL_PORT})/booktest?multiStatements=true&parseTime=true"
31+
"managed": true
3232
},
3333
"rules": [
3434
"sqlc/db-prepare"

examples/ondeck/mysql/db_test.go

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ import (
99
"strings"
1010
"testing"
1111

12-
"github.com/sqlc-dev/sqlc/internal/sqltest"
13-
12+
_ "github.com/go-sql-driver/mysql"
1413
"github.com/google/go-cmp/cmp"
14+
15+
"github.com/sqlc-dev/sqlc/internal/sqltest/hosted"
1516
)
1617

1718
func join(vals ...string) sql.NullString {
@@ -143,10 +144,14 @@ func runOnDeckQueries(t *testing.T, q *Queries) {
143144
func TestPrepared(t *testing.T) {
144145
t.Parallel()
145146

146-
sdb, cleanup := sqltest.MySQL(t, []string{"schema"})
147-
defer cleanup()
147+
uri := hosted.MySQL(t, []string{"schema"})
148+
db, err := sql.Open("mysql", uri)
149+
if err != nil {
150+
t.Fatal(err)
151+
}
152+
defer db.Close()
148153

149-
q, err := Prepare(context.Background(), sdb)
154+
q, err := Prepare(context.Background(), db)
150155
if err != nil {
151156
t.Fatal(err)
152157
}
@@ -157,8 +162,12 @@ func TestPrepared(t *testing.T) {
157162
func TestQueries(t *testing.T) {
158163
t.Parallel()
159164

160-
sdb, cleanup := sqltest.MySQL(t, []string{"schema"})
161-
defer cleanup()
165+
uri := hosted.MySQL(t, []string{"schema"})
166+
db, err := sql.Open("mysql", uri)
167+
if err != nil {
168+
t.Fatal(err)
169+
}
170+
defer db.Close()
162171

163-
runOnDeckQueries(t, New(sdb))
172+
runOnDeckQueries(t, New(db))
164173
}

examples/ondeck/sqlc.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
"queries": "mysql/query",
3232
"engine": "mysql",
3333
"database": {
34-
"uri": "root:${MYSQL_ROOT_PASSWORD}@tcp(${MYSQL_HOST}:${MYSQL_PORT})/ondeck?multiStatements=true&parseTime=true"
34+
"managed": true
3535
},
3636
"rules": [
3737
"sqlc/db-prepare"

internal/cmd/vet.go

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -404,10 +404,6 @@ func (c *checker) fetchDatabaseUri(ctx context.Context, s config.SQL) (string, f
404404
return uri, cleanup, err
405405
}
406406

407-
if s.Engine != config.EnginePostgreSQL {
408-
return "", cleanup, fmt.Errorf("managed: only PostgreSQL currently")
409-
}
410-
411407
if c.Client == nil {
412408
// FIXME: Eventual race condition
413409
client, err := quickdb.NewClientFromConfig(c.Conf.Cloud)
@@ -431,7 +427,7 @@ func (c *checker) fetchDatabaseUri(ctx context.Context, s config.SQL) (string, f
431427
}
432428

433429
resp, err := c.Client.CreateEphemeralDatabase(ctx, &pb.CreateEphemeralDatabaseRequest{
434-
Engine: "postgresql",
430+
Engine: string(s.Engine),
435431
Region: quickdb.GetClosestRegion(),
436432
Migrations: ddl,
437433
})
@@ -446,7 +442,19 @@ func (c *checker) fetchDatabaseUri(ctx context.Context, s config.SQL) (string, f
446442
return err
447443
}
448444

449-
return resp.Uri, cleanup, nil
445+
var uri string
446+
switch s.Engine {
447+
case config.EngineMySQL:
448+
dburi, err := quickdb.MySQLReformatURI(resp.Uri)
449+
if err != nil {
450+
return "", cleanup, fmt.Errorf("reformat uri: %w", err)
451+
}
452+
uri = dburi
453+
default:
454+
uri = resp.Uri
455+
}
456+
457+
return uri, cleanup, nil
450458
}
451459

452460
func (c *checker) DSN(dsn string) (string, error) {

internal/endtoend/vet_test.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,6 @@ func TestExamplesVet(t *testing.T) {
5656
path := filepath.Join(examples, tc)
5757

5858
if tc != "kotlin" && tc != "python" {
59-
if s, found := findSchema(t, filepath.Join(path, "mysql")); found {
60-
db, cleanup := sqltest.CreateMySQLDatabase(t, tc, []string{s})
61-
defer db.Close()
62-
defer cleanup()
63-
}
6459
if s, found := findSchema(t, filepath.Join(path, "sqlite")); found {
6560
dsn := fmt.Sprintf("file:%s?mode=memory&cache=shared", tc)
6661
db, cleanup := sqltest.CreateSQLiteDatabase(t, dsn, []string{s})

internal/quickdb/mysql.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package quickdb
2+
3+
import (
4+
"fmt"
5+
"net/url"
6+
)
7+
8+
// The database URI returned by the QuickDB service isn't understood by the
9+
// go-mysql-driver
10+
func MySQLReformatURI(original string) (string, error) {
11+
u, err := url.Parse(original)
12+
if err != nil {
13+
return "", err
14+
}
15+
return fmt.Sprintf("%s@tcp(%s)%s?multiStatements=true&parseTime=true&tls=true", u.User, u.Host, u.Path), nil
16+
}

internal/sqltest/hosted/client.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package hosted
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"sync"
7+
8+
"github.com/sqlc-dev/sqlc/internal/quickdb"
9+
pb "github.com/sqlc-dev/sqlc/internal/quickdb/v1"
10+
)
11+
12+
var client pb.QuickClient
13+
var once sync.Once
14+
15+
func initClient() error {
16+
projectID := os.Getenv("CI_SQLC_PROJECT_ID")
17+
authToken := os.Getenv("CI_SQLC_AUTH_TOKEN")
18+
if projectID == "" || authToken == "" {
19+
return fmt.Errorf("missing project id or auth token")
20+
}
21+
c, err := quickdb.NewClient(projectID, authToken)
22+
if err != nil {
23+
return err
24+
}
25+
client = c
26+
return nil
27+
}

internal/sqltest/hosted/mysql.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package hosted
2+
3+
import (
4+
"context"
5+
"os"
6+
"testing"
7+
8+
"github.com/sqlc-dev/sqlc/internal/quickdb"
9+
pb "github.com/sqlc-dev/sqlc/internal/quickdb/v1"
10+
"github.com/sqlc-dev/sqlc/internal/sql/sqlpath"
11+
)
12+
13+
func MySQL(t *testing.T, migrations []string) string {
14+
ctx := context.Background()
15+
t.Helper()
16+
17+
once.Do(func() {
18+
if err := initClient(); err != nil {
19+
t.Log(err)
20+
}
21+
})
22+
23+
if client == nil {
24+
t.Skip("client init failed")
25+
}
26+
27+
var seed []string
28+
files, err := sqlpath.Glob(migrations)
29+
if err != nil {
30+
t.Fatal(err)
31+
}
32+
for _, f := range files {
33+
blob, err := os.ReadFile(f)
34+
if err != nil {
35+
t.Fatal(err)
36+
}
37+
seed = append(seed, string(blob))
38+
}
39+
40+
resp, err := client.CreateEphemeralDatabase(ctx, &pb.CreateEphemeralDatabaseRequest{
41+
Engine: "mysql",
42+
Region: quickdb.GetClosestRegion(),
43+
Migrations: seed,
44+
})
45+
if err != nil {
46+
t.Fatalf("region %s: %s", quickdb.GetClosestRegion(), err)
47+
}
48+
49+
t.Cleanup(func() {
50+
_, err = client.DropEphemeralDatabase(ctx, &pb.DropEphemeralDatabaseRequest{
51+
DatabaseId: resp.DatabaseId,
52+
})
53+
if err != nil {
54+
t.Fatal(err)
55+
}
56+
})
57+
58+
uri, err := quickdb.MySQLReformatURI(resp.Uri)
59+
if err != nil {
60+
t.Fatalf("uri error: %s", err)
61+
}
62+
63+
return uri
64+
}

internal/sqltest/hosted/db.go renamed to internal/sqltest/hosted/postgres.go

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,14 @@ package hosted
22

33
import (
44
"context"
5-
"fmt"
65
"os"
7-
"sync"
86
"testing"
97

108
"github.com/sqlc-dev/sqlc/internal/quickdb"
119
pb "github.com/sqlc-dev/sqlc/internal/quickdb/v1"
1210
"github.com/sqlc-dev/sqlc/internal/sql/sqlpath"
1311
)
1412

15-
var client pb.QuickClient
16-
var once sync.Once
17-
18-
func initClient() error {
19-
projectID := os.Getenv("CI_SQLC_PROJECT_ID")
20-
authToken := os.Getenv("CI_SQLC_AUTH_TOKEN")
21-
if projectID == "" || authToken == "" {
22-
return fmt.Errorf("missing project id or auth token")
23-
}
24-
c, err := quickdb.NewClient(projectID, authToken)
25-
if err != nil {
26-
return err
27-
}
28-
client = c
29-
return nil
30-
}
31-
3213
func PostgreSQL(t *testing.T, migrations []string) string {
3314
ctx := context.Background()
3415
t.Helper()

internal/sqltest/mysql.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ import (
77
"path/filepath"
88
"testing"
99

10-
"github.com/sqlc-dev/sqlc/internal/sql/sqlpath"
11-
1210
_ "github.com/go-sql-driver/mysql"
11+
12+
"github.com/sqlc-dev/sqlc/internal/sql/sqlpath"
1313
)
1414

1515
func MySQL(t *testing.T, migrations []string) (*sql.DB, func()) {

0 commit comments

Comments
 (0)