@@ -6,11 +6,17 @@ import (
6
6
"fmt"
7
7
"log"
8
8
"os"
9
+ "strings"
9
10
"time"
10
11
11
12
_ "github.com/googleapis/go-sql-spanner" // Spanner driver
12
13
"github.com/ory/dockertest/v3"
13
14
"github.com/ory/dockertest/v3/docker"
15
+
16
+ database "cloud.google.com/go/spanner/admin/database/apiv1"
17
+ dbpb "cloud.google.com/go/spanner/admin/database/apiv1/databasepb"
18
+ instance "cloud.google.com/go/spanner/admin/instance/apiv1"
19
+ inspb "cloud.google.com/go/spanner/admin/instance/apiv1/instancepb"
14
20
)
15
21
16
22
const (
@@ -22,7 +28,6 @@ const (
22
28
SPANNER_DATABASE = "test-db"
23
29
)
24
30
25
- // newSpanner spins up a Cloud Spanner emulator and connects to it using the Go SQL driver.
26
31
func newSpanner (opts ... OptionsFunc ) (* sql.DB , func (), error ) {
27
32
option := & options {}
28
33
for _ , f := range opts {
@@ -39,7 +44,7 @@ func newSpanner(opts ...OptionsFunc) (*sql.DB, func(), error) {
39
44
Repository : SPANNER_IMAGE ,
40
45
Tag : SPANNER_VERSION ,
41
46
ExposedPorts : []string {
42
- "9010/tcp" ,
47
+ "9010/tcp" , "9020/tcp" ,
43
48
},
44
49
Labels : map [string ]string {"goose_test" : "1" },
45
50
},
@@ -54,27 +59,28 @@ func newSpanner(opts ...OptionsFunc) (*sql.DB, func(), error) {
54
59
55
60
hostPort := resource .GetPort ("9010/tcp" )
56
61
emulatorHost := fmt .Sprintf ("localhost:%s" , hostPort )
57
-
58
- // Set environment variable so that the Spanner driver connects to the emulator.
59
62
os .Setenv ("SPANNER_EMULATOR_HOST" , emulatorHost )
60
63
61
- // Use gcloud CLI or spanner admin client to create instance & database.
64
+ // Provision instance + database inside emulator
62
65
err = pool .Retry (func () error {
63
- ctx , cancel := context .WithTimeout (context .Background (), 10 * time .Second )
66
+ ctx , cancel := context .WithTimeout (context .Background (), 20 * time .Second )
64
67
defer cancel ()
65
68
69
+ if err := createSpannerResources (ctx ); err != nil {
70
+ return err
71
+ }
72
+
66
73
dsn := fmt .Sprintf ("projects/%s/instances/%s/databases/%s" , SPANNER_PROJECT , SPANNER_INSTANCE , SPANNER_DATABASE )
67
74
db , err := sql .Open ("spanner" , dsn )
68
75
if err != nil {
69
76
return err
70
77
}
71
78
defer db .Close ()
72
-
73
79
return db .PingContext (ctx )
74
80
})
75
81
if err != nil {
76
82
_ = pool .Purge (resource )
77
- return nil , nil , fmt .Errorf ("could not ping spanner emulator: %v" , err )
83
+ return nil , nil , fmt .Errorf ("could not initialize spanner emulator: %v" , err )
78
84
}
79
85
80
86
dsn := fmt .Sprintf ("projects/%s/instances/%s/databases/%s" , SPANNER_PROJECT , SPANNER_INSTANCE , SPANNER_DATABASE )
@@ -94,3 +100,42 @@ func newSpanner(opts ...OptionsFunc) (*sql.DB, func(), error) {
94
100
95
101
return db , cleanup , nil
96
102
}
103
+
104
+ func createSpannerResources (ctx context.Context ) error {
105
+ instClient , err := instance .NewInstanceAdminClient (ctx )
106
+ if err != nil {
107
+ return fmt .Errorf ("create instance client failed: %w" , err )
108
+ }
109
+ defer instClient .Close ()
110
+
111
+ dbClient , err := database .NewDatabaseAdminClient (ctx )
112
+ if err != nil {
113
+ return fmt .Errorf ("create database client failed: %w" , err )
114
+ }
115
+ defer dbClient .Close ()
116
+
117
+ instReq := & inspb.CreateInstanceRequest {
118
+ Parent : "projects/" + SPANNER_PROJECT ,
119
+ InstanceId : SPANNER_INSTANCE ,
120
+ Instance : & inspb.Instance {
121
+ Config : "projects/" + SPANNER_PROJECT + "/instanceConfigs/emulator-config" ,
122
+ DisplayName : "Test Instance" ,
123
+ NodeCount : 1 ,
124
+ },
125
+ }
126
+ if _ , err = instClient .CreateInstance (ctx , instReq ); err != nil &&
127
+ ! strings .Contains (err .Error (), "AlreadyExists" ) {
128
+ return fmt .Errorf ("create instance failed: %w" , err )
129
+ }
130
+
131
+ dbReq := & dbpb.CreateDatabaseRequest {
132
+ Parent : fmt .Sprintf ("projects/%s/instances/%s" , SPANNER_PROJECT , SPANNER_INSTANCE ),
133
+ CreateStatement : "CREATE DATABASE `" + SPANNER_DATABASE + "`" ,
134
+ }
135
+ if _ , err = dbClient .CreateDatabase (ctx , dbReq ); err != nil &&
136
+ ! strings .Contains (err .Error (), "AlreadyExists" ) {
137
+ return fmt .Errorf ("create database failed: %w" , err )
138
+ }
139
+
140
+ return nil
141
+ }
0 commit comments