storj/private/migrate/create_test.go
JT Olio 8e242cd012 dbutil: statically require all databases accesses to use contexts
this will allow for some nice runtime analysis down the road.
also, this allows for wrapping database handles in a way that
can interact with these contexts

requires https://review.dev.storj.io/c/storj/dbx/+/514

Change-Id: Ib087b7cd73296dd2c1e0331314da34d861f61d2b
2020-01-14 18:20:47 -05:00

129 lines
3.4 KiB
Go

// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.
package migrate_test
import (
"database/sql"
"strconv"
"testing"
_ "github.com/lib/pq"
_ "github.com/mattn/go-sqlite3"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"storj.io/common/testcontext"
"storj.io/storj/private/dbutil/dbwrap"
"storj.io/storj/private/dbutil/pgutil/pgtest"
"storj.io/storj/private/dbutil/tempdb"
"storj.io/storj/private/migrate"
)
func TestCreate_Sqlite(t *testing.T) {
ctx := testcontext.New(t)
defer ctx.Cleanup()
rdb, err := sql.Open("sqlite3", ":memory:")
if err != nil {
t.Fatal(err)
}
defer func() { assert.NoError(t, rdb.Close()) }()
db := dbwrap.SQLDB(rdb)
// should create table
err = migrate.Create(ctx, "example", &sqliteDB{db, "CREATE TABLE example_table (id text)"})
require.NoError(t, err)
// shouldn't create a new table
err = migrate.Create(ctx, "example", &sqliteDB{db, "CREATE TABLE example_table (id text)"})
require.NoError(t, err)
// should fail, because schema changed
err = migrate.Create(ctx, "example", &sqliteDB{db, "CREATE TABLE example_table (id text, version int)"})
require.Error(t, err)
// should fail, because of trying to CREATE TABLE with same name
err = migrate.Create(ctx, "conflict", &sqliteDB{db, "CREATE TABLE example_table (id text, version int)"})
require.Error(t, err)
}
func TestCreate_Postgres(t *testing.T) {
if *pgtest.ConnStr == "" {
t.Skipf("postgres flag missing, example:\n-postgres-test-db=%s", pgtest.DefaultConnStr)
}
ctx := testcontext.New(t)
defer ctx.Cleanup()
testCreateGeneric(ctx, t, *pgtest.ConnStr)
}
func TestCreate_Cockroach(t *testing.T) {
if *pgtest.CrdbConnStr == "" {
t.Skip("Cockroach flag missing, example: -cockroach-test-db=" + pgtest.DefaultCrdbConnStr)
}
ctx := testcontext.New(t)
defer ctx.Cleanup()
testCreateGeneric(ctx, t, *pgtest.CrdbConnStr)
}
func testCreateGeneric(ctx *testcontext.Context, t *testing.T, connStr string) {
rdb, err := tempdb.OpenUnique(ctx, connStr, "create-")
if err != nil {
t.Fatal(err)
}
defer func() { assert.NoError(t, rdb.Close()) }()
db := dbwrap.SQLDB(rdb.DB)
// should create table
err = migrate.Create(ctx, "example", &postgresDB{db, "CREATE TABLE example_table (id text)"})
require.NoError(t, err)
// shouldn't create a new table
err = migrate.Create(ctx, "example", &postgresDB{db, "CREATE TABLE example_table (id text)"})
require.NoError(t, err)
// should fail, because schema changed
err = migrate.Create(ctx, "example", &postgresDB{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, "CREATE TABLE example_table (id text, version integer)"})
require.Error(t, err)
}
type sqliteDB struct {
dbwrap.DB
schema string
}
func (db *sqliteDB) Rebind(s string) string { return s }
func (db *sqliteDB) Schema() string { return db.schema }
type postgresDB struct {
dbwrap.DB
schema string
}
func (db *postgresDB) Rebind(sql string) string {
out := make([]byte, 0, len(sql)+10)
j := 1
for i := 0; i < len(sql); i++ {
ch := sql[i]
if ch != '?' {
out = append(out, ch)
continue
}
out = append(out, '$')
out = append(out, strconv.Itoa(j)...)
j++
}
return string(out)
}
func (db *postgresDB) Schema() string { return db.schema }