@@ -6,6 +6,7 @@ package datastore
66import (
77 "context"
88 "fmt"
9+ "sync"
910 "testing"
1011
1112 "github.com/google/uuid"
@@ -24,15 +25,19 @@ const (
2425 enableRangefeeds = `SET CLUSTER SETTING kv.rangefeed.enabled = true;`
2526)
2627
28+ // crdbTester is safe for concurrent use by tests.
2729type crdbTester struct {
28- conn * pgx.Conn
29- hostname string
30- creds string
31- port string
30+ conn * pgx.Conn // GUARDED_BY(connMutex)
31+ connMutex sync.Mutex
32+ hostname string
33+ creds string
34+ port string
3235}
3336
37+ var _ RunningEngineForTest = (* crdbTester )(nil )
38+
3439// RunCRDBForTesting returns a RunningEngineForTest for CRDB
35- func RunCRDBForTesting (t testing.TB , bridgeNetworkName string , crdbVersion string ) RunningEngineForTest {
40+ func RunCRDBForTesting (t testing.TB , bridgeNetworkName string , crdbVersion string ) * crdbTester {
3641 pool , err := dockertest .NewPool ("" )
3742 require .NoError (t , err )
3843
@@ -55,6 +60,8 @@ func RunCRDBForTesting(t testing.TB, bridgeNetworkName string, crdbVersion strin
5560 creds : "root:fake" ,
5661 }
5762 t .Cleanup (func () {
63+ builder .connMutex .Lock ()
64+ defer builder .connMutex .Unlock ()
5865 if builder .conn != nil {
5966 require .NoError (t , builder .conn .Close (context .Background ()))
6067 }
@@ -74,26 +81,31 @@ func RunCRDBForTesting(t testing.TB, bridgeNetworkName string, crdbVersion strin
7481 var err error
7582 ctx , cancelConnect := context .WithTimeout (context .Background (), dockerBootTimeout )
7683 defer cancelConnect ()
77- builder . conn , err = pgx .Connect (ctx , uri )
84+ conn , err : = pgx .Connect (ctx , uri )
7885 if err != nil {
7986 return err
8087 }
88+ builder .connMutex .Lock ()
89+ builder .conn = conn
8190 ctx , cancelRangeFeeds := context .WithTimeout (context .Background (), dockerBootTimeout )
8291 defer cancelRangeFeeds ()
8392 _ , err = builder .conn .Exec (ctx , enableRangefeeds )
93+ builder .connMutex .Unlock ()
8494 return err
8595 }))
8696
8797 return builder
8898}
8999
90- // NewDatabase creates a database. It is NOT safe for concurrent use.
100+ // NewDatabase creates a database.
91101func (r * crdbTester ) NewDatabase (t testing.TB ) string {
92102 uniquePortion , err := secrets .TokenHex (4 )
93103 require .NoError (t , err )
94104
95105 newDBName := "db" + uniquePortion
96106
107+ r .connMutex .Lock ()
108+ defer r .connMutex .Unlock ()
97109 _ , err = r .conn .Exec (context .Background (), "CREATE DATABASE " + newDBName )
98110 require .NoError (t , err )
99111
@@ -107,7 +119,7 @@ func (r *crdbTester) NewDatabase(t testing.TB) string {
107119 return connectStr
108120}
109121
110- // NewDatastore creates a database and runs migrations on it. It is NOT safe for concurrent use.
122+ // NewDatastore creates a database and runs migrations on it.
111123func (r * crdbTester ) NewDatastore (t testing.TB , initFunc InitFunc ) datastore.Datastore {
112124 connectStr := r .NewDatabase (t )
113125
0 commit comments