private/dbutil/pgtest: support multiple databases for testing
Currently Cockroach isn't performant for concurrent database setup and tear-down. Instead of a single instance allow setting multiple potential connection strings and let the tests pick one connection string randomly. This improves test duration by ~10 minutes. While we are at significantly changing how pgtest works, introduce helper PickPostgres and PickCockroach for selecting the database to reduce code duplications in multiple places. Change-Id: I8ad171d5c4c8a4fc081ec2ae9bdd0cc948a80619
This commit is contained in:
parent
6f84be133a
commit
85c45cd56f
@ -30,11 +30,13 @@ pipeline {
|
|||||||
sh 'make -j4 build-packages'
|
sh 'make -j4 build-packages'
|
||||||
sh 'make install-sim'
|
sh 'make install-sim'
|
||||||
|
|
||||||
sh 'cockroach start-single-node --insecure --store=type=mem,size=2GiB --listen-addr=localhost:26257 --http-addr=localhost:8080 --cache 512MiB --max-sql-memory 512MiB --background'
|
sh 'cockroach start-single-node --insecure --store=type=mem,size=2GiB --listen-addr=localhost:26256 --http-addr=localhost:8086 --cache 512MiB --max-sql-memory 512MiB --background'
|
||||||
|
sh 'cockroach start-single-node --insecure --store=type=mem,size=2GiB --listen-addr=localhost:26257 --http-addr=localhost:8087 --cache 512MiB --max-sql-memory 512MiB --background'
|
||||||
|
sh 'cockroach start-single-node --insecure --store=type=mem,size=2GiB --listen-addr=localhost:26258 --http-addr=localhost:8088 --cache 512MiB --max-sql-memory 512MiB --background'
|
||||||
|
sh 'cockroach start-single-node --insecure --store=type=mem,size=2GiB --listen-addr=localhost:26259 --http-addr=localhost:8089 --cache 512MiB --max-sql-memory 512MiB --background'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
stage('Verification') {
|
stage('Verification') {
|
||||||
parallel {
|
parallel {
|
||||||
stage('Lint') {
|
stage('Lint') {
|
||||||
@ -55,12 +57,19 @@ pipeline {
|
|||||||
|
|
||||||
stage('Tests') {
|
stage('Tests') {
|
||||||
environment {
|
environment {
|
||||||
STORJ_COCKROACH_TEST = 'cockroach://root@localhost:26257/testcockroach?sslmode=disable'
|
STORJ_COCKROACH_TEST = 'cockroach://root@localhost:26256/testcockroach?sslmode=disable;' +
|
||||||
|
'cockroach://root@localhost:26257/testcockroach?sslmode=disable;' +
|
||||||
|
'cockroach://root@localhost:26258/testcockroach?sslmode=disable;' +
|
||||||
|
'cockroach://root@localhost:26259/testcockroach?sslmode=disable'
|
||||||
STORJ_POSTGRES_TEST = 'postgres://postgres@localhost/teststorj?sslmode=disable'
|
STORJ_POSTGRES_TEST = 'postgres://postgres@localhost/teststorj?sslmode=disable'
|
||||||
COVERFLAGS = "${ env.BRANCH_NAME != 'master' ? '' : '-coverprofile=.build/coverprofile -coverpkg=storj.io/storj/private/...,storj.io/storj/lib/...,storj.io/storj/pkg/...,storj.io/storj/satellite/...,storj.io/storj/storage/...,storj.io/storj/storagenode/...,storj.io/storj/versioncontrol/...'}"
|
COVERFLAGS = "${ env.BRANCH_NAME != 'master' ? '' : '-coverprofile=.build/coverprofile -coverpkg=storj.io/storj/private/...,storj.io/storj/lib/...,storj.io/storj/pkg/...,storj.io/storj/satellite/...,storj.io/storj/storage/...,storj.io/storj/storagenode/...,storj.io/storj/versioncontrol/...'}"
|
||||||
}
|
}
|
||||||
steps {
|
steps {
|
||||||
|
sh 'cockroach sql --insecure --host=localhost:26256 -e \'create database testcockroach;\''
|
||||||
sh 'cockroach sql --insecure --host=localhost:26257 -e \'create database testcockroach;\''
|
sh 'cockroach sql --insecure --host=localhost:26257 -e \'create database testcockroach;\''
|
||||||
|
sh 'cockroach sql --insecure --host=localhost:26258 -e \'create database testcockroach;\''
|
||||||
|
sh 'cockroach sql --insecure --host=localhost:26259 -e \'create database testcockroach;\''
|
||||||
|
|
||||||
sh 'psql -U postgres -c \'create database teststorj;\''
|
sh 'psql -U postgres -c \'create database teststorj;\''
|
||||||
sh 'use-ports -from 1024 -to 10000 &'
|
sh 'use-ports -from 1024 -to 10000 &'
|
||||||
sh 'go test -parallel 4 -p 6 -vet=off $COVERFLAGS -timeout 20m -json -race ./... 2>&1 | tee .build/tests.json | xunit -out .build/tests.xml'
|
sh 'go test -parallel 4 -p 6 -vet=off $COVERFLAGS -timeout 20m -json -race ./... 2>&1 | tee .build/tests.json | xunit -out .build/tests.xml'
|
||||||
@ -112,6 +121,7 @@ pipeline {
|
|||||||
steps {
|
steps {
|
||||||
sh 'cockroach sql --insecure --host=localhost:26257 -e \'create database testcockroach4;\''
|
sh 'cockroach sql --insecure --host=localhost:26257 -e \'create database testcockroach4;\''
|
||||||
sh 'make test-sim'
|
sh 'make test-sim'
|
||||||
|
sh 'cockroach sql --insecure --host=localhost:26257 -e \'drop database testcockroach4;\''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,6 +151,7 @@ pipeline {
|
|||||||
steps {
|
steps {
|
||||||
sh 'cockroach sql --insecure --host=localhost:26257 -e \'create database testcockroach5;\''
|
sh 'cockroach sql --insecure --host=localhost:26257 -e \'create database testcockroach5;\''
|
||||||
sh 'make test-sim-backwards-compatible'
|
sh 'make test-sim-backwards-compatible'
|
||||||
|
sh 'cockroach sql --insecure --host=localhost:26257 -e \'drop database testcockroach5;\''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,18 +11,17 @@ import (
|
|||||||
"github.com/zeebo/errs"
|
"github.com/zeebo/errs"
|
||||||
|
|
||||||
"storj.io/common/testcontext"
|
"storj.io/common/testcontext"
|
||||||
"storj.io/storj/private/dbutil/pgutil/pgtest"
|
"storj.io/storj/private/dbutil/pgtest"
|
||||||
"storj.io/storj/private/tagsql"
|
"storj.io/storj/private/tagsql"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestLibPqCompatibility(t *testing.T) {
|
func TestLibPqCompatibility(t *testing.T) {
|
||||||
|
connstr := pgtest.PickCockroach(t)
|
||||||
|
|
||||||
ctx := testcontext.New(t)
|
ctx := testcontext.New(t)
|
||||||
defer ctx.Cleanup()
|
defer ctx.Cleanup()
|
||||||
|
|
||||||
if *pgtest.CrdbConnStr == "" {
|
testDB, err := OpenUnique(ctx, connstr, "TestLibPqCompatibility")
|
||||||
t.Skip("CockroachDB flag missing")
|
|
||||||
}
|
|
||||||
testDB, err := OpenUnique(ctx, *pgtest.CrdbConnStr, "TestLibPqCompatibility")
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer ctx.Check(testDB.Close)
|
defer ctx.Check(testDB.Close)
|
||||||
|
|
||||||
|
@ -12,20 +12,19 @@ import (
|
|||||||
"storj.io/common/testcontext"
|
"storj.io/common/testcontext"
|
||||||
"storj.io/storj/private/dbutil"
|
"storj.io/storj/private/dbutil"
|
||||||
"storj.io/storj/private/dbutil/cockroachutil"
|
"storj.io/storj/private/dbutil/cockroachutil"
|
||||||
"storj.io/storj/private/dbutil/pgutil/pgtest"
|
"storj.io/storj/private/dbutil/pgtest"
|
||||||
"storj.io/storj/private/dbutil/tempdb"
|
"storj.io/storj/private/dbutil/tempdb"
|
||||||
"storj.io/storj/private/tagsql"
|
"storj.io/storj/private/tagsql"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestTempCockroachDB(t *testing.T) {
|
func TestTempCockroachDB(t *testing.T) {
|
||||||
|
connstr := pgtest.PickCockroach(t)
|
||||||
|
|
||||||
ctx := testcontext.New(t)
|
ctx := testcontext.New(t)
|
||||||
defer ctx.Cleanup()
|
defer ctx.Cleanup()
|
||||||
|
|
||||||
if *pgtest.CrdbConnStr == "" {
|
|
||||||
t.Skip("CockroachDB flag missing")
|
|
||||||
}
|
|
||||||
prefix := "name#spaced/Test/DB"
|
prefix := "name#spaced/Test/DB"
|
||||||
testDB, err := tempdb.OpenUnique(ctx, *pgtest.CrdbConnStr, prefix)
|
testDB, err := tempdb.OpenUnique(ctx, connstr, prefix)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.Equal(t, "cockroach", testDB.Driver)
|
require.Equal(t, "cockroach", testDB.Driver)
|
||||||
@ -62,7 +61,7 @@ func TestTempCockroachDB(t *testing.T) {
|
|||||||
|
|
||||||
// make a new connection back to the master connstr just to check that the our temp db
|
// make a new connection back to the master connstr just to check that the our temp db
|
||||||
// really was dropped
|
// really was dropped
|
||||||
plainDBConn, err := tagsql.Open("cockroach", *pgtest.CrdbConnStr)
|
plainDBConn, err := tagsql.Open("cockroach", connstr)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer ctx.Check(plainDBConn.Close)
|
defer ctx.Check(plainDBConn.Close)
|
||||||
|
|
||||||
|
89
private/dbutil/pgtest/flag.go
Normal file
89
private/dbutil/pgtest/flag.go
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
// Copyright (C) 2019 Storj Labs, Inc.
|
||||||
|
// See LICENSE for copying information.
|
||||||
|
|
||||||
|
package pgtest
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"math/rand"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"storj.io/common/testcontext"
|
||||||
|
)
|
||||||
|
|
||||||
|
// We need to define this in a separate package due to https://golang.org/issue/23910.
|
||||||
|
|
||||||
|
// postgres is the test database connection string.
|
||||||
|
var postgres = flag.String("postgres-test-db", os.Getenv("STORJ_POSTGRES_TEST"), "PostgreSQL test database connection string (semicolon delimited for multiple)")
|
||||||
|
|
||||||
|
// cockroach is the test database connection string for CockroachDB
|
||||||
|
var cockroach = flag.String("cockroach-test-db", os.Getenv("STORJ_COCKROACH_TEST"), "CockroachDB test database connection string (semicolon delimited for multiple)")
|
||||||
|
|
||||||
|
// DefaultPostgres is expected to work under the storj-test docker-compose instance
|
||||||
|
const DefaultPostgres = "postgres://storj:storj-pass@test-postgres/teststorj?sslmode=disable"
|
||||||
|
|
||||||
|
// DefaultCockroach is expected to work when a local cockroachDB instance is running
|
||||||
|
const DefaultCockroach = "cockroach://root@localhost:26257/master?sslmode=disable"
|
||||||
|
|
||||||
|
// Database defines a postgres compatible database.
|
||||||
|
type Database struct {
|
||||||
|
Name string
|
||||||
|
// Pick picks a connection string for the database and skips when it's missing.
|
||||||
|
Pick func(t TB) string
|
||||||
|
}
|
||||||
|
|
||||||
|
// TB defines minimal interface required for Pick.
|
||||||
|
type TB interface {
|
||||||
|
Skip(...interface{})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Databases returns list of postgres compatible databases.
|
||||||
|
func Databases() []Database {
|
||||||
|
return []Database{
|
||||||
|
{Name: "Postgres", Pick: PickPostgres},
|
||||||
|
{Name: "Cockroach", Pick: PickCockroach},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run runs tests with all postgres compatible databases.
|
||||||
|
func Run(t *testing.T, test func(ctx *testcontext.Context, t *testing.T, connstr string)) {
|
||||||
|
for _, db := range Databases() {
|
||||||
|
db := db
|
||||||
|
t.Run(db.Name, func(t *testing.T) {
|
||||||
|
connstr := db.Pick(t)
|
||||||
|
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
ctx := testcontext.New(t)
|
||||||
|
defer ctx.Cleanup()
|
||||||
|
|
||||||
|
test(ctx, t, connstr)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PickPostgres picks a random postgres database from flag.
|
||||||
|
func PickPostgres(t TB) string {
|
||||||
|
if *postgres == "" {
|
||||||
|
t.Skip("Postgres flag missing, example: -postgres-test-db=" + DefaultPostgres)
|
||||||
|
}
|
||||||
|
return pickRandom(*postgres)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PickCockroach picks a random cockroach database from flag.
|
||||||
|
func PickCockroach(t TB) string {
|
||||||
|
if *cockroach == "" {
|
||||||
|
t.Skip("Cockroach flag missing, example: -cockroach-test-db=" + DefaultCockroach)
|
||||||
|
}
|
||||||
|
return pickRandom(*cockroach)
|
||||||
|
}
|
||||||
|
|
||||||
|
func pickRandom(dbstr string) string {
|
||||||
|
values := strings.Split(dbstr, ";")
|
||||||
|
if len(values) <= 1 {
|
||||||
|
return dbstr
|
||||||
|
}
|
||||||
|
return values[rand.Intn(len(values))]
|
||||||
|
}
|
@ -10,20 +10,19 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"storj.io/common/testcontext"
|
"storj.io/common/testcontext"
|
||||||
"storj.io/storj/private/dbutil/pgutil/pgtest"
|
"storj.io/storj/private/dbutil/pgtest"
|
||||||
"storj.io/storj/private/dbutil/tempdb"
|
"storj.io/storj/private/dbutil/tempdb"
|
||||||
"storj.io/storj/private/tagsql"
|
"storj.io/storj/private/tagsql"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestTempPostgresDB(t *testing.T) {
|
func TestTempPostgresDB(t *testing.T) {
|
||||||
|
connstr := pgtest.PickPostgres(t)
|
||||||
|
|
||||||
ctx := testcontext.New(t)
|
ctx := testcontext.New(t)
|
||||||
defer ctx.Cleanup()
|
defer ctx.Cleanup()
|
||||||
|
|
||||||
if *pgtest.ConnStr == "" {
|
|
||||||
t.Skip("PostgreSQL flag missing")
|
|
||||||
}
|
|
||||||
prefix := "name#spaced/Test/DB"
|
prefix := "name#spaced/Test/DB"
|
||||||
testDB, err := tempdb.OpenUnique(ctx, *pgtest.ConnStr, prefix)
|
testDB, err := tempdb.OpenUnique(ctx, connstr, prefix)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// assert new test db exists and can be connected to again
|
// assert new test db exists and can be connected to again
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
// Copyright (C) 2019 Storj Labs, Inc.
|
|
||||||
// See LICENSE for copying information.
|
|
||||||
|
|
||||||
package pgtest
|
|
||||||
|
|
||||||
import (
|
|
||||||
"flag"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
// We need to define this in a separate package due to https://golang.org/issue/23910.
|
|
||||||
|
|
||||||
// ConnStr is the test database connection string.
|
|
||||||
var ConnStr = flag.String("postgres-test-db", os.Getenv("STORJ_POSTGRES_TEST"), "PostgreSQL test database connection string")
|
|
||||||
|
|
||||||
// CrdbConnStr is the test database connection string for CockroachDB
|
|
||||||
var CrdbConnStr = flag.String("cockroach-test-db", os.Getenv("STORJ_COCKROACH_TEST"), "CockroachDB test database connection string")
|
|
||||||
|
|
||||||
// DefaultConnStr is expected to work under the storj-test docker-compose instance
|
|
||||||
const DefaultConnStr = "postgres://storj:storj-pass@test-postgres/teststorj?sslmode=disable"
|
|
||||||
|
|
||||||
// DefaultCrdbConnStr is expected to work when a local cockroachDB instance is running
|
|
||||||
const DefaultCrdbConnStr = "cockroach://root@localhost:26257/master?sslmode=disable"
|
|
@ -13,119 +13,97 @@ import (
|
|||||||
"storj.io/common/testcontext"
|
"storj.io/common/testcontext"
|
||||||
"storj.io/storj/private/dbutil"
|
"storj.io/storj/private/dbutil"
|
||||||
"storj.io/storj/private/dbutil/dbschema"
|
"storj.io/storj/private/dbutil/dbschema"
|
||||||
|
"storj.io/storj/private/dbutil/pgtest"
|
||||||
"storj.io/storj/private/dbutil/pgutil"
|
"storj.io/storj/private/dbutil/pgutil"
|
||||||
"storj.io/storj/private/dbutil/pgutil/pgtest"
|
|
||||||
"storj.io/storj/private/dbutil/tempdb"
|
"storj.io/storj/private/dbutil/tempdb"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
func TestQuery(t *testing.T) {
|
||||||
// DefaultPostgresConn is a connstring that works with docker-compose
|
pgtest.Run(t, func(ctx *testcontext.Context, t *testing.T, connstr string) {
|
||||||
DefaultPostgresConn = "postgres://storj:storj-pass@test-postgres/teststorj?sslmode=disable"
|
db, err := tempdb.OpenUnique(ctx, connstr, "pgutil-query")
|
||||||
)
|
require.NoError(t, err)
|
||||||
|
defer ctx.Check(db.Close)
|
||||||
|
|
||||||
func TestQueryPostgres(t *testing.T) {
|
emptySchema, err := pgutil.QuerySchema(ctx, db)
|
||||||
if *pgtest.ConnStr == "" {
|
require.NoError(t, err)
|
||||||
t.Skip("Postgres flag missing, example: -postgres-test-db=" + DefaultPostgresConn)
|
assert.Equal(t, &dbschema.Schema{}, emptySchema)
|
||||||
}
|
|
||||||
|
|
||||||
doQueryTest(t, *pgtest.ConnStr)
|
_, err = db.ExecContext(ctx, `
|
||||||
}
|
CREATE TABLE users (
|
||||||
|
a bigint NOT NULL,
|
||||||
|
b bigint NOT NULL,
|
||||||
|
c text,
|
||||||
|
UNIQUE (c),
|
||||||
|
PRIMARY KEY (a)
|
||||||
|
);
|
||||||
|
CREATE TABLE names (
|
||||||
|
users_a bigint REFERENCES users( a ) ON DELETE CASCADE,
|
||||||
|
a text NOT NULL,
|
||||||
|
x text,
|
||||||
|
b text,
|
||||||
|
PRIMARY KEY (a, x),
|
||||||
|
UNIQUE ( x ),
|
||||||
|
UNIQUE ( a, b )
|
||||||
|
);
|
||||||
|
`)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
func TestQueryCockroach(t *testing.T) {
|
schema, err := pgutil.QuerySchema(ctx, db)
|
||||||
if *pgtest.CrdbConnStr == "" {
|
require.NoError(t, err)
|
||||||
t.Skip("Cockroach flag missing, example: -cockroach-test-db=" + pgtest.DefaultCrdbConnStr)
|
|
||||||
}
|
|
||||||
|
|
||||||
doQueryTest(t, *pgtest.CrdbConnStr)
|
expected := &dbschema.Schema{
|
||||||
}
|
Tables: []*dbschema.Table{
|
||||||
|
{
|
||||||
func doQueryTest(t *testing.T, connStr string) {
|
Name: "users",
|
||||||
ctx := testcontext.New(t)
|
Columns: []*dbschema.Column{
|
||||||
defer ctx.Cleanup()
|
{Name: "a", Type: "bigint", IsNullable: false, Reference: nil},
|
||||||
|
{Name: "b", Type: "bigint", IsNullable: false, Reference: nil},
|
||||||
db, err := tempdb.OpenUnique(ctx, connStr, "pgutil-query")
|
{Name: "c", Type: "text", IsNullable: true, Reference: nil},
|
||||||
require.NoError(t, err)
|
},
|
||||||
defer ctx.Check(db.Close)
|
PrimaryKey: []string{"a"},
|
||||||
|
Unique: [][]string{
|
||||||
emptySchema, err := pgutil.QuerySchema(ctx, db)
|
{"c"},
|
||||||
require.NoError(t, err)
|
},
|
||||||
assert.Equal(t, &dbschema.Schema{}, emptySchema)
|
|
||||||
|
|
||||||
_, err = db.ExecContext(ctx, `
|
|
||||||
CREATE TABLE users (
|
|
||||||
a bigint NOT NULL,
|
|
||||||
b bigint NOT NULL,
|
|
||||||
c text,
|
|
||||||
UNIQUE (c),
|
|
||||||
PRIMARY KEY (a)
|
|
||||||
);
|
|
||||||
CREATE TABLE names (
|
|
||||||
users_a bigint REFERENCES users( a ) ON DELETE CASCADE,
|
|
||||||
a text NOT NULL,
|
|
||||||
x text,
|
|
||||||
b text,
|
|
||||||
PRIMARY KEY (a, x),
|
|
||||||
UNIQUE ( x ),
|
|
||||||
UNIQUE ( a, b )
|
|
||||||
);
|
|
||||||
`)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
schema, err := pgutil.QuerySchema(ctx, db)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
expected := &dbschema.Schema{
|
|
||||||
Tables: []*dbschema.Table{
|
|
||||||
{
|
|
||||||
Name: "users",
|
|
||||||
Columns: []*dbschema.Column{
|
|
||||||
{Name: "a", Type: "bigint", IsNullable: false, Reference: nil},
|
|
||||||
{Name: "b", Type: "bigint", IsNullable: false, Reference: nil},
|
|
||||||
{Name: "c", Type: "text", IsNullable: true, Reference: nil},
|
|
||||||
},
|
},
|
||||||
PrimaryKey: []string{"a"},
|
{
|
||||||
Unique: [][]string{
|
Name: "names",
|
||||||
{"c"},
|
Columns: []*dbschema.Column{
|
||||||
|
{Name: "users_a", Type: "bigint", IsNullable: true,
|
||||||
|
Reference: &dbschema.Reference{
|
||||||
|
Table: "users",
|
||||||
|
Column: "a",
|
||||||
|
OnDelete: "CASCADE",
|
||||||
|
}},
|
||||||
|
{Name: "a", Type: "text", IsNullable: false, Reference: nil},
|
||||||
|
{Name: "x", Type: "text", IsNullable: false, Reference: nil}, // not null, because primary key
|
||||||
|
{Name: "b", Type: "text", IsNullable: true, Reference: nil},
|
||||||
|
},
|
||||||
|
PrimaryKey: []string{"a", "x"},
|
||||||
|
Unique: [][]string{
|
||||||
|
{"a", "b"},
|
||||||
|
{"x"},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
Indexes: []*dbschema.Index{
|
||||||
Name: "names",
|
{Name: "names_a_b_key", Table: "names", Columns: []string{"a", "b"}, Unique: true, Partial: ""},
|
||||||
Columns: []*dbschema.Column{
|
{Name: "names_pkey", Table: "names", Columns: []string{"a", "x"}, Unique: true, Partial: ""},
|
||||||
{Name: "users_a", Type: "bigint", IsNullable: true,
|
{Name: "names_x_key", Table: "names", Columns: []string{"x"}, Unique: true, Partial: ""},
|
||||||
Reference: &dbschema.Reference{
|
{Name: "users_c_key", Table: "users", Columns: []string{"c"}, Unique: true, Partial: ""},
|
||||||
Table: "users",
|
{Name: "users_pkey", Table: "users", Columns: []string{"a"}, Unique: true, Partial: ""},
|
||||||
Column: "a",
|
|
||||||
OnDelete: "CASCADE",
|
|
||||||
}},
|
|
||||||
{Name: "a", Type: "text", IsNullable: false, Reference: nil},
|
|
||||||
{Name: "x", Type: "text", IsNullable: false, Reference: nil}, // not null, because primary key
|
|
||||||
{Name: "b", Type: "text", IsNullable: true, Reference: nil},
|
|
||||||
},
|
|
||||||
PrimaryKey: []string{"a", "x"},
|
|
||||||
Unique: [][]string{
|
|
||||||
{"a", "b"},
|
|
||||||
{"x"},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
}
|
||||||
Indexes: []*dbschema.Index{
|
|
||||||
{Name: "names_a_b_key", Table: "names", Columns: []string{"a", "b"}, Unique: true, Partial: ""},
|
|
||||||
{Name: "names_pkey", Table: "names", Columns: []string{"a", "x"}, Unique: true, Partial: ""},
|
|
||||||
{Name: "names_x_key", Table: "names", Columns: []string{"x"}, Unique: true, Partial: ""},
|
|
||||||
{Name: "users_c_key", Table: "users", Columns: []string{"c"}, Unique: true, Partial: ""},
|
|
||||||
{Name: "users_pkey", Table: "users", Columns: []string{"a"}, Unique: true, Partial: ""},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
if db.Implementation == dbutil.Cockroach {
|
if db.Implementation == dbutil.Cockroach {
|
||||||
expected.Indexes = append(expected.Indexes, &dbschema.Index{
|
expected.Indexes = append(expected.Indexes, &dbschema.Index{
|
||||||
Name: "names_auto_index_fk_users_a_ref_users",
|
Name: "names_auto_index_fk_users_a_ref_users",
|
||||||
Table: "names",
|
Table: "names",
|
||||||
Columns: []string{"users_a"},
|
Columns: []string{"users_a"},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
expected.Sort()
|
expected.Sort()
|
||||||
schema.Sort()
|
schema.Sort()
|
||||||
assert.Equal(t, expected, schema)
|
assert.Equal(t, expected, schema)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"storj.io/common/testcontext"
|
"storj.io/common/testcontext"
|
||||||
"storj.io/storj/private/dbutil/pgutil/pgtest"
|
"storj.io/storj/private/dbutil/pgtest"
|
||||||
"storj.io/storj/private/dbutil/tempdb"
|
"storj.io/storj/private/dbutil/tempdb"
|
||||||
"storj.io/storj/private/migrate"
|
"storj.io/storj/private/migrate"
|
||||||
"storj.io/storj/private/tagsql"
|
"storj.io/storj/private/tagsql"
|
||||||
@ -46,48 +46,30 @@ func TestCreate_Sqlite(t *testing.T) {
|
|||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCreate_Postgres(t *testing.T) {
|
func TestCreate(t *testing.T) {
|
||||||
if *pgtest.ConnStr == "" {
|
pgtest.Run(t, func(ctx *testcontext.Context, t *testing.T, connstr string) {
|
||||||
t.Skipf("postgres flag missing, example:\n-postgres-test-db=%s", pgtest.DefaultConnStr)
|
db, err := tempdb.OpenUnique(ctx, connstr, "create-")
|
||||||
}
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
defer func() { assert.NoError(t, db.Close()) }()
|
||||||
|
|
||||||
ctx := testcontext.New(t)
|
// should create table
|
||||||
defer ctx.Cleanup()
|
err = migrate.Create(ctx, "example", &postgresDB{db.DB, "CREATE TABLE example_table (id text)"})
|
||||||
testCreateGeneric(ctx, t, *pgtest.ConnStr)
|
require.NoError(t, err)
|
||||||
}
|
|
||||||
|
|
||||||
func TestCreate_Cockroach(t *testing.T) {
|
// shouldn't create a new table
|
||||||
if *pgtest.CrdbConnStr == "" {
|
err = migrate.Create(ctx, "example", &postgresDB{db.DB, "CREATE TABLE example_table (id text)"})
|
||||||
t.Skip("Cockroach flag missing, example: -cockroach-test-db=" + pgtest.DefaultCrdbConnStr)
|
require.NoError(t, err)
|
||||||
}
|
|
||||||
|
|
||||||
ctx := testcontext.New(t)
|
// should fail, because schema changed
|
||||||
defer ctx.Cleanup()
|
err = migrate.Create(ctx, "example", &postgresDB{db.DB, "CREATE TABLE example_table (id text, version integer)"})
|
||||||
testCreateGeneric(ctx, t, *pgtest.CrdbConnStr)
|
require.Error(t, err)
|
||||||
}
|
|
||||||
|
|
||||||
func testCreateGeneric(ctx *testcontext.Context, t *testing.T, connStr string) {
|
// should fail, because of trying to CREATE TABLE with same name
|
||||||
db, err := tempdb.OpenUnique(ctx, connStr, "create-")
|
err = migrate.Create(ctx, "conflict", &postgresDB{db.DB, "CREATE TABLE example_table (id text, version integer)"})
|
||||||
if err != nil {
|
require.Error(t, err)
|
||||||
t.Fatal(err)
|
})
|
||||||
}
|
|
||||||
defer func() { assert.NoError(t, db.Close()) }()
|
|
||||||
|
|
||||||
// should create table
|
|
||||||
err = migrate.Create(ctx, "example", &postgresDB{db.DB, "CREATE TABLE example_table (id text)"})
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
// shouldn't create a new table
|
|
||||||
err = migrate.Create(ctx, "example", &postgresDB{db.DB, "CREATE TABLE example_table (id text)"})
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
// should fail, because schema changed
|
|
||||||
err = migrate.Create(ctx, "example", &postgresDB{db.DB, "CREATE TABLE example_table (id text, version integer)"})
|
|
||||||
require.Error(t, err)
|
|
||||||
|
|
||||||
// should fail, because of trying to CREATE TABLE with same name
|
|
||||||
err = migrate.Create(ctx, "conflict", &postgresDB{db.DB, "CREATE TABLE example_table (id text, version integer)"})
|
|
||||||
require.Error(t, err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type sqliteDB struct {
|
type sqliteDB struct {
|
||||||
|
@ -18,7 +18,7 @@ import (
|
|||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
"storj.io/common/testcontext"
|
"storj.io/common/testcontext"
|
||||||
"storj.io/storj/private/dbutil/pgutil/pgtest"
|
"storj.io/storj/private/dbutil/pgtest"
|
||||||
"storj.io/storj/private/dbutil/tempdb"
|
"storj.io/storj/private/dbutil/tempdb"
|
||||||
"storj.io/storj/private/migrate"
|
"storj.io/storj/private/migrate"
|
||||||
"storj.io/storj/private/tagsql"
|
"storj.io/storj/private/tagsql"
|
||||||
@ -46,38 +46,20 @@ func TestBasicMigrationSqlite(t *testing.T) {
|
|||||||
basicMigration(ctx, t, db, &sqliteDB{DB: db})
|
basicMigration(ctx, t, db, &sqliteDB{DB: db})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBasicMigrationPostgres(t *testing.T) {
|
func TestBasicMigration(t *testing.T) {
|
||||||
if *pgtest.ConnStr == "" {
|
pgtest.Run(t, func(ctx *testcontext.Context, t *testing.T, connstr string) {
|
||||||
t.Skipf("postgres flag missing, example:\n-postgres-test-db=%s", pgtest.DefaultConnStr)
|
db, err := tempdb.OpenUnique(ctx, connstr, "create-")
|
||||||
}
|
if err != nil {
|
||||||
ctx := testcontext.New(t)
|
t.Fatal(err)
|
||||||
defer ctx.Cleanup()
|
}
|
||||||
|
defer func() { assert.NoError(t, db.Close()) }()
|
||||||
|
|
||||||
testBasicMigrationGeneric(ctx, t, *pgtest.ConnStr)
|
basicMigration(ctx, t, db.DB, &postgresDB{DB: db.DB})
|
||||||
}
|
})
|
||||||
|
|
||||||
func TestBasicMigrationCockroach(t *testing.T) {
|
|
||||||
if *pgtest.CrdbConnStr == "" {
|
|
||||||
t.Skipf("cockroach flag missing, example:\n-cockroach-test-db=%s", pgtest.DefaultCrdbConnStr)
|
|
||||||
}
|
|
||||||
ctx := testcontext.New(t)
|
|
||||||
defer ctx.Cleanup()
|
|
||||||
|
|
||||||
testBasicMigrationGeneric(ctx, t, *pgtest.CrdbConnStr)
|
|
||||||
}
|
|
||||||
|
|
||||||
func testBasicMigrationGeneric(ctx *testcontext.Context, t *testing.T, connStr string) {
|
|
||||||
db, err := tempdb.OpenUnique(ctx, connStr, "create-")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
defer func() { assert.NoError(t, db.Close()) }()
|
|
||||||
|
|
||||||
basicMigration(ctx, t, db.DB, &postgresDB{DB: db.DB})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func basicMigration(ctx *testcontext.Context, t *testing.T, db tagsql.DB, testDB tagsql.DB) {
|
func basicMigration(ctx *testcontext.Context, t *testing.T, db tagsql.DB, testDB tagsql.DB) {
|
||||||
dbName := strings.ToLower(`versions_` + t.Name())
|
dbName := strings.ToLower(`versions_` + strings.Replace(t.Name(), "/", "_", -1))
|
||||||
defer func() { assert.NoError(t, dropTables(ctx, db, dbName, "users")) }()
|
defer func() { assert.NoError(t, dropTables(ctx, db, dbName, "users")) }()
|
||||||
|
|
||||||
err := ioutil.WriteFile(ctx.File("alpha.txt"), []byte("test"), 0644)
|
err := ioutil.WriteFile(ctx.File("alpha.txt"), []byte("test"), 0644)
|
||||||
@ -160,11 +142,9 @@ func TestMultipleMigrationSqlite(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMultipleMigrationPostgres(t *testing.T) {
|
func TestMultipleMigrationPostgres(t *testing.T) {
|
||||||
if *pgtest.ConnStr == "" {
|
connstr := pgtest.PickPostgres(t)
|
||||||
t.Skipf("postgres flag missing, example:\n-postgres-test-db=%s", pgtest.DefaultConnStr)
|
|
||||||
}
|
|
||||||
|
|
||||||
db, err := tagsql.Open("postgres", *pgtest.ConnStr)
|
db, err := tagsql.Open("postgres", connstr)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer func() { assert.NoError(t, db.Close()) }()
|
defer func() { assert.NoError(t, db.Close()) }()
|
||||||
|
|
||||||
@ -236,11 +216,9 @@ func TestFailedMigrationSqlite(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestFailedMigrationPostgres(t *testing.T) {
|
func TestFailedMigrationPostgres(t *testing.T) {
|
||||||
if *pgtest.ConnStr == "" {
|
connstr := pgtest.PickPostgres(t)
|
||||||
t.Skipf("postgres flag missing, example:\n-postgres-test-db=%s", pgtest.DefaultConnStr)
|
|
||||||
}
|
|
||||||
|
|
||||||
db, err := tagsql.Open("postgres", *pgtest.ConnStr)
|
db, err := tagsql.Open("postgres", connstr)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer func() { assert.NoError(t, db.Close()) }()
|
defer func() { assert.NoError(t, db.Close()) }()
|
||||||
|
|
||||||
|
@ -12,8 +12,8 @@ import (
|
|||||||
|
|
||||||
"storj.io/common/testcontext"
|
"storj.io/common/testcontext"
|
||||||
"storj.io/storj/private/dbutil/cockroachutil"
|
"storj.io/storj/private/dbutil/cockroachutil"
|
||||||
|
"storj.io/storj/private/dbutil/pgtest"
|
||||||
"storj.io/storj/private/dbutil/pgutil"
|
"storj.io/storj/private/dbutil/pgutil"
|
||||||
"storj.io/storj/private/dbutil/pgutil/pgtest"
|
|
||||||
"storj.io/storj/private/tagsql"
|
"storj.io/storj/private/tagsql"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -34,14 +34,12 @@ func run(t *testing.T, fn func(*testcontext.Context, *testing.T, tagsql.DB, tags
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("lib-pq-postgres", func(t *testing.T) {
|
t.Run("lib-pq-postgres", func(t *testing.T) {
|
||||||
|
connstr := pgtest.PickPostgres(t)
|
||||||
|
|
||||||
ctx := testcontext.New(t)
|
ctx := testcontext.New(t)
|
||||||
defer ctx.Cleanup()
|
defer ctx.Cleanup()
|
||||||
|
|
||||||
if *pgtest.ConnStr == "" {
|
db, err := pgutil.OpenUnique(ctx, connstr, "detect")
|
||||||
t.Skipf("postgresql flag missing, example:\n-postgres-test-db=%s", pgtest.DefaultConnStr)
|
|
||||||
}
|
|
||||||
|
|
||||||
db, err := pgutil.OpenUnique(ctx, *pgtest.ConnStr, "detect")
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer ctx.Check(db.Close)
|
defer ctx.Check(db.Close)
|
||||||
|
|
||||||
@ -49,14 +47,12 @@ func run(t *testing.T, fn func(*testcontext.Context, *testing.T, tagsql.DB, tags
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("lib-pq-cockroach", func(t *testing.T) {
|
t.Run("lib-pq-cockroach", func(t *testing.T) {
|
||||||
|
connstr := pgtest.PickCockroach(t)
|
||||||
|
|
||||||
ctx := testcontext.New(t)
|
ctx := testcontext.New(t)
|
||||||
defer ctx.Cleanup()
|
defer ctx.Cleanup()
|
||||||
|
|
||||||
if *pgtest.CrdbConnStr == "" {
|
db, err := cockroachutil.OpenUnique(ctx, connstr, "detect")
|
||||||
t.Skipf("postgresql flag missing, example:\n-cockroach-test-db=%s", pgtest.DefaultCrdbConnStr)
|
|
||||||
}
|
|
||||||
|
|
||||||
db, err := cockroachutil.OpenUnique(ctx, *pgtest.CrdbConnStr, "detect")
|
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer ctx.Check(db.Close)
|
defer ctx.Check(db.Close)
|
||||||
|
|
||||||
|
@ -121,11 +121,6 @@ func (peer *closablePeer) Close() error {
|
|||||||
|
|
||||||
// NewCustom creates a new full system with the specified configuration.
|
// NewCustom creates a new full system with the specified configuration.
|
||||||
func NewCustom(log *zap.Logger, config Config, satelliteDatabases satellitedbtest.SatelliteDatabases) (*Planet, error) {
|
func NewCustom(log *zap.Logger, config Config, satelliteDatabases satellitedbtest.SatelliteDatabases) (*Planet, error) {
|
||||||
// Clear error in the beginning to avoid issues down the line.
|
|
||||||
if err := satellitedbtest.PostgresDefined(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if config.IdentityVersion == nil {
|
if config.IdentityVersion == nil {
|
||||||
version := storj.LatestIDVersion()
|
version := storj.LatestIDVersion()
|
||||||
config.IdentityVersion = &version
|
config.IdentityVersion = &version
|
||||||
|
@ -9,11 +9,23 @@ import (
|
|||||||
"go.uber.org/zap/zaptest"
|
"go.uber.org/zap/zaptest"
|
||||||
|
|
||||||
"storj.io/common/testcontext"
|
"storj.io/common/testcontext"
|
||||||
|
"storj.io/storj/private/dbutil/pgtest"
|
||||||
"storj.io/storj/satellite/satellitedb/satellitedbtest"
|
"storj.io/storj/satellite/satellitedb/satellitedbtest"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Run runs testplanet in multiple configurations.
|
// Run runs testplanet in multiple configurations.
|
||||||
func Run(t *testing.T, config Config, test func(t *testing.T, ctx *testcontext.Context, planet *Planet)) {
|
func Run(t *testing.T, config Config, test func(t *testing.T, ctx *testcontext.Context, planet *Planet)) {
|
||||||
|
databases := satellitedbtest.Databases()
|
||||||
|
hasDatabase := false
|
||||||
|
for _, db := range databases {
|
||||||
|
hasDatabase = hasDatabase || db.MasterDB.URL != ""
|
||||||
|
}
|
||||||
|
if !hasDatabase {
|
||||||
|
t.Fatal("Databases flag missing, set at least one:\n" +
|
||||||
|
"-postgres-test-db=" + pgtest.DefaultPostgres + "\n" +
|
||||||
|
"-cockroach-test-db=" + pgtest.DefaultCockroach)
|
||||||
|
}
|
||||||
|
|
||||||
for _, satelliteDB := range satellitedbtest.Databases() {
|
for _, satelliteDB := range satellitedbtest.Databases() {
|
||||||
satelliteDB := satelliteDB
|
satelliteDB := satelliteDB
|
||||||
t.Run(satelliteDB.Name, func(t *testing.T) {
|
t.Run(satelliteDB.Name, func(t *testing.T) {
|
||||||
@ -28,6 +40,7 @@ func Run(t *testing.T, config Config, test func(t *testing.T, ctx *testcontext.C
|
|||||||
if satelliteDB.MasterDB.URL == "" {
|
if satelliteDB.MasterDB.URL == "" {
|
||||||
t.Skipf("Database %s connection string not provided. %s", satelliteDB.MasterDB.Name, satelliteDB.MasterDB.Message)
|
t.Skipf("Database %s connection string not provided. %s", satelliteDB.MasterDB.Name, satelliteDB.MasterDB.Message)
|
||||||
}
|
}
|
||||||
|
|
||||||
planetConfig := config
|
planetConfig := config
|
||||||
if planetConfig.Name == "" {
|
if planetConfig.Name == "" {
|
||||||
planetConfig.Name = t.Name()
|
planetConfig.Name = t.Name()
|
||||||
|
@ -22,8 +22,8 @@ import (
|
|||||||
|
|
||||||
"storj.io/common/testcontext"
|
"storj.io/common/testcontext"
|
||||||
"storj.io/storj/private/dbutil/dbschema"
|
"storj.io/storj/private/dbutil/dbschema"
|
||||||
|
"storj.io/storj/private/dbutil/pgtest"
|
||||||
"storj.io/storj/private/dbutil/pgutil"
|
"storj.io/storj/private/dbutil/pgutil"
|
||||||
"storj.io/storj/private/dbutil/pgutil/pgtest"
|
|
||||||
"storj.io/storj/private/dbutil/tempdb"
|
"storj.io/storj/private/dbutil/tempdb"
|
||||||
"storj.io/storj/private/migrate"
|
"storj.io/storj/private/migrate"
|
||||||
"storj.io/storj/satellite/satellitedb"
|
"storj.io/storj/satellite/satellitedb"
|
||||||
@ -132,72 +132,8 @@ func loadSchemaFromSQL(ctx context.Context, connstr, script string) (_ *dbschema
|
|||||||
return pgutil.QuerySchema(ctx, db)
|
return pgutil.QuerySchema(ctx, db)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMigrateCockroach(t *testing.T) {
|
func TestMigratePostgres(t *testing.T) { migrateTest(t, pgtest.PickPostgres(t)) }
|
||||||
if *pgtest.CrdbConnStr == "" {
|
func TestMigrateCockroach(t *testing.T) { migrateTest(t, pgtest.PickCockroach(t)) }
|
||||||
t.Skip("Cockroach flag missing, example: -cockroach-test-db=" + pgtest.DefaultCrdbConnStr)
|
|
||||||
}
|
|
||||||
t.Parallel()
|
|
||||||
migrateTest(t, *pgtest.CrdbConnStr)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMigratePostgres(t *testing.T) {
|
|
||||||
if *pgtest.ConnStr == "" {
|
|
||||||
t.Skip("Postgres flag missing, example: -postgres-test-db=" + pgtest.DefaultConnStr)
|
|
||||||
}
|
|
||||||
t.Parallel()
|
|
||||||
migrateTest(t, *pgtest.ConnStr)
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkSetup_Postgres(b *testing.B) {
|
|
||||||
if *pgtest.ConnStr == "" {
|
|
||||||
b.Skip("Postgres flag missing, example: -postgres-test-db=" + pgtest.DefaultConnStr)
|
|
||||||
}
|
|
||||||
b.Run("merged", func(b *testing.B) {
|
|
||||||
benchmarkSetup(b, *pgtest.ConnStr, true)
|
|
||||||
})
|
|
||||||
b.Run("separate", func(b *testing.B) {
|
|
||||||
benchmarkSetup(b, *pgtest.ConnStr, false)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkSetup_Cockroach(b *testing.B) {
|
|
||||||
if *pgtest.CrdbConnStr == "" {
|
|
||||||
b.Skip("Cockroach flag missing, example: -cockroach-test-db=" + pgtest.DefaultCrdbConnStr)
|
|
||||||
}
|
|
||||||
b.Run("merged", func(b *testing.B) {
|
|
||||||
benchmarkSetup(b, *pgtest.CrdbConnStr, true)
|
|
||||||
})
|
|
||||||
b.Run("separate", func(b *testing.B) {
|
|
||||||
benchmarkSetup(b, *pgtest.CrdbConnStr, false)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func benchmarkSetup(b *testing.B, connStr string, merged bool) {
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
func() {
|
|
||||||
ctx := context.Background()
|
|
||||||
log := zap.NewNop()
|
|
||||||
|
|
||||||
// create tempDB
|
|
||||||
tempDB, err := tempdb.OpenUnique(ctx, connStr, "migrate")
|
|
||||||
require.NoError(b, err)
|
|
||||||
defer func() { require.NoError(b, tempDB.Close()) }()
|
|
||||||
|
|
||||||
// create a new satellitedb connection
|
|
||||||
db, err := satellitedb.New(log, tempDB.ConnStr, satellitedb.Options{})
|
|
||||||
require.NoError(b, err)
|
|
||||||
defer func() { require.NoError(b, db.Close()) }()
|
|
||||||
|
|
||||||
if merged {
|
|
||||||
err = db.TestingCreateTables(ctx)
|
|
||||||
require.NoError(b, err)
|
|
||||||
} else {
|
|
||||||
err = db.CreateTables(ctx)
|
|
||||||
require.NoError(b, err)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// satelliteDB provides access to certain methods on a *satellitedb.satelliteDB
|
// satelliteDB provides access to certain methods on a *satellitedb.satelliteDB
|
||||||
// instance, since that type is not exported.
|
// instance, since that type is not exported.
|
||||||
@ -207,6 +143,8 @@ type satelliteDB interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func migrateTest(t *testing.T, connStr string) {
|
func migrateTest(t *testing.T, connStr string) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
ctx := testcontext.NewWithTimeout(t, 8*time.Minute)
|
ctx := testcontext.NewWithTimeout(t, 8*time.Minute)
|
||||||
defer ctx.Cleanup()
|
defer ctx.Cleanup()
|
||||||
|
|
||||||
@ -271,3 +209,50 @@ func migrateTest(t *testing.T, connStr string) {
|
|||||||
// verify that we also match the dbx version
|
// verify that we also match the dbx version
|
||||||
require.Equal(t, dbxschema, finalSchema, "result of all migration scripts did not match dbx schema")
|
require.Equal(t, dbxschema, finalSchema, "result of all migration scripts did not match dbx schema")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkSetup_Postgres(b *testing.B) {
|
||||||
|
connstr := pgtest.PickPostgres(b)
|
||||||
|
b.Run("merged", func(b *testing.B) {
|
||||||
|
benchmarkSetup(b, connstr, true)
|
||||||
|
})
|
||||||
|
b.Run("separate", func(b *testing.B) {
|
||||||
|
benchmarkSetup(b, connstr, false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkSetup_Cockroach(b *testing.B) {
|
||||||
|
connstr := pgtest.PickCockroach(b)
|
||||||
|
b.Run("merged", func(b *testing.B) {
|
||||||
|
benchmarkSetup(b, connstr, true)
|
||||||
|
})
|
||||||
|
b.Run("separate", func(b *testing.B) {
|
||||||
|
benchmarkSetup(b, connstr, false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func benchmarkSetup(b *testing.B, connStr string, merged bool) {
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
func() {
|
||||||
|
ctx := context.Background()
|
||||||
|
log := zap.NewNop()
|
||||||
|
|
||||||
|
// create tempDB
|
||||||
|
tempDB, err := tempdb.OpenUnique(ctx, connStr, "migrate")
|
||||||
|
require.NoError(b, err)
|
||||||
|
defer func() { require.NoError(b, tempDB.Close()) }()
|
||||||
|
|
||||||
|
// create a new satellitedb connection
|
||||||
|
db, err := satellitedb.New(log, tempDB.ConnStr, satellitedb.Options{})
|
||||||
|
require.NoError(b, err)
|
||||||
|
defer func() { require.NoError(b, db.Close()) }()
|
||||||
|
|
||||||
|
if merged {
|
||||||
|
err = db.TestingCreateTables(ctx)
|
||||||
|
require.NoError(b, err)
|
||||||
|
} else {
|
||||||
|
err = db.CreateTables(ctx)
|
||||||
|
require.NoError(b, err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
// Copyright (C) 2019 Storj Labs, Inc.
|
|
||||||
// See LICENSE for copying information.
|
|
||||||
|
|
||||||
package satellitedbtest
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/zeebo/errs"
|
|
||||||
|
|
||||||
"storj.io/storj/private/dbutil/pgutil/pgtest"
|
|
||||||
)
|
|
||||||
|
|
||||||
// PostgresDefined returns an error when the --postgres-test-db or STORJ_POSTGRES_TEST is not set for tests.
|
|
||||||
func PostgresDefined() error {
|
|
||||||
if *pgtest.ConnStr == "" {
|
|
||||||
return errs.New("flag --postgres-test-db or environment variable STORJ_POSTGRES_TEST not defined for PostgreSQL test database")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
@ -18,8 +18,8 @@ import (
|
|||||||
|
|
||||||
"storj.io/common/testcontext"
|
"storj.io/common/testcontext"
|
||||||
"storj.io/storj/private/dbutil"
|
"storj.io/storj/private/dbutil"
|
||||||
|
"storj.io/storj/private/dbutil/pgtest"
|
||||||
"storj.io/storj/private/dbutil/pgutil"
|
"storj.io/storj/private/dbutil/pgutil"
|
||||||
"storj.io/storj/private/dbutil/pgutil/pgtest"
|
|
||||||
"storj.io/storj/private/dbutil/tempdb"
|
"storj.io/storj/private/dbutil/tempdb"
|
||||||
"storj.io/storj/satellite"
|
"storj.io/storj/satellite"
|
||||||
"storj.io/storj/satellite/metainfo"
|
"storj.io/storj/satellite/metainfo"
|
||||||
@ -41,18 +41,24 @@ type Database struct {
|
|||||||
Message string
|
Message string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ignoreSkip struct{}
|
||||||
|
|
||||||
|
func (ignoreSkip) Skip(...interface{}) {}
|
||||||
|
|
||||||
// Databases returns default databases.
|
// Databases returns default databases.
|
||||||
func Databases() []SatelliteDatabases {
|
func Databases() []SatelliteDatabases {
|
||||||
|
cockroachConnStr := pgtest.PickCockroach(ignoreSkip{})
|
||||||
|
postgresConnStr := pgtest.PickPostgres(ignoreSkip{})
|
||||||
return []SatelliteDatabases{
|
return []SatelliteDatabases{
|
||||||
{
|
{
|
||||||
Name: "Postgres",
|
Name: "Postgres",
|
||||||
MasterDB: Database{"Postgres", *pgtest.ConnStr, "Postgres flag missing, example: -postgres-test-db=" + pgtest.DefaultConnStr + " or use STORJ_POSTGRES_TEST environment variable."},
|
MasterDB: Database{"Postgres", postgresConnStr, "Postgres flag missing, example: -postgres-test-db=" + pgtest.DefaultPostgres + " or use STORJ_POSTGRES_TEST environment variable."},
|
||||||
PointerDB: Database{"Postgres", *pgtest.ConnStr, ""},
|
PointerDB: Database{"Postgres", postgresConnStr, ""},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "Cockroach",
|
Name: "Cockroach",
|
||||||
MasterDB: Database{"Cockroach", *pgtest.CrdbConnStr, "Cockroach flag missing, example: -cockroach-test-db=" + pgtest.DefaultCrdbConnStr + " or use STORJ_COCKROACH_TEST environment variable."},
|
MasterDB: Database{"Cockroach", cockroachConnStr, "Cockroach flag missing, example: -cockroach-test-db=" + pgtest.DefaultCockroach + " or use STORJ_COCKROACH_TEST environment variable."},
|
||||||
PointerDB: Database{"Cockroach", *pgtest.CrdbConnStr, ""},
|
PointerDB: Database{"Cockroach", cockroachConnStr, ""},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,21 +11,19 @@ import (
|
|||||||
|
|
||||||
"storj.io/common/testcontext"
|
"storj.io/common/testcontext"
|
||||||
"storj.io/storj/private/dbutil/cockroachutil"
|
"storj.io/storj/private/dbutil/cockroachutil"
|
||||||
"storj.io/storj/private/dbutil/pgutil/pgtest"
|
"storj.io/storj/private/dbutil/pgtest"
|
||||||
"storj.io/storj/storage/testsuite"
|
"storj.io/storj/storage/testsuite"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newTestCockroachDB(ctx context.Context, t testing.TB) (store *Client, cleanup func()) {
|
func newTestCockroachDB(ctx context.Context, t testing.TB) (store *Client, cleanup func()) {
|
||||||
if *pgtest.CrdbConnStr == "" {
|
connstr := pgtest.PickCockroach(t)
|
||||||
t.Skipf("cockroach flag missing, example:\n-cockroach-test-db=%s", pgtest.DefaultCrdbConnStr)
|
|
||||||
}
|
|
||||||
|
|
||||||
tdb, err := cockroachutil.OpenUnique(ctx, *pgtest.CrdbConnStr, "test-schema")
|
tdb, err := cockroachutil.OpenUnique(ctx, connstr, "test-schema")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("init: %+v", err)
|
t.Fatalf("init: %+v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return NewWith(tdb.DB, *pgtest.CrdbConnStr), func() {
|
return NewWith(tdb.DB, connstr), func() {
|
||||||
if err := tdb.Close(); err != nil {
|
if err := tdb.Close(); err != nil {
|
||||||
t.Fatalf("failed to close db: %v", err)
|
t.Fatalf("failed to close db: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ import (
|
|||||||
"github.com/zeebo/errs"
|
"github.com/zeebo/errs"
|
||||||
|
|
||||||
"storj.io/common/testcontext"
|
"storj.io/common/testcontext"
|
||||||
"storj.io/storj/private/dbutil/pgutil/pgtest"
|
"storj.io/storj/private/dbutil/pgtest"
|
||||||
"storj.io/storj/private/dbutil/txutil"
|
"storj.io/storj/private/dbutil/txutil"
|
||||||
"storj.io/storj/private/tagsql"
|
"storj.io/storj/private/tagsql"
|
||||||
"storj.io/storj/storage"
|
"storj.io/storj/storage"
|
||||||
@ -21,11 +21,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func newTestPostgres(t testing.TB) (store *Client, cleanup func()) {
|
func newTestPostgres(t testing.TB) (store *Client, cleanup func()) {
|
||||||
if *pgtest.ConnStr == "" {
|
connstr := pgtest.PickPostgres(t)
|
||||||
t.Skipf("postgres flag missing, example:\n-postgres-test-db=%s", pgtest.DefaultConnStr)
|
|
||||||
}
|
|
||||||
|
|
||||||
pgdb, err := New(*pgtest.ConnStr)
|
pgdb, err := New(connstr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("init: %v", err)
|
t.Fatalf("init: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -675,4 +675,3 @@ func Schema() map[string]*dbschema.Schema {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user