From 38c353358f6b9f0594384ead81e7b2f69c55af9a Mon Sep 17 00:00:00 2001 From: hperl <34397+hperl@users.noreply.github.com> Date: Mon, 16 May 2022 13:49:27 +0200 Subject: [PATCH] tests: more robust test db connections --- go.mod | 4 +- .../migrations/migratest/migration_test.go | 16 ++--- internal/x/dbx/dsn_testutils.go | 64 +++++++++++++++---- 3 files changed, 61 insertions(+), 23 deletions(-) diff --git a/go.mod b/go.mod index 241e0233c..6ee7fb9f5 100644 --- a/go.mod +++ b/go.mod @@ -26,9 +26,12 @@ require ( github.com/go-openapi/strfmt v0.20.3 github.com/go-openapi/swag v0.19.15 github.com/go-openapi/validate v0.20.3 + github.com/go-sql-driver/mysql v1.6.0 github.com/gobuffalo/pop/v6 v6.0.1 github.com/gofrs/uuid v4.1.0+incompatible github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 + github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 + github.com/instana/testify v1.6.2-0.20200721153833-94b1851f4d65 github.com/julienschmidt/httprouter v1.3.0 github.com/luna-duclos/instrumentedsql v1.1.3 github.com/mikefarah/yq/v4 v4.19.1 @@ -96,7 +99,6 @@ require ( github.com/go-openapi/jsonreference v0.19.5 // indirect github.com/go-openapi/loads v0.20.2 // indirect github.com/go-openapi/spec v0.20.3 // indirect - github.com/go-sql-driver/mysql v1.6.0 // indirect github.com/go-stack/stack v1.8.1 // indirect github.com/gobuffalo/envy v1.10.1 // indirect github.com/gobuffalo/fizz v1.14.0 // indirect diff --git a/internal/persistence/sql/migrations/migratest/migration_test.go b/internal/persistence/sql/migrations/migratest/migration_test.go index 66bfbb197..69cc03076 100644 --- a/internal/persistence/sql/migrations/migratest/migration_test.go +++ b/internal/persistence/sql/migrations/migratest/migration_test.go @@ -113,23 +113,23 @@ func TestMigrations(t *testing.T) { ctx := context.Background() l := logrusx.New("", "", logrusx.ForceLevel(logrus.DebugLevel)) - var c *pop.Connection + var conn *pop.Connection var err error - c, err = pop.NewConnection(&pop.ConnectionDetails{URL: db.Conn}) + conn, err = pop.NewConnection(&pop.ConnectionDetails{URL: db.Conn}) require.NoError(t, err) - require.NoError(t, c.Open()) - t.Cleanup(func() { c.Close() }) for i := 0; i < 120; i++ { - if err := c.Store.(interface{ Ping() error }).Ping(); err == nil { + require.NoError(t, conn.Open()) + if err := dbx.Ping(conn); err == nil { + t.Cleanup(func() { conn.Close() }) break } time.Sleep(time.Second) } - require.NoError(t, c.Store.(interface{ Ping() error }).Ping()) + require.NoError(t, dbx.Ping(conn)) tm, err := popx.NewMigrationBox( fsx.Merge(sql.Migrations, networkx.Migrations), - popx.NewMigrator(c, l, nil, 1*time.Minute), + popx.NewMigrator(conn, l, nil, 1*time.Minute), popx.WithGoMigrations(uuidmapping.Migrations), withTestdata(t, os.DirFS("./testdata")), ) @@ -170,7 +170,7 @@ func TestMigrations(t *testing.T) { t.Run("table=legacy namespaces", func(t *testing.T) { // as they are legacy, we expect them to be actually dropped - assert.ErrorIs(t, sqlcon.HandleError(c.RawQuery( + assert.ErrorIs(t, sqlcon.HandleError(conn.RawQuery( "SELECT * FROM keto_namespace", ).Exec()), sqlcon.ErrNoSuchTable) }) diff --git a/internal/x/dbx/dsn_testutils.go b/internal/x/dbx/dsn_testutils.go index 7f5acf44c..39ad3e784 100644 --- a/internal/x/dbx/dsn_testutils.go +++ b/internal/x/dbx/dsn_testutils.go @@ -9,6 +9,7 @@ import ( "path/filepath" "strings" "testing" + "time" "github.com/go-sql-driver/mysql" "github.com/gobuffalo/pop/v6" @@ -56,22 +57,48 @@ func dbName(_ string) string { return fmt.Sprintf("testdb_%x", buf) } -func createDB(t testing.TB, dsn string) (err error) { +func openAndPing(url string) (conn *pop.Connection, err error) { + if conn, err = pop.NewConnection(&pop.ConnectionDetails{URL: url}); err != nil { + return nil, fmt.Errorf("failed to connect to %q: %w", url, err) + } + for i := 0; i < 120; i++ { + fmt.Println("trying to open connection to", url) + if err := conn.Open(); err != nil { + // return nil, fmt.Errorf("failed to open connection: %w", err) + time.Sleep(1 * time.Second) + continue + } + if err := Ping(conn); err == nil { + break + } + time.Sleep(1 * time.Second) + } + if err := Ping(conn); err != nil { + return nil, fmt.Errorf("failed to ping: %w", err) + } + return conn, nil +} + +func createDB(t testing.TB, url string, dbName string) (err error) { var conn *pop.Connection - if conn, err = pop.NewConnection(&pop.ConnectionDetails{URL: dsn}); err != nil { - return fmt.Errorf("failed to connect to %q: %w", dsn, err) + if conn, err = openAndPing(url); err != nil { + return fmt.Errorf("failed to connect to %q: %w", url, err) } - if err = pop.CreateDB(conn); err != nil { - return fmt.Errorf("failed to create db in %q: %w", dsn, err) + + if err := conn.RawQuery("CREATE DATABASE " + dbName).Exec(); err != nil { + return fmt.Errorf("failed to create db %q in %q: %w", dbName, url, err) } + t.Cleanup(func() { - if err = pop.DropDB(conn); err != nil { - t.Log(err) + if err := conn.RawQuery("DROP DATABASE " + dbName).Exec(); err != nil { + t.Logf("could not drop database %q in %q: %v", dbName, url, err) } + conn.Close() }) return + } func GetDSNs(t testing.TB, debugSqliteOnDisk bool) []*DsnT { @@ -88,26 +115,31 @@ func GetDSNs(t testing.TB, debugSqliteOnDisk bool) []*DsnT { if !testing.Short() { var mysql, postgres, cockroach string - db := dbName(t.Name()) + testDB := dbName(t.Name()) dockertest.Parallel([]func(){ func() { - mysql = withDbName(dockertest.RunTestMySQL(t), db) - if err := createDB(t, mysql); err != nil { + url := dockertest.RunTestMySQL(t) + time.Sleep(1 * time.Second) + if err := createDB(t, url, testDB); err != nil { t.Fatal(err) } + mysql = withDbName(url, testDB) }, func() { - postgres = withDbName(dockertest.RunTestPostgreSQL(t), db) - if err := createDB(t, postgres); err != nil { + url := dockertest.RunTestPostgreSQL(t) + if err := createDB(t, url, testDB); err != nil { t.Fatal(err) } + postgres = withDbName(url, testDB) }, func() { - cockroach = withDbName(dockertest.RunTestCockroachDB(t), db) - if err := createDB(t, cockroach); err != nil { + url := dockertest.RunTestCockroachDB(t) + // time.Sleep(1 * time.Second) + if err := createDB(t, url, testDB); err != nil { t.Fatal(err) } + cockroach = withDbName(url, testDB) }, }) @@ -187,3 +219,7 @@ func ConfigFile(t testing.TB, values map[string]interface{}) string { return fn } + +type pinger interface{ Ping() error } + +func Ping(conn *pop.Connection) error { return conn.Store.(pinger).Ping() }