refact: Add db.DB wrapper and refact all test fixtures to use it. (#1535)

* refact: Changes required for gorm v2

* refact: Add db.DB wrapper and refact all test fixtures to use it

Stop leaking the gorm abstraction within our unit tests.

* refact: Migrate direct calls to pq to pgx driver

The refactor will remove the remaining direct dependencies on
the pq driver which has been deprecated in favor of the pgx
driver.

It includes the addition of common.SqlOpen which is a wrapper around
sql.Open, which is needed to deal with the driver name changing from
"postgres" to "pgx" but in our code base the dialect and driver are
synonyms.
This commit is contained in:
Jim authored and GitHub committed 2021-09-30 09:17:27 -04:00
1 parent 136ac00b49
commit 8d6dee09a9
77 files changed
+441 -321

No files matched your search

+3
View File
@@ -86,6 +86,9 @@ the first place.
* github.com/kr/pretty * github.com/kr/pretty
* Jeff * Jeff
* github.com/lib/pq * github.com/lib/pq
* Jim
* Mike
* github.com/jackc/pgx
* Jim * Jim
* Mike * Mike
* github.com/mattn/go-colorable * github.com/mattn/go-colorable
+1 -2
View File
@@ -52,12 +52,11 @@ require (
github.com/hashicorp/vault/sdk v0.2.1 github.com/hashicorp/vault/sdk v0.2.1
github.com/iancoleman/strcase v0.2.0 github.com/iancoleman/strcase v0.2.0
github.com/jackc/pgconn v1.10.0 github.com/jackc/pgconn v1.10.0
github.com/jackc/pgx/v4 v4.11.0
github.com/jefferai/keyring v1.1.7-0.20210105022822-8749b3d9ce79 github.com/jefferai/keyring v1.1.7-0.20210105022822-8749b3d9ce79
github.com/jinzhu/gorm v1.9.12
github.com/json-iterator/go v1.1.10 // indirect github.com/json-iterator/go v1.1.10 // indirect
github.com/kr/pretty v0.3.0 github.com/kr/pretty v0.3.0
github.com/kr/text v0.2.0 github.com/kr/text v0.2.0
github.com/lib/pq v1.10.3
github.com/mattn/go-colorable v0.1.8 github.com/mattn/go-colorable v0.1.8
github.com/mattn/go-isatty v0.0.13 // indirect github.com/mattn/go-isatty v0.0.13 // indirect
github.com/mitchellh/cli v1.1.2 github.com/mitchellh/cli v1.1.2
+1 -2
View File
@@ -708,9 +708,8 @@ github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.6.0/go.mod h1:4vXEAYvW1fRQ2/FhZ78H73A60MHw1geSm145z2mdY1g= github.com/lib/pq v1.6.0/go.mod h1:4vXEAYvW1fRQ2/FhZ78H73A60MHw1geSm145z2mdY1g=
github.com/lib/pq v1.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg=
github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lib/pq v1.10.3 h1:v9QZf2Sn6AmjXtQeFpdoq/eaNtYP6IN+7lcrygsIAtg=
github.com/lib/pq v1.10.3/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
@@ -1160,7 +1160,7 @@ func TestRepository_UpdateAccount(t *testing.T) {
assert.Equal(tt.wantCount, gotCount, "row count") assert.Equal(tt.wantCount, gotCount, "row count")
assert.NotSame(tt.orig, got) assert.NotSame(tt.orig, got)
assert.Equal(tt.orig.AuthMethodId, got.AuthMethodId) assert.Equal(tt.orig.AuthMethodId, got.AuthMethodId)
underlyingDB, err := conn.DB() underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err) require.NoError(err)
dbassert := dbassert.New(t, underlyingDB) dbassert := dbassert.New(t, underlyingDB)
if tt.want.Name == "" { if tt.want.Name == "" {
@@ -952,7 +952,7 @@ func TestRepository_UpdateManagedGroup(t *testing.T) {
assert.Equal(tt.wantCount, gotCount, "row count") assert.Equal(tt.wantCount, gotCount, "row count")
assert.NotSame(tt.orig, got) assert.NotSame(tt.orig, got)
assert.Equal(tt.orig.AuthMethodId, got.AuthMethodId) assert.Equal(tt.orig.AuthMethodId, got.AuthMethodId)
underlyingDB, err := conn.DB() underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err) require.NoError(err)
dbassert := dbassert.New(t, underlyingDB) dbassert := dbassert.New(t, underlyingDB)
if tt.want.Name == "" { if tt.want.Name == "" {
+4 -5
View File
@@ -31,7 +31,6 @@ import (
wrapping "github.com/hashicorp/go-kms-wrapping" wrapping "github.com/hashicorp/go-kms-wrapping"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"google.golang.org/protobuf/types/known/timestamppb" "google.golang.org/protobuf/types/known/timestamppb"
"gorm.io/gorm"
) )
const TestFakeManagedGroupFilter = `"/foo" == "bar"` const TestFakeManagedGroupFilter = `"/foo" == "bar"`
@@ -41,7 +40,7 @@ const TestFakeManagedGroupFilter = `"/foo" == "bar"`
// WithSigningAlgs options are supported. // WithSigningAlgs options are supported.
func TestAuthMethod( func TestAuthMethod(
t *testing.T, t *testing.T,
conn *gorm.DB, conn *db.DB,
databaseWrapper wrapping.Wrapper, databaseWrapper wrapping.Wrapper,
scopeId string, scopeId string,
state AuthMethodState, state AuthMethodState,
@@ -158,7 +157,7 @@ func TestSortAuthMethods(t *testing.T, methods []*AuthMethod) {
} }
// TestAccount creates a test oidc auth account. // TestAccount creates a test oidc auth account.
func TestAccount(t *testing.T, conn *gorm.DB, am *AuthMethod, subject string, opt ...Option) *Account { func TestAccount(t *testing.T, conn *db.DB, am *AuthMethod, subject string, opt ...Option) *Account {
t.Helper() t.Helper()
require := require.New(t) require := require.New(t)
rw := db.New(conn) rw := db.New(conn)
@@ -179,7 +178,7 @@ func TestAccount(t *testing.T, conn *gorm.DB, am *AuthMethod, subject string, op
} }
// TestManagedGroup creates a test oidc managed group. // TestManagedGroup creates a test oidc managed group.
func TestManagedGroup(t *testing.T, conn *gorm.DB, am *AuthMethod, filter string, opt ...Option) *ManagedGroup { func TestManagedGroup(t *testing.T, conn *db.DB, am *AuthMethod, filter string, opt ...Option) *ManagedGroup {
t.Helper() t.Helper()
require := require.New(t) require := require.New(t)
rw := db.New(conn) rw := db.New(conn)
@@ -197,7 +196,7 @@ func TestManagedGroup(t *testing.T, conn *gorm.DB, am *AuthMethod, filter string
} }
// TestManagedGroupMember adds given account IDs to a managed group // TestManagedGroupMember adds given account IDs to a managed group
func TestManagedGroupMember(t *testing.T, conn *gorm.DB, managedGroupId, memberId string, opt ...Option) *ManagedGroupMemberAccount { func TestManagedGroupMember(t *testing.T, conn *db.DB, managedGroupId, memberId string, opt ...Option) *ManagedGroupMemberAccount {
t.Helper() t.Helper()
require := require.New(t) require := require.New(t)
rw := db.New(conn) rw := db.New(conn)
+1 -2
View File
@@ -10,7 +10,6 @@ import (
"github.com/hashicorp/boundary/internal/iam" "github.com/hashicorp/boundary/internal/iam"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gorm.io/gorm"
) )
func TestArgon2Configuration_New(t *testing.T) { func TestArgon2Configuration_New(t *testing.T) {
@@ -289,7 +288,7 @@ func TestArgon2Configuration_Validate(t *testing.T) {
} }
} }
func testArgon2Confs(t *testing.T, conn *gorm.DB, authMethodId string, count int) []*Argon2Configuration { func testArgon2Confs(t *testing.T, conn *db.DB, authMethodId string, count int) []*Argon2Configuration {
t.Helper() t.Helper()
assert, require := assert.New(t), require.New(t) assert, require := assert.New(t), require.New(t)
rw := db.New(conn) rw := db.New(conn)
@@ -589,6 +589,7 @@ func TestRepository_UpdateAccount(t *testing.T) {
wrapper := db.TestWrapper(t) wrapper := db.TestWrapper(t)
kms := kms.TestKms(t, conn, wrapper) kms := kms.TestKms(t, conn, wrapper)
iamRepo := iam.TestRepo(t, conn, wrapper) iamRepo := iam.TestRepo(t, conn, wrapper)
ctx := context.Background()
changeLoginName := func(s string) func(*Account) *Account { changeLoginName := func(s string) func(*Account) *Account {
return func(a *Account) *Account { return func(a *Account) *Account {
@@ -949,7 +950,7 @@ func TestRepository_UpdateAccount(t *testing.T) {
assert.Equal(tt.wantCount, gotCount, "row count") assert.Equal(tt.wantCount, gotCount, "row count")
assert.NotSame(tt.orig, got) assert.NotSame(tt.orig, got)
assert.Equal(tt.orig.AuthMethodId, got.AuthMethodId) assert.Equal(tt.orig.AuthMethodId, got.AuthMethodId)
underlyingDB, err := conn.DB() underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err) require.NoError(err)
dbassert := dbassert.New(t, underlyingDB) dbassert := dbassert.New(t, underlyingDB)
if tt.want.Name == "" { if tt.want.Name == "" {
@@ -769,7 +769,7 @@ func TestRepository_UpdateAuthMethod(t *testing.T) {
require.NoError(err) require.NoError(err)
assert.Empty(cmp.Diff(updatedAM, foundAuthMethod, protocmp.Transform())) assert.Empty(cmp.Diff(updatedAM, foundAuthMethod, protocmp.Transform()))
underlyingDB, err := conn.DB() underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err) require.NoError(err)
dbassert := dbassert.New(t, underlyingDB) dbassert := dbassert.New(t, underlyingDB)
if amToUpdate.Name == "" && contains(tt.args.fieldMaskPaths, "name") { if amToUpdate.Name == "" && contains(tt.args.fieldMaskPaths, "name") {
+4 -5
View File
@@ -8,13 +8,12 @@ import (
"github.com/hashicorp/boundary/internal/db" "github.com/hashicorp/boundary/internal/db"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gorm.io/gorm"
) )
// TestAuthMethod creates a password auth methods to the provided DB with the // TestAuthMethod creates a password auth methods to the provided DB with the
// provided scope id. If any errors are encountered during the creation of the // provided scope id. If any errors are encountered during the creation of the
// auth methods, the test will fail. // auth methods, the test will fail.
func TestAuthMethod(t *testing.T, conn *gorm.DB, scopeId string, opt ...Option) *AuthMethod { func TestAuthMethod(t *testing.T, conn *db.DB, scopeId string, opt ...Option) *AuthMethod {
t.Helper() t.Helper()
assert, require := assert.New(t), require.New(t) assert, require := assert.New(t), require.New(t)
w := db.New(conn) w := db.New(conn)
@@ -48,7 +47,7 @@ func TestAuthMethod(t *testing.T, conn *gorm.DB, scopeId string, opt ...Option)
// TestAuthMethods creates count number of password auth methods to the provided DB // TestAuthMethods creates count number of password auth methods to the provided DB
// with the provided scope id. If any errors are encountered during the creation of // with the provided scope id. If any errors are encountered during the creation of
// the auth methods, the test will fail. // the auth methods, the test will fail.
func TestAuthMethods(t *testing.T, conn *gorm.DB, scopeId string, count int) []*AuthMethod { func TestAuthMethods(t *testing.T, conn *db.DB, scopeId string, count int) []*AuthMethod {
t.Helper() t.Helper()
var auts []*AuthMethod var auts []*AuthMethod
for i := 0; i < count; i++ { for i := 0; i < count; i++ {
@@ -60,7 +59,7 @@ func TestAuthMethods(t *testing.T, conn *gorm.DB, scopeId string, count int) []*
// TestMultipleAccounts creates count number of password account to the provided DB // TestMultipleAccounts creates count number of password account to the provided DB
// with the provided auth method id. The auth method must have been created previously. // with the provided auth method id. The auth method must have been created previously.
// If any errors are encountered during the creation of the account, the test will fail. // If any errors are encountered during the creation of the account, the test will fail.
func TestMultipleAccounts(t *testing.T, conn *gorm.DB, authMethodId string, count int) []*Account { func TestMultipleAccounts(t *testing.T, conn *db.DB, authMethodId string, count int) []*Account {
t.Helper() t.Helper()
var auts []*Account var auts []*Account
for i := 0; i < count; i++ { for i := 0; i < count; i++ {
@@ -73,7 +72,7 @@ func TestMultipleAccounts(t *testing.T, conn *gorm.DB, authMethodId string, coun
// auth method id and loginName. The auth method must have been created // auth method id and loginName. The auth method must have been created
// previously. See password.NewAccount(...) for a list of supported options. // previously. See password.NewAccount(...) for a list of supported options.
// If any errors are encountered during the creation of the account, the test will fail. // If any errors are encountered during the creation of the account, the test will fail.
func TestAccount(t *testing.T, conn *gorm.DB, authMethodId, loginName string, opt ...Option) *Account { func TestAccount(t *testing.T, conn *db.DB, authMethodId, loginName string, opt ...Option) *Account {
t.Helper() t.Helper()
assert, require := assert.New(t), require.New(t) assert, require := assert.New(t), require.New(t)
require.NotEmpty(loginName) require.NotEmpty(loginName)
+1 -2
View File
@@ -9,10 +9,9 @@ import (
"github.com/hashicorp/boundary/internal/iam" "github.com/hashicorp/boundary/internal/iam"
"github.com/hashicorp/boundary/internal/kms" "github.com/hashicorp/boundary/internal/kms"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gorm.io/gorm"
) )
func TestAuthToken(t *testing.T, conn *gorm.DB, kms *kms.Kms, scopeId string, opt ...Option) *AuthToken { func TestAuthToken(t *testing.T, conn *db.DB, kms *kms.Kms, scopeId string, opt ...Option) *AuthToken {
t.Helper() t.Helper()
authMethod := password.TestAuthMethods(t, conn, scopeId, 1)[0] authMethod := password.TestAuthMethods(t, conn, scopeId, 1)[0]
// auth account is only used to join auth method to user. // auth account is only used to join auth method to user.
+1 -1
View File
@@ -94,7 +94,7 @@ func (b *Server) CreateDevDatabase(ctx context.Context, opt ...Option) error {
b.Info["dev database container"] = strings.TrimPrefix(container, "/") b.Info["dev database container"] = strings.TrimPrefix(container, "/")
} }
if err := b.ConnectToDatabase(dialect); err != nil { if err := b.ConnectToDatabase(ctx, dialect); err != nil {
if c != nil { if c != nil {
err = multierror.Append(err, c()) err = multierror.Append(err, c())
} }
@@ -4,11 +4,12 @@
package docker package docker
import ( import (
"database/sql"
"fmt" "fmt"
"os" "os"
"strings" "strings"
"github.com/hashicorp/boundary/internal/db/common"
_ "github.com/jackc/pgx/v4/stdlib"
"github.com/ory/dockertest/v3" "github.com/ory/dockertest/v3"
) )
@@ -37,7 +38,7 @@ func startDbInDockerSupported(dialect string, opt ...Option) (cleanup func() err
} }
switch dialect { switch dialect {
case "postgres": case "postgres", "pgx":
switch { switch {
case os.Getenv("BOUNDARY_TESTING_PG_URL") != "": case os.Getenv("BOUNDARY_TESTING_PG_URL") != "":
url = os.Getenv("BOUNDARY_TESTING_PG_URL") url = os.Getenv("BOUNDARY_TESTING_PG_URL")
@@ -68,7 +69,7 @@ func startDbInDockerSupported(dialect string, opt ...Option) (cleanup func() err
} }
if err := pool.Retry(func() error { if err := pool.Retry(func() error {
db, err := sql.Open(dialect, url) db, err := common.SqlOpen(dialect, url)
if err != nil { if err != nil {
return fmt.Errorf("error opening %s dev container: %w", dialect, err) return fmt.Errorf("error opening %s dev container: %w", dialect, err)
} }
+11 -31
View File
@@ -39,8 +39,6 @@ import (
"github.com/hashicorp/go-secure-stdlib/strutil" "github.com/hashicorp/go-secure-stdlib/strutil"
"github.com/mitchellh/cli" "github.com/mitchellh/cli"
"google.golang.org/grpc/grpclog" "google.golang.org/grpc/grpclog"
"gorm.io/gorm"
"gorm.io/gorm/logger"
) )
const ( const (
@@ -120,7 +118,7 @@ type Server struct {
DatabaseMaxOpenConnections int DatabaseMaxOpenConnections int
DevDatabaseCleanupFunc func() error DevDatabaseCleanupFunc func() error
Database *gorm.DB Database *db.DB
// StatusGracePeriodDuration represents the period of time (as a // StatusGracePeriodDuration represents the period of time (as a
// duration) that the controller will wait before marking // duration) that the controller will wait before marking
@@ -548,38 +546,22 @@ func (b *Server) RunShutdownFuncs() error {
return mErr.ErrorOrNil() return mErr.ErrorOrNil()
} }
func (b *Server) ConnectToDatabase(dialect string) error { func (b *Server) ConnectToDatabase(ctx context.Context, dialect string) error {
dbType, err := db.StringToDbType(dialect) dbType, err := db.StringToDbType(dialect)
if err != nil { if err != nil {
return fmt.Errorf("unable to create db object with dialect %s: %w", dialect, err) return fmt.Errorf("unable to create db object with dialect %s: %w", dialect, err)
} }
dbase, err := db.Open(dbType, b.DatabaseUrl) opts := []db.Option{
db.WithMaxOpenConnections(b.DatabaseMaxOpenConnections),
}
if os.Getenv("BOUNDARY_DISABLE_GORM_FORMATTER") == "" {
opts = append(opts, db.WithGormFormatter(b.Logger))
}
dbase, err := db.Open(dbType, b.DatabaseUrl, opts...)
if err != nil { if err != nil {
return fmt.Errorf("unable to create db object with dialect %s: %w", dialect, err) return fmt.Errorf("unable to create db object with dialect %s: %w", dialect, err)
} }
if b.DatabaseMaxOpenConnections == 1 {
return fmt.Errorf("unable to create db object with dialect %s: %s", dialect, "max_open_connections must be unlimited by setting 0 or at least 2")
} else {
underlyingDB, err := dbase.DB()
if err != nil {
return fmt.Errorf("unable retreive db: %w", err)
}
underlyingDB.SetMaxOpenConns(b.DatabaseMaxOpenConnections)
}
b.Database = dbase b.Database = dbase
if os.Getenv("BOUNDARY_DISABLE_GORM_FORMATTER") == "" {
newLogger := logger.New(
db.GetGormLogger(b.Logger),
logger.Config{
LogLevel: logger.Error, // Log level
Colorful: false, // Disable color
},
)
dbase = dbase.Session(&gorm.Session{Logger: newLogger})
}
b.Database = dbase
return nil return nil
} }
@@ -618,13 +600,11 @@ func (b *Server) CreateGlobalKmsKeys(ctx context.Context) error {
return nil return nil
} }
func (b *Server) DestroyDevDatabase() error { func (b *Server) DestroyDevDatabase(ctx context.Context) error {
if b.Database != nil { if b.Database != nil {
underlyingDB, err := b.Database.DB() if err := b.Database.Close(ctx); err != nil {
if err != nil {
return err return err
} }
underlyingDB.Close()
} }
if b.DevDatabaseCleanupFunc != nil { if b.DevDatabaseCleanupFunc != nil {
return b.DevDatabaseCleanupFunc() return b.DevDatabaseCleanupFunc()
+2 -2
View File
@@ -2,10 +2,10 @@ package database
import ( import (
"context" "context"
"database/sql"
"fmt" "fmt"
"github.com/hashicorp/boundary/internal/cmd/base" "github.com/hashicorp/boundary/internal/cmd/base"
"github.com/hashicorp/boundary/internal/db/common"
"github.com/hashicorp/boundary/internal/db/schema" "github.com/hashicorp/boundary/internal/db/schema"
"github.com/hashicorp/boundary/internal/errors" "github.com/hashicorp/boundary/internal/errors"
"github.com/mitchellh/cli" "github.com/mitchellh/cli"
@@ -20,7 +20,7 @@ func migrateDatabase(ctx context.Context, ui cli.Ui, dialect, u string, initiali
noop := func() {} noop := func() {}
// This database is used to keep an exclusive lock on the database for the // This database is used to keep an exclusive lock on the database for the
// remainder of the command // remainder of the command
dBase, err := sql.Open(dialect, u) dBase, err := common.SqlOpen(dialect, u)
if err != nil { if err != nil {
ui.Error(fmt.Errorf("Error establishing db connection: %w", err).Error()) ui.Error(fmt.Errorf("Error establishing db connection: %w", err).Error())
return noop, 2 return noop, 2
+10 -10
View File
@@ -2,10 +2,10 @@ package database
import ( import (
"context" "context"
"database/sql"
"testing" "testing"
"github.com/hashicorp/boundary/internal/cmd/base" "github.com/hashicorp/boundary/internal/cmd/base"
"github.com/hashicorp/boundary/internal/db/common"
"github.com/hashicorp/boundary/internal/db/schema" "github.com/hashicorp/boundary/internal/db/schema"
"github.com/hashicorp/boundary/testing/dbtest" "github.com/hashicorp/boundary/testing/dbtest"
"github.com/mitchellh/cli" "github.com/mitchellh/cli"
@@ -49,7 +49,7 @@ func TestMigrateDatabase(t *testing.T) {
require.NoError(t, c()) require.NoError(t, c())
}) })
dBase, err := sql.Open(dialect, u) dBase, err := common.SqlOpen(dialect, u)
require.NoError(t, err) require.NoError(t, err)
earlyMigrationVersion := 2000 earlyMigrationVersion := 2000
@@ -75,7 +75,7 @@ func TestMigrateDatabase(t *testing.T) {
require.NoError(t, c()) require.NoError(t, c())
}) })
dBase, err := sql.Open(dialect, u) dBase, err := common.SqlOpen(dialect, u)
require.NoError(t, err) require.NoError(t, err)
earlyMigrationVersion := 2000 earlyMigrationVersion := 2000
@@ -100,7 +100,7 @@ func TestMigrateDatabase(t *testing.T) {
t.Cleanup(func() { t.Cleanup(func() {
require.NoError(t, c()) require.NoError(t, c())
}) })
dBase, err := sql.Open(dialect, u) dBase, err := common.SqlOpen(dialect, u)
require.NoError(t, err) require.NoError(t, err)
createStmt := `create table if not exists schema_migrations (version bigint primary key, dirty boolean not null)` createStmt := `create table if not exists schema_migrations (version bigint primary key, dirty boolean not null)`
@@ -120,7 +120,7 @@ func TestMigrateDatabase(t *testing.T) {
t.Cleanup(func() { t.Cleanup(func() {
require.NoError(t, c()) require.NoError(t, c())
}) })
dBase, err := sql.Open(dialect, u) dBase, err := common.SqlOpen(dialect, u)
require.NoError(t, err) require.NoError(t, err)
createStmt := `create table if not exists schema_migrations (version bigint primary key, dirty boolean not null)` createStmt := `create table if not exists schema_migrations (version bigint primary key, dirty boolean not null)`
@@ -154,7 +154,7 @@ func TestMigrateDatabase(t *testing.T) {
t.Cleanup(func() { t.Cleanup(func() {
require.NoError(t, c()) require.NoError(t, c())
}) })
dBase, err := sql.Open(dialect, u) dBase, err := common.SqlOpen(dialect, u)
require.NoError(t, err) require.NoError(t, err)
man, err := schema.NewManager(ctx, dialect, dBase) man, err := schema.NewManager(ctx, dialect, dBase)
@@ -177,7 +177,7 @@ func TestMigrateDatabase(t *testing.T) {
t.Cleanup(func() { t.Cleanup(func() {
require.NoError(t, c()) require.NoError(t, c())
}) })
dBase, err := sql.Open(dialect, u) dBase, err := common.SqlOpen(dialect, u)
require.NoError(t, err) require.NoError(t, err)
man, err := schema.NewManager(ctx, dialect, dBase) man, err := schema.NewManager(ctx, dialect, dBase)
@@ -217,7 +217,7 @@ func TestVerifyOplogIsEmpty(t *testing.T) {
}) })
_ = c _ = c
dBase, err := sql.Open(dialect, u) dBase, err := common.SqlOpen(dialect, u)
require.NoError(t, err) require.NoError(t, err)
man, err := schema.NewManager(ctx, dialect, dBase) man, err := schema.NewManager(ctx, dialect, dBase)
@@ -228,7 +228,7 @@ func TestVerifyOplogIsEmpty(t *testing.T) {
cmd.srv = base.NewServer(&base.Command{UI: cmd.UI}) cmd.srv = base.NewServer(&base.Command{UI: cmd.UI})
cmd.srv.DatabaseUrl = u cmd.srv.DatabaseUrl = u
require.NoError(t, cmd.srv.ConnectToDatabase(dialect)) require.NoError(t, cmd.srv.ConnectToDatabase(ctx, dialect))
assert.NoError(t, cmd.verifyOplogIsEmpty()) assert.NoError(t, cmd.verifyOplogIsEmpty(ctx))
} }
+6 -4
View File
@@ -1,6 +1,7 @@
package database package database
import ( import (
"context"
"fmt" "fmt"
"github.com/hashicorp/boundary/internal/cmd/base" "github.com/hashicorp/boundary/internal/cmd/base"
@@ -164,6 +165,7 @@ func (c *InitCommand) AutocompleteFlags() complete.Flags {
} }
func (c *InitCommand) Run(args []string) (retCode int) { func (c *InitCommand) Run(args []string) (retCode int) {
ctx := context.Background()
if result := c.ParseFlagsAndConfig(args); result > 0 { if result := c.ParseFlagsAndConfig(args); result > 0 {
return result return result
} }
@@ -277,11 +279,11 @@ func (c *InitCommand) Run(args []string) (retCode int) {
return base.CommandUserError return base.CommandUserError
} }
// Everything after is done with normal database URL and is affecting actual data // Everything after is done with normal database URL and is affecting actual data
if err := c.srv.ConnectToDatabase(dialect); err != nil { if err := c.srv.ConnectToDatabase(ctx, dialect); err != nil {
c.UI.Error(fmt.Errorf("Error connecting to database after migrations: %w", err).Error()) c.UI.Error(fmt.Errorf("Error connecting to database after migrations: %w", err).Error())
return base.CommandCliError return base.CommandCliError
} }
if err := c.verifyOplogIsEmpty(); err != nil { if err := c.verifyOplogIsEmpty(ctx); err != nil {
c.UI.Error(fmt.Sprintf("The database appears to have already been initialized: %v", err)) c.UI.Error(fmt.Sprintf("The database appears to have already been initialized: %v", err))
return base.CommandCliError return base.CommandCliError
} }
@@ -491,9 +493,9 @@ func (c *InitCommand) ParseFlagsAndConfig(args []string) int {
return base.CommandSuccess return base.CommandSuccess
} }
func (c *InitCommand) verifyOplogIsEmpty() error { func (c *InitCommand) verifyOplogIsEmpty(ctx context.Context) error {
const op = "database.(InitCommand).verifyOplogIsEmpty" const op = "database.(InitCommand).verifyOplogIsEmpty"
underlyingDB, err := c.srv.Database.DB() underlyingDB, err := c.srv.Database.SqlDB(ctx)
if err != nil { if err != nil {
return errors.NewDeprecated(errors.Internal, op, "unable to retreive db", errors.WithWrap(err)) return errors.NewDeprecated(errors.Internal, op, "unable to retreive db", errors.WithWrap(err))
} }
+1 -1
View File
@@ -556,7 +556,7 @@ func (c *Command) Run(args []string) int {
} }
if !c.flagDisableDatabaseDestruction { if !c.flagDisableDatabaseDestruction {
c.ShutdownFuncs = append(c.ShutdownFuncs, c.DestroyDevDatabase) c.ShutdownFuncs = append(c.ShutdownFuncs, func() error { return c.DestroyDevDatabase(ctx) })
} }
default: default:
c.DatabaseUrl, err = parseutil.ParsePath(c.flagDatabaseUrl) c.DatabaseUrl, err = parseutil.ParsePath(c.flagDatabaseUrl)
+2 -2
View File
@@ -389,12 +389,12 @@ func (c *Command) Run(args []string) int {
} }
c.DatabaseMaxOpenConnections = c.Config.Controller.Database.MaxOpenConnections c.DatabaseMaxOpenConnections = c.Config.Controller.Database.MaxOpenConnections
if err := c.ConnectToDatabase("postgres"); err != nil { if err := c.ConnectToDatabase(ctx, "postgres"); err != nil {
c.UI.Error(fmt.Errorf("Error connecting to database: %w", err).Error()) c.UI.Error(fmt.Errorf("Error connecting to database: %w", err).Error())
return base.CommandCliError return base.CommandCliError
} }
underlyingDB, err := c.Database.DB() underlyingDB, err := c.Database.SqlDB(ctx)
if err != nil { if err != nil {
c.UI.Error(fmt.Errorf("Can't get db: %w.", err).Error()) c.UI.Error(fmt.Errorf("Can't get db: %w.", err).Error())
return base.CommandCliError return base.CommandCliError
+2 -3
View File
@@ -21,7 +21,6 @@ import (
vault "github.com/hashicorp/vault/api" vault "github.com/hashicorp/vault/api"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gorm.io/gorm"
) )
const testUpdateTokenStatusExpirationQuery = ` const testUpdateTokenStatusExpirationQuery = `
@@ -33,7 +32,7 @@ update credential_vault_token
` `
func testVaultToken(t *testing.T, func testVaultToken(t *testing.T,
conn *gorm.DB, conn *db.DB,
wrapper wrapping.Wrapper, wrapper wrapping.Wrapper,
v *TestVaultServer, v *TestVaultServer,
cs *CredentialStore, cs *CredentialStore,
@@ -87,7 +86,7 @@ func testVaultToken(t *testing.T,
} }
func testVaultCred(t *testing.T, func testVaultCred(t *testing.T,
conn *gorm.DB, conn *db.DB,
v *TestVaultServer, v *TestVaultServer,
cl *CredentialLibrary, cl *CredentialLibrary,
sess *session.Session, sess *session.Session,
@@ -795,7 +795,7 @@ func TestRepository_UpdateCredentialLibrary(t *testing.T) {
assert.Equal(tt.wantCount, gotCount, "row count") assert.Equal(tt.wantCount, gotCount, "row count")
assert.NotSame(tt.orig, got) assert.NotSame(tt.orig, got)
assert.Equal(tt.orig.StoreId, got.StoreId) assert.Equal(tt.orig.StoreId, got.StoreId)
underlyingDB, err := conn.DB() underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err) require.NoError(err)
dbassert := dbassert.New(t, underlyingDB) dbassert := dbassert.New(t, underlyingDB)
if tt.want.Name == "" { if tt.want.Name == "" {
@@ -23,7 +23,6 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"google.golang.org/protobuf/testing/protocmp" "google.golang.org/protobuf/testing/protocmp"
"gorm.io/gorm"
) )
func TestRepository_CreateCredentialStoreResource(t *testing.T) { func TestRepository_CreateCredentialStoreResource(t *testing.T) {
@@ -756,7 +755,7 @@ func TestRepository_UpdateCredentialStore_Attributes(t *testing.T) {
assert.Equal(tt.wantCount, gotCount, "row count") assert.Equal(tt.wantCount, gotCount, "row count")
assert.NotSame(tt.orig, got) assert.NotSame(tt.orig, got)
assert.Equal(tt.orig.ScopeId, got.ScopeId) assert.Equal(tt.orig.ScopeId, got.ScopeId)
underlyingDB, err := conn.DB() underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err) require.NoError(err)
dbassert := dbassert.New(t, underlyingDB) dbassert := dbassert.New(t, underlyingDB)
if tt.want.Name == "" { if tt.want.Name == "" {
@@ -887,7 +886,7 @@ func TestRepository_UpdateCredentialStore_Attributes(t *testing.T) {
assert.Equal(1, gotCount2, "count of updated records") assert.Equal(1, gotCount2, "count of updated records")
require.NotNil(got2) require.NotNil(got2)
assert.Nil(got2.CaCert) assert.Nil(got2.CaCert)
underlyingDB, err := conn.DB() underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err) require.NoError(err)
dbassert := dbassert.New(t, underlyingDB) dbassert := dbassert.New(t, underlyingDB)
dbassert.IsNull(got2, "CaCert") dbassert.IsNull(got2, "CaCert")
@@ -1270,9 +1269,9 @@ func TestRepository_DeleteCredentialStore(t *testing.T) {
type tokenMap map[string]*tokenCount type tokenMap map[string]*tokenCount
type setupFn func(t *testing.T, conn *gorm.DB) (storeId string, libs []*CredentialLibrary, tokens tokenMap, repo *Repository) type setupFn func(t *testing.T, conn *db.DB) (storeId string, libs []*CredentialLibrary, tokens tokenMap, repo *Repository)
baseSetup := func(t *testing.T, conn *gorm.DB) (wrapper wrapping.Wrapper, repo *Repository, scopeId string) { baseSetup := func(t *testing.T, conn *db.DB) (wrapper wrapping.Wrapper, repo *Repository, scopeId string) {
wrapper = db.TestWrapper(t) wrapper = db.TestWrapper(t)
kms := kms.TestKms(t, conn, wrapper) kms := kms.TestKms(t, conn, wrapper)
sche := scheduler.TestScheduler(t, conn, wrapper) sche := scheduler.TestScheduler(t, conn, wrapper)
@@ -1286,7 +1285,7 @@ func TestRepository_DeleteCredentialStore(t *testing.T) {
return return
} }
testStores := func(t *testing.T, conn *gorm.DB, wrapper wrapping.Wrapper, tokens tokenMap, scopeId string, count int) ([]*CredentialStore, tokenMap) { testStores := func(t *testing.T, conn *db.DB, wrapper wrapping.Wrapper, tokens tokenMap, scopeId string, count int) ([]*CredentialStore, tokenMap) {
if tokens == nil { if tokens == nil {
tokens = make(tokenMap) tokens = make(tokenMap)
} }
@@ -1299,13 +1298,13 @@ func TestRepository_DeleteCredentialStore(t *testing.T) {
return css, tokens return css, tokens
} }
makeMaintainingTokens := func(t *testing.T, conn *gorm.DB, wrapper wrapping.Wrapper, tokens tokenMap, scopeId, storeId string, count int) tokenMap { makeMaintainingTokens := func(t *testing.T, conn *db.DB, wrapper wrapping.Wrapper, tokens tokenMap, scopeId, storeId string, count int) tokenMap {
testTokens(t, conn, wrapper, scopeId, storeId, count) testTokens(t, conn, wrapper, scopeId, storeId, count)
tokens[storeId].maintaining = count tokens[storeId].maintaining = count
return tokens return tokens
} }
makeRevokedTokens := func(t *testing.T, conn *gorm.DB, wrapper wrapping.Wrapper, tokens tokenMap, scopeId, storeId string, count int) tokenMap { makeRevokedTokens := func(t *testing.T, conn *db.DB, wrapper wrapping.Wrapper, tokens tokenMap, scopeId, storeId string, count int) tokenMap {
require.NotNil(t, tokens) require.NotNil(t, tokens)
const query = ` const query = `
update credential_vault_token update credential_vault_token
@@ -1327,7 +1326,7 @@ update credential_vault_token
return tokens return tokens
} }
makeExpiredTokens := func(t *testing.T, conn *gorm.DB, wrapper wrapping.Wrapper, tokens tokenMap, scopeId, storeId string, count int) tokenMap { makeExpiredTokens := func(t *testing.T, conn *db.DB, wrapper wrapping.Wrapper, tokens tokenMap, scopeId, storeId string, count int) tokenMap {
require.NotNil(t, tokens) require.NotNil(t, tokens)
const query = ` const query = `
update credential_vault_token update credential_vault_token
@@ -1349,7 +1348,7 @@ update credential_vault_token
return tokens return tokens
} }
assertTokens := func(t *testing.T, conn *gorm.DB, want tokenMap) { assertTokens := func(t *testing.T, conn *db.DB, want tokenMap) {
const query = ` const query = `
select store_id, status, count(token_hmac) select store_id, status, count(token_hmac)
from credential_vault_token from credential_vault_token
@@ -1399,7 +1398,7 @@ group by store_id, status;
}{ }{
{ {
name: "simple", name: "simple",
setup: func(t *testing.T, conn *gorm.DB) (storeId string, libs []*CredentialLibrary, tokens tokenMap, repo *Repository) { setup: func(t *testing.T, conn *db.DB) (storeId string, libs []*CredentialLibrary, tokens tokenMap, repo *Repository) {
wrapper, repo, scopeId := baseSetup(t, conn) wrapper, repo, scopeId := baseSetup(t, conn)
css, tokens := testStores(t, conn, wrapper, nil, scopeId, 1) css, tokens := testStores(t, conn, wrapper, nil, scopeId, 1)
cs := css[0] cs := css[0]
@@ -1409,7 +1408,7 @@ group by store_id, status;
}, },
{ {
name: "with-libraries", name: "with-libraries",
setup: func(t *testing.T, conn *gorm.DB) (storeId string, libs []*CredentialLibrary, tokens tokenMap, repo *Repository) { setup: func(t *testing.T, conn *db.DB) (storeId string, libs []*CredentialLibrary, tokens tokenMap, repo *Repository) {
wrapper, repo, scopeId := baseSetup(t, conn) wrapper, repo, scopeId := baseSetup(t, conn)
css, tokens := testStores(t, conn, wrapper, nil, scopeId, 1) css, tokens := testStores(t, conn, wrapper, nil, scopeId, 1)
cs := css[0] cs := css[0]
@@ -1421,7 +1420,7 @@ group by store_id, status;
}, },
{ {
name: "with-maintaining-tokens", name: "with-maintaining-tokens",
setup: func(t *testing.T, conn *gorm.DB) (storeId string, libs []*CredentialLibrary, tokens tokenMap, repo *Repository) { setup: func(t *testing.T, conn *db.DB) (storeId string, libs []*CredentialLibrary, tokens tokenMap, repo *Repository) {
wrapper, repo, scopeId := baseSetup(t, conn) wrapper, repo, scopeId := baseSetup(t, conn)
css, tokens := testStores(t, conn, wrapper, nil, scopeId, 1) css, tokens := testStores(t, conn, wrapper, nil, scopeId, 1)
cs := css[0] cs := css[0]
@@ -1434,7 +1433,7 @@ group by store_id, status;
}, },
{ {
name: "with-revoked-tokens", name: "with-revoked-tokens",
setup: func(t *testing.T, conn *gorm.DB) (storeId string, libs []*CredentialLibrary, tokens tokenMap, repo *Repository) { setup: func(t *testing.T, conn *db.DB) (storeId string, libs []*CredentialLibrary, tokens tokenMap, repo *Repository) {
wrapper, repo, scopeId := baseSetup(t, conn) wrapper, repo, scopeId := baseSetup(t, conn)
css, tokens := testStores(t, conn, wrapper, nil, scopeId, 1) css, tokens := testStores(t, conn, wrapper, nil, scopeId, 1)
cs := css[0] cs := css[0]
@@ -1447,7 +1446,7 @@ group by store_id, status;
}, },
{ {
name: "with-expired-tokens", name: "with-expired-tokens",
setup: func(t *testing.T, conn *gorm.DB) (storeId string, libs []*CredentialLibrary, tokens tokenMap, repo *Repository) { setup: func(t *testing.T, conn *db.DB) (storeId string, libs []*CredentialLibrary, tokens tokenMap, repo *Repository) {
wrapper, repo, scopeId := baseSetup(t, conn) wrapper, repo, scopeId := baseSetup(t, conn)
css, tokens := testStores(t, conn, wrapper, nil, scopeId, 1) css, tokens := testStores(t, conn, wrapper, nil, scopeId, 1)
cs := css[0] cs := css[0]
@@ -1460,7 +1459,7 @@ group by store_id, status;
}, },
{ {
name: "with-all-token-statuses", name: "with-all-token-statuses",
setup: func(t *testing.T, conn *gorm.DB) (storeId string, libs []*CredentialLibrary, tokens tokenMap, repo *Repository) { setup: func(t *testing.T, conn *db.DB) (storeId string, libs []*CredentialLibrary, tokens tokenMap, repo *Repository) {
wrapper, repo, scopeId := baseSetup(t, conn) wrapper, repo, scopeId := baseSetup(t, conn)
css, tokens := testStores(t, conn, wrapper, nil, scopeId, 1) css, tokens := testStores(t, conn, wrapper, nil, scopeId, 1)
cs := css[0] cs := css[0]
+4 -3
View File
@@ -5,7 +5,6 @@ package vault
import ( import (
"crypto/tls" "crypto/tls"
"database/sql"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
@@ -16,8 +15,10 @@ import (
"testing" "testing"
"time" "time"
"github.com/hashicorp/boundary/internal/db/common"
"github.com/hashicorp/go-rootcerts" "github.com/hashicorp/go-rootcerts"
vault "github.com/hashicorp/vault/api" vault "github.com/hashicorp/vault/api"
_ "github.com/jackc/pgx/v4/stdlib"
"github.com/ory/dockertest/v3" "github.com/ory/dockertest/v3"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@@ -224,7 +225,7 @@ func gotMountDatabase(t *testing.T, v *TestVaultServer, opt ...TestOption) *Test
dburl := fmt.Sprintf(dbUrlTemplate, "postgres", "password") dburl := fmt.Sprintf(dbUrlTemplate, "postgres", "password")
err = pool.Retry(func() error { err = pool.Retry(func() error {
var err error var err error
db, err := sql.Open("postgres", dburl) db, err := common.SqlOpen("postgres", dburl)
if err != nil { if err != nil {
return err return err
} }
@@ -244,7 +245,7 @@ func gotMountDatabase(t *testing.T, v *TestVaultServer, opt ...TestOption) *Test
grantClosedRole = `grant select, insert, update, delete on boundary_closed to closed_role` grantClosedRole = `grant select, insert, update, delete on boundary_closed to closed_role`
) )
db, err := sql.Open("postgres", dburl) db, err := common.SqlOpen("postgres", dburl)
require.NoError(err) require.NoError(err)
defer db.Close() defer db.Close()
+8 -9
View File
@@ -7,7 +7,6 @@ import (
"crypto/rand" "crypto/rand"
"crypto/x509" "crypto/x509"
"crypto/x509/pkix" "crypto/x509/pkix"
"database/sql"
"encoding/pem" "encoding/pem"
"fmt" "fmt"
"math/big" "math/big"
@@ -19,6 +18,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/hashicorp/boundary/internal/db/common"
"github.com/hashicorp/boundary/internal/errors" "github.com/hashicorp/boundary/internal/errors"
"github.com/hashicorp/boundary/internal/db" "github.com/hashicorp/boundary/internal/db"
@@ -28,14 +28,13 @@ import (
vault "github.com/hashicorp/vault/api" vault "github.com/hashicorp/vault/api"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gorm.io/gorm"
) )
// TestCredentialStore creates a vault credential store in the provided DB with // TestCredentialStore creates a vault credential store in the provided DB with
// the provided scope, vault address, token, and accessor and any values passed // the provided scope, vault address, token, and accessor and any values passed
// in through the Options vargs. If any errors are encountered during the // in through the Options vargs. If any errors are encountered during the
// creation of the store, the test will fail. // creation of the store, the test will fail.
func TestCredentialStore(t *testing.T, conn *gorm.DB, wrapper wrapping.Wrapper, scopeId, vaultAddr, vaultToken, accessor string, opts ...Option) *CredentialStore { func TestCredentialStore(t *testing.T, conn *db.DB, wrapper wrapping.Wrapper, scopeId, vaultAddr, vaultToken, accessor string, opts ...Option) *CredentialStore {
t.Helper() t.Helper()
ctx := context.Background() ctx := context.Background()
kmsCache := kms.TestKms(t, conn, wrapper) kmsCache := kms.TestKms(t, conn, wrapper)
@@ -76,7 +75,7 @@ func TestCredentialStore(t *testing.T, conn *gorm.DB, wrapper wrapping.Wrapper,
// the provided DB with the provided scope id. If any errors are // the provided DB with the provided scope id. If any errors are
// encountered during the creation of the credential stores, the test will // encountered during the creation of the credential stores, the test will
// fail. // fail.
func TestCredentialStores(t *testing.T, conn *gorm.DB, wrapper wrapping.Wrapper, scopeId string, count int) []*CredentialStore { func TestCredentialStores(t *testing.T, conn *db.DB, wrapper wrapping.Wrapper, scopeId string, count int) []*CredentialStore {
t.Helper() t.Helper()
ctx := context.Background() ctx := context.Background()
kmsCache := kms.TestKms(t, conn, wrapper) kmsCache := kms.TestKms(t, conn, wrapper)
@@ -114,7 +113,7 @@ func TestCredentialStores(t *testing.T, conn *gorm.DB, wrapper wrapping.Wrapper,
// libraries in the provided DB with the provided store id. If any errors // libraries in the provided DB with the provided store id. If any errors
// are encountered during the creation of the credential libraries, the // are encountered during the creation of the credential libraries, the
// test will fail. // test will fail.
func TestCredentialLibraries(t *testing.T, conn *gorm.DB, _ wrapping.Wrapper, storeId string, count int) []*CredentialLibrary { func TestCredentialLibraries(t *testing.T, conn *db.DB, _ wrapping.Wrapper, storeId string, count int) []*CredentialLibrary {
t.Helper() t.Helper()
assert, require := assert.New(t), require.New(t) assert, require := assert.New(t), require.New(t)
w := db.New(conn) w := db.New(conn)
@@ -145,7 +144,7 @@ func TestCredentialLibraries(t *testing.T, conn *gorm.DB, _ wrapping.Wrapper, st
// TestCredentials creates count number of vault credentials in the provided DB with // TestCredentials creates count number of vault credentials in the provided DB with
// the provided library id and session id. If any errors are encountered // the provided library id and session id. If any errors are encountered
// during the creation of the credentials, the test will fail. // during the creation of the credentials, the test will fail.
func TestCredentials(t *testing.T, conn *gorm.DB, wrapper wrapping.Wrapper, libraryId, sessionId string, count int) []*Credential { func TestCredentials(t *testing.T, conn *db.DB, wrapper wrapping.Wrapper, libraryId, sessionId string, count int) []*Credential {
t.Helper() t.Helper()
assert, require := assert.New(t), require.New(t) assert, require := assert.New(t), require.New(t)
rw := db.New(conn) rw := db.New(conn)
@@ -189,7 +188,7 @@ func TestCredentials(t *testing.T, conn *gorm.DB, wrapper wrapping.Wrapper, libr
return credentials return credentials
} }
func createTestToken(t *testing.T, conn *gorm.DB, wrapper wrapping.Wrapper, scopeId, storeId, token, accessor string) *Token { func createTestToken(t *testing.T, conn *db.DB, wrapper wrapping.Wrapper, scopeId, storeId, token, accessor string) *Token {
t.Helper() t.Helper()
w := db.New(conn) w := db.New(conn)
ctx := context.Background() ctx := context.Background()
@@ -211,7 +210,7 @@ func createTestToken(t *testing.T, conn *gorm.DB, wrapper wrapping.Wrapper, scop
return inToken return inToken
} }
func testTokens(t *testing.T, conn *gorm.DB, wrapper wrapping.Wrapper, scopeId, storeId string, count int) []*Token { func testTokens(t *testing.T, conn *db.DB, wrapper wrapping.Wrapper, scopeId, storeId string, count int) []*Token {
t.Helper() t.Helper()
assert, require := assert.New(t), require.New(t) assert, require := assert.New(t), require.New(t)
w := db.New(conn) w := db.New(conn)
@@ -871,7 +870,7 @@ func (d *TestDatabase) ValidateCredential(t *testing.T, s *vault.Secret) error {
require := require.New(t) require := require.New(t)
require.NotNil(s) require.NotNil(s)
dburl := d.URL.Encode(t, s) dburl := d.URL.Encode(t, s)
db, err := sql.Open("postgres", dburl) db, err := common.SqlOpen("postgres", dburl)
if err != nil { if err != nil {
return err return err
} }
+7 -5
View File
@@ -1,6 +1,7 @@
package dbassert package dbassert
import ( import (
"context"
"testing" "testing"
"github.com/hashicorp/boundary/internal/db" "github.com/hashicorp/boundary/internal/db"
@@ -10,7 +11,6 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gorm.io/gorm"
) )
func Test_FieldDomain(t *testing.T) { func Test_FieldDomain(t *testing.T) {
@@ -59,11 +59,12 @@ func Test_FieldNullable(t *testing.T) {
func Test_FieldIsNull(t *testing.T) { func Test_FieldIsNull(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
assert := assert.New(t) assert := assert.New(t)
conn, _ := db.TestSetup(t, "postgres") conn, _ := db.TestSetup(t, "postgres")
initStore(t, conn) initStore(t, conn)
require := require.New(t) require := require.New(t)
underlyingDB, err := conn.DB() underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err) require.NoError(err)
assert.NoError(err) assert.NoError(err)
mockery := new(dbassert.MockTesting) mockery := new(dbassert.MockTesting)
@@ -82,10 +83,11 @@ func Test_FieldIsNull(t *testing.T) {
func Test_FieldNotNull(t *testing.T) { func Test_FieldNotNull(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
conn, _ := db.TestSetup(t, "postgres") conn, _ := db.TestSetup(t, "postgres")
initStore(t, conn) initStore(t, conn)
require := require.New(t) require := require.New(t)
underlyingDB, err := conn.DB() underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err) require.NoError(err)
mockery := new(dbassert.MockTesting) mockery := new(dbassert.MockTesting)
dbassert := New(mockery, underlyingDB) dbassert := New(mockery, underlyingDB)
@@ -113,7 +115,7 @@ type testModel struct {
func (*testModel) TableName() string { return "test_table_dbasserts" } func (*testModel) TableName() string { return "test_table_dbasserts" }
// CreateTestModel is a helper that creates a testModel in the DB. // CreateTestModel is a helper that creates a testModel in the DB.
func createTestModel(t dbassert.TestingT, db *gorm.DB, nullable *string, typeInt *int) *testModel { func createTestModel(t dbassert.TestingT, db *db.DB, nullable *string, typeInt *int) *testModel {
publicId, err := base62.Random(12) publicId, err := base62.Random(12)
assert.NoError(t, err) assert.NoError(t, err)
m := testModel{ m := testModel{
@@ -126,7 +128,7 @@ func createTestModel(t dbassert.TestingT, db *gorm.DB, nullable *string, typeInt
return &m return &m
} }
func initStore(t *testing.T, db *gorm.DB) { func initStore(t *testing.T, db *db.DB) {
t.Helper() t.Helper()
const ( const (
createDomainType = ` createDomainType = `
+15
View File
@@ -0,0 +1,15 @@
package common
import (
"database/sql"
_ "github.com/jackc/pgx/v4"
)
func SqlOpen(driverName, dataSourceName string) (*sql.DB, error) {
switch driverName {
case "postgres", "pgx":
driverName = "pgx"
}
return sql.Open(driverName, dataSourceName)
}
+65 -5
View File
@@ -2,14 +2,18 @@ package db
import ( import (
"context" "context"
"database/sql"
stderrors "errors" stderrors "errors"
"fmt" "fmt"
"github.com/hashicorp/boundary/internal/errors"
"github.com/hashicorp/boundary/internal/observability/event" "github.com/hashicorp/boundary/internal/observability/event"
"github.com/hashicorp/go-hclog" "github.com/hashicorp/go-hclog"
"github.com/jackc/pgconn" "github.com/jackc/pgconn"
_ "github.com/jackc/pgx/v4"
"gorm.io/driver/postgres" "gorm.io/driver/postgres"
"gorm.io/gorm" "gorm.io/gorm"
"gorm.io/gorm/logger"
) )
type DbType int type DbType int
@@ -34,9 +38,44 @@ func StringToDbType(dialect string) (DbType, error) {
} }
} }
// Open a database connection which is long-lived. // DB is a wrapper around the ORM
// You need to call Close() on the returned gorm.DB type DB struct {
func Open(dbType DbType, connectionUrl string) (*gorm.DB, error) { *gorm.DB
}
// SqlDB returns the underlying sql.DB
//
// Note: This func is not named DB(), because our choice of ORM (gorm) which is
// embedded for various reasons, already exports a DB() func and it's base type
// is also an export DB type
func (d *DB) SqlDB(ctx context.Context) (*sql.DB, error) {
const op = "db.(DB).SqlDB"
if d.DB == nil {
return nil, errors.New(ctx, errors.Internal, op, "missing underlying database")
}
return d.DB.DB()
}
// Close the underlying sql.DB
func (d *DB) Close(ctx context.Context) error {
const op = "db.(DB).Close"
if d.DB == nil {
return errors.New(ctx, errors.Internal, op, "missing underlying database")
}
underlying, err := d.DB.DB()
if err != nil {
return errors.Wrap(ctx, err, op)
}
return underlying.Close()
}
// Open a database connection which is long-lived. The options of
// WithGormFormatter and WithMaxOpenConnections are supported.
//
// Note: Consider if you need to call Close() on the returned DB. Typically the
// answer is no, but there are occasions when it's necessary. See the sql.DB
// docs for more information.
func Open(dbType DbType, connectionUrl string, opt ...Option) (*DB, error) {
var dialect gorm.Dialector var dialect gorm.Dialector
switch dbType { switch dbType {
case Postgres: case Postgres:
@@ -52,7 +91,28 @@ func Open(dbType DbType, connectionUrl string) (*gorm.DB, error) {
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to open database: %w", err) return nil, fmt.Errorf("unable to open database: %w", err)
} }
return db, nil opts := GetOpts(opt...)
if opts.withGormFormatter != nil {
newLogger := logger.New(
getGormLogger(opts.withGormFormatter),
logger.Config{
LogLevel: logger.Error, // Log level
Colorful: false, // Disable color
},
)
db = db.Session(&gorm.Session{Logger: newLogger})
}
if opts.withMaxOpenConnections > 0 {
if dialect.Name() == "postgres" && opts.withMaxOpenConnections == 1 {
return nil, fmt.Errorf("unable to create db object with dialect %s: %s", dialect, "max_open_connections must be unlimited by setting 0 or at least 2")
}
underlyingDB, err := db.DB()
if err != nil {
return nil, fmt.Errorf("unable retreive db: %w", err)
}
underlyingDB.SetMaxOpenConns(opts.withMaxOpenConnections)
}
return &DB{db}, nil
} }
func GetGormLogFormatter(log hclog.Logger) func(values ...interface{}) (messages []interface{}) { func GetGormLogFormatter(log hclog.Logger) func(values ...interface{}) (messages []interface{}) {
@@ -85,6 +145,6 @@ func (g gormLogger) Printf(msg string, values ...interface{}) {
} }
} }
func GetGormLogger(log hclog.Logger) gormLogger { func getGormLogger(log hclog.Logger) gormLogger {
return gormLogger{logger: log} return gormLogger{logger: log}
} }
+3 -1
View File
@@ -1,6 +1,7 @@
package db package db
import ( import (
"context"
"testing" "testing"
"github.com/hashicorp/boundary/testing/dbtest" "github.com/hashicorp/boundary/testing/dbtest"
@@ -8,6 +9,7 @@ import (
) )
func TestOpen(t *testing.T) { func TestOpen(t *testing.T) {
ctx := context.Background()
cleanup, url, _, err := dbtest.StartUsingTemplate(dbtest.Postgres) cleanup, url, _, err := dbtest.StartUsingTemplate(dbtest.Postgres)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
@@ -48,7 +50,7 @@ func TestOpen(t *testing.T) {
got, err := Open(tt.args.dbType, tt.args.connectionUrl) got, err := Open(tt.args.dbType, tt.args.connectionUrl)
defer func() { defer func() {
if err == nil { if err == nil {
sqlDB, err := got.DB() sqlDB, err := got.SqlDB(ctx)
require.NoError(t, err) require.NoError(t, err)
err = sqlDB.Close() err = sqlDB.Close()
require.NoError(t, err) require.NoError(t, err)
+36 -31
View File
@@ -1,6 +1,7 @@
package db package db
import ( import (
"context"
"strings" "strings"
"testing" "testing"
"time" "time"
@@ -25,8 +26,10 @@ returning id;
` `
) )
ctx := context.Background()
conn, _ := TestSetup(t, "postgres") conn, _ := TestSetup(t, "postgres")
db, err := conn.DB() db, err := conn.SqlDB(ctx)
require.NoError(t, err) require.NoError(t, err)
for _, typ := range []string{"public", "private", "role", "scope"} { for _, typ := range []string{"public", "private", "role", "scope"} {
@@ -107,9 +110,9 @@ insert into test_table
values ($1); values ($1);
` `
) )
ctx := context.Background()
conn, _ := TestSetup(t, "postgres") conn, _ := TestSetup(t, "postgres")
db, err := conn.DB() db, err := conn.SqlDB(ctx)
require.NoError(t, err) require.NoError(t, err)
if _, err := db.Exec(createTable); err != nil { if _, err := db.Exec(createTable); err != nil {
@@ -179,9 +182,9 @@ insert into test_table
values ($1); values ($1);
` `
) )
ctx := context.Background()
conn, _ := TestSetup(t, "postgres") conn, _ := TestSetup(t, "postgres")
db, err := conn.DB() db, err := conn.SqlDB(ctx)
require.NoError(t, err) require.NoError(t, err)
if _, err := db.Exec(createTable); err != nil { if _, err := db.Exec(createTable); err != nil {
@@ -256,8 +259,9 @@ returning id;
` `
) )
ctx := context.Background()
conn, _ := TestSetup(t, "postgres") conn, _ := TestSetup(t, "postgres")
db, err := conn.DB() db, err := conn.SqlDB(ctx)
require.NoError(t, err) require.NoError(t, err)
if _, err := db.Exec(createTable); err != nil { if _, err := db.Exec(createTable); err != nil {
t.Fatalf("query: \n%s\n error: %s", createTable, err) t.Fatalf("query: \n%s\n error: %s", createTable, err)
@@ -322,9 +326,9 @@ update test_update_time_column
set update_time = null; set update_time = null;
` `
) )
ctx := context.Background()
conn, _ := TestSetup(t, "postgres") conn, _ := TestSetup(t, "postgres")
db, err := conn.DB() db, err := conn.SqlDB(ctx)
require.NoError(t, err) require.NoError(t, err)
_, err = db.Exec(createTable) _, err = db.Exec(createTable)
assert.NoError(err) assert.NoError(err)
@@ -396,8 +400,8 @@ returning public_id;
) )
conn, _ := TestSetup(t, "postgres") conn, _ := TestSetup(t, "postgres")
assert, require := assert.New(t), require.New(t) assert, require := assert.New(t), require.New(t)
ctx := context.Background()
db, err := conn.DB() db, err := conn.SqlDB(ctx)
require.NoError(err) require.NoError(err)
_, err = db.Exec(createTable) _, err = db.Exec(createTable)
@@ -457,8 +461,8 @@ returning private_id;
) )
conn, _ := TestSetup(t, "postgres") conn, _ := TestSetup(t, "postgres")
assert, require := assert.New(t), require.New(t) assert, require := assert.New(t), require.New(t)
ctx := context.Background()
db, err := conn.DB() db, err := conn.SqlDB(ctx)
require.NoError(err) require.NoError(err)
_, err = db.Exec(createTable) _, err = db.Exec(createTable)
@@ -491,8 +495,9 @@ returning private_id;
} }
func TestDomain_DefaultUsersExist(t *testing.T) { func TestDomain_DefaultUsersExist(t *testing.T) {
ctx := context.Background()
conn, _ := TestSetup(t, "postgres") conn, _ := TestSetup(t, "postgres")
db, err := conn.DB() db, err := conn.SqlDB(ctx)
require.NoError(t, err) require.NoError(t, err)
for _, val := range []string{"u_anon", "u_auth"} { for _, val := range []string{"u_anon", "u_auth"} {
rows, err := db.Query(`select from iam_user where public_id = $1`, val) rows, err := db.Query(`select from iam_user where public_id = $1`, val)
@@ -579,9 +584,9 @@ set id = null;
Name string Name string
Updatable string Updatable string
} }
ctx := context.Background()
conn, _ := TestSetup(t, "postgres") conn, _ := TestSetup(t, "postgres")
db, err := conn.DB() db, err := conn.SqlDB(ctx)
require.NoError(t, err) require.NoError(t, err)
_, err = db.Exec(createTable) _, err = db.Exec(createTable)
assert.NoError(t, err) assert.NoError(t, err)
@@ -693,9 +698,9 @@ values ($1)
returning id; returning id;
` `
) )
ctx := context.Background()
conn, _ := TestSetup(t, "postgres") conn, _ := TestSetup(t, "postgres")
db, err := conn.DB() db, err := conn.SqlDB(ctx)
require.NoError(t, err) require.NoError(t, err)
if _, err := db.Exec(createTable); err != nil { if _, err := db.Exec(createTable); err != nil {
@@ -741,9 +746,9 @@ values ($1)
returning id; returning id;
` `
) )
ctx := context.Background()
conn, _ := TestSetup(t, "postgres") conn, _ := TestSetup(t, "postgres")
db, err := conn.DB() db, err := conn.SqlDB(ctx)
require.NoError(t, err) require.NoError(t, err)
if _, err := db.Exec(createTable); err != nil { if _, err := db.Exec(createTable); err != nil {
@@ -788,9 +793,9 @@ values ($1)
returning id; returning id;
` `
) )
ctx := context.Background()
conn, _ := TestSetup(t, "postgres") conn, _ := TestSetup(t, "postgres")
db, err := conn.DB() db, err := conn.SqlDB(ctx)
require.NoError(t, err) require.NoError(t, err)
if _, err := db.Exec(createTable); err != nil { if _, err := db.Exec(createTable); err != nil {
@@ -835,9 +840,9 @@ values ($1)
returning id; returning id;
` `
) )
ctx := context.Background()
conn, _ := TestSetup(t, "postgres") conn, _ := TestSetup(t, "postgres")
db, err := conn.DB() db, err := conn.SqlDB(ctx)
require.NoError(t, err) require.NoError(t, err)
if _, err := db.Exec(createTable); err != nil { if _, err := db.Exec(createTable); err != nil {
@@ -882,9 +887,9 @@ values ($1)
returning id; returning id;
` `
) )
ctx := context.Background()
conn, _ := TestSetup(t, "postgres") conn, _ := TestSetup(t, "postgres")
db, err := conn.DB() db, err := conn.SqlDB(ctx)
require.NoError(t, err) require.NoError(t, err)
if _, err := db.Exec(createTable); err != nil { if _, err := db.Exec(createTable); err != nil {
@@ -929,9 +934,9 @@ values ($1)
returning id; returning id;
` `
) )
ctx := context.Background()
conn, _ := TestSetup(t, "postgres") conn, _ := TestSetup(t, "postgres")
db, err := conn.DB() db, err := conn.SqlDB(ctx)
require.NoError(t, err) require.NoError(t, err)
if _, err := db.Exec(createTable); err != nil { if _, err := db.Exec(createTable); err != nil {
@@ -980,9 +985,9 @@ func TestDomain_wt_is_sentinel(t *testing.T) {
select wt_is_sentinel($1); select wt_is_sentinel($1);
` `
) )
ctx := context.Background()
conn, _ := TestSetup(t, "postgres") conn, _ := TestSetup(t, "postgres")
db, err := conn.DB() db, err := conn.SqlDB(ctx)
require.NoError(t, err) require.NoError(t, err)
tests := []struct { tests := []struct {
@@ -1043,9 +1048,9 @@ insert on test_not_null_columns
` `
dropTriggers = `drop trigger test_insert_not_null_columns on test_not_null_columns` dropTriggers = `drop trigger test_insert_not_null_columns on test_not_null_columns`
) )
ctx := context.Background()
conn, _ := TestSetup(t, "postgres") conn, _ := TestSetup(t, "postgres")
db, err := conn.DB() db, err := conn.SqlDB(ctx)
assert.NoError(t, err) assert.NoError(t, err)
_, err = db.Exec(createTable) _, err = db.Exec(createTable)
+20
View File
@@ -2,6 +2,7 @@ package db
import ( import (
"github.com/hashicorp/boundary/internal/oplog" "github.com/hashicorp/boundary/internal/oplog"
"github.com/hashicorp/go-hclog"
wrapping "github.com/hashicorp/go-kms-wrapping" wrapping "github.com/hashicorp/go-kms-wrapping"
) )
@@ -43,6 +44,9 @@ type Options struct {
// withPrngValues is used to switch the ID generation to a pseudo-random mode // withPrngValues is used to switch the ID generation to a pseudo-random mode
withPrngValues []string withPrngValues []string
withGormFormatter hclog.Logger
withMaxOpenConnections int
} }
type oplogOpts struct { type oplogOpts struct {
@@ -165,3 +169,19 @@ func WithPrngValues(withPrngValues []string) Option {
o.withPrngValues = withPrngValues o.withPrngValues = withPrngValues
} }
} }
// WithGormFormatter specifies an optional hclog to use for gorm's log
// formmater
func WithGormFormatter(l hclog.Logger) Option {
return func(o *Options) {
o.withGormFormatter = l
}
}
// WithMaxOpenConnections specifices and optional max open connections for the
// database
func WithMaxOpenConnections(max int) Option {
return func(o *Options) {
o.withMaxOpenConnections = max
}
}
+27
View File
@@ -4,6 +4,7 @@ import (
"testing" "testing"
"github.com/hashicorp/boundary/internal/oplog" "github.com/hashicorp/boundary/internal/oplog"
"github.com/hashicorp/go-hclog"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@@ -175,4 +176,30 @@ func Test_getOpts(t *testing.T) {
testOpts.withOrder = "version desc" testOpts.withOrder = "version desc"
assert.Equal(opts, testOpts) assert.Equal(opts, testOpts)
}) })
t.Run("WithGormFormatter", func(t *testing.T) {
assert := assert.New(t)
// test default of false
opts := GetOpts()
testOpts := getDefaultOptions()
assert.Equal(opts, testOpts)
testLogger := hclog.New(&hclog.LoggerOptions{})
// try setting to false
opts = GetOpts(WithGormFormatter(testLogger))
testOpts.withGormFormatter = testLogger
assert.Equal(opts, testOpts)
})
t.Run("WithMaxOpenConnections", func(t *testing.T) {
assert := assert.New(t)
// test default of false
opts := GetOpts()
testOpts := getDefaultOptions()
assert.Equal(opts, testOpts)
// try setting to false
opts = GetOpts(WithMaxOpenConnections(22))
testOpts.withMaxOpenConnections = 22
assert.Equal(opts, testOpts)
})
} }
+11 -11
View File
@@ -190,7 +190,7 @@ type VetForWriter interface {
// Db uses a gorm DB connection for read/write // Db uses a gorm DB connection for read/write
type Db struct { type Db struct {
underlying *gorm.DB underlying *DB
} }
// ensure that Db implements the interfaces of: Reader and Writer // ensure that Db implements the interfaces of: Reader and Writer
@@ -199,7 +199,7 @@ var (
_ Writer = (*Db)(nil) _ Writer = (*Db)(nil)
) )
func New(underlying *gorm.DB) *Db { func New(underlying *DB) *Db {
return &Db{underlying: underlying} return &Db{underlying: underlying}
} }
@@ -597,7 +597,7 @@ func (rw *Db) Delete(ctx context.Context, i interface{}, opt ...Option) (int, er
return NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get ticket")) return NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get ticket"))
} }
} }
db := rw.underlying db := rw.underlying.DB
if opts.withWhereClause != "" { if opts.withWhereClause != "" {
db = db.Where(opts.withWhereClause, opts.withWhereClauseArgs...) db = db.Where(opts.withWhereClause, opts.withWhereClauseArgs...)
} }
@@ -713,7 +713,7 @@ func (rw *Db) getTicketFor(aggregateName string) (*store.Ticket, error) {
if rw.underlying == nil { if rw.underlying == nil {
return nil, errors.NewDeprecated(errors.InvalidParameter, op, fmt.Sprintf("%s: underlying db missing", aggregateName), errors.WithoutEvent()) return nil, errors.NewDeprecated(errors.InvalidParameter, op, fmt.Sprintf("%s: underlying db missing", aggregateName), errors.WithoutEvent())
} }
ticketer, err := oplog.NewGormTicketer(rw.underlying, oplog.WithAggregateNames(true)) ticketer, err := oplog.NewGormTicketer(rw.underlying.DB, oplog.WithAggregateNames(true))
if err != nil { if err != nil {
return nil, errors.WrapDeprecated(err, op, errors.WithMsg(fmt.Sprintf("%s: unable to get Ticketer", aggregateName)), errors.WithoutEvent()) return nil, errors.WrapDeprecated(err, op, errors.WithMsg(fmt.Sprintf("%s: unable to get Ticketer", aggregateName)), errors.WithoutEvent())
} }
@@ -793,7 +793,7 @@ func (rw *Db) addOplogForItems(ctx context.Context, opType OpType, opts Options,
if err != nil { if err != nil {
return errors.Wrap(ctx, err, op, errors.WithMsg("oplog validation failed"), errors.WithoutEvent()) return errors.Wrap(ctx, err, op, errors.WithMsg("oplog validation failed"), errors.WithoutEvent())
} }
ticketer, err := oplog.NewGormTicketer(rw.underlying, oplog.WithAggregateNames(true)) ticketer, err := oplog.NewGormTicketer(rw.underlying.DB, oplog.WithAggregateNames(true))
if err != nil { if err != nil {
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to get Ticketer"), errors.WithoutEvent()) return errors.Wrap(ctx, err, op, errors.WithMsg("unable to get Ticketer"), errors.WithoutEvent())
} }
@@ -808,7 +808,7 @@ func (rw *Db) addOplogForItems(ctx context.Context, opType OpType, opts Options,
} }
if err := entry.WriteEntryWith( if err := entry.WriteEntryWith(
ctx, ctx,
&oplog.GormWriter{Tx: rw.underlying}, &oplog.GormWriter{Tx: rw.underlying.DB},
ticket, ticket,
oplogMsgs..., oplogMsgs...,
); err != nil { ); err != nil {
@@ -827,7 +827,7 @@ func (rw *Db) addOplog(ctx context.Context, opType OpType, opts Options, ticket
if ticket == nil { if ticket == nil {
return errors.New(ctx, errors.InvalidParameter, op, "missing ticket", errors.WithoutEvent()) return errors.New(ctx, errors.InvalidParameter, op, "missing ticket", errors.WithoutEvent())
} }
ticketer, err := oplog.NewGormTicketer(rw.underlying, oplog.WithAggregateNames(true)) ticketer, err := oplog.NewGormTicketer(rw.underlying.DB, oplog.WithAggregateNames(true))
if err != nil { if err != nil {
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to get Ticketer"), errors.WithoutEvent()) return errors.Wrap(ctx, err, op, errors.WithMsg("unable to get Ticketer"), errors.WithoutEvent())
} }
@@ -846,7 +846,7 @@ func (rw *Db) addOplog(ctx context.Context, opType OpType, opts Options, ticket
} }
err = entry.WriteEntryWith( err = entry.WriteEntryWith(
ctx, ctx,
&oplog.GormWriter{Tx: rw.underlying}, &oplog.GormWriter{Tx: rw.underlying.DB},
ticket, ticket,
msg, msg,
) )
@@ -876,7 +876,7 @@ func (rw *Db) WriteOplogEntryWith(ctx context.Context, wrapper wrapping.Wrapper,
return errors.New(ctx, errors.InvalidParameter, op, "missing metadata") return errors.New(ctx, errors.InvalidParameter, op, "missing metadata")
} }
ticketer, err := oplog.NewGormTicketer(rw.underlying, oplog.WithAggregateNames(true)) ticketer, err := oplog.NewGormTicketer(rw.underlying.DB, oplog.WithAggregateNames(true))
if err != nil { if err != nil {
return errors.Wrap(ctx, err, op, errors.WithMsg("unable to get Ticketer")) return errors.Wrap(ctx, err, op, errors.WithMsg("unable to get Ticketer"))
} }
@@ -892,7 +892,7 @@ func (rw *Db) WriteOplogEntryWith(ctx context.Context, wrapper wrapping.Wrapper,
} }
err = entry.WriteEntryWith( err = entry.WriteEntryWith(
ctx, ctx,
&oplog.GormWriter{Tx: rw.underlying}, &oplog.GormWriter{Tx: rw.underlying.DB},
ticket, ticket,
msgs..., msgs...,
) )
@@ -947,7 +947,7 @@ func (w *Db) DoTx(ctx context.Context, retries uint, backOff Backoff, Handler Tx
newTx := w.underlying.WithContext(ctx) newTx := w.underlying.WithContext(ctx)
newTx = newTx.Begin() newTx = newTx.Begin()
rw := &Db{newTx} rw := &Db{underlying: &DB{newTx}}
if err := Handler(rw, rw); err != nil { if err := Handler(rw, rw); err != nil {
if err := newTx.Rollback().Error; err != nil { if err := newTx.Rollback().Error; err != nil {
return info, errors.Wrap(ctx, err, op, errors.WithoutEvent()) return info, errors.Wrap(ctx, err, op, errors.WithoutEvent())
+10 -11
View File
@@ -22,7 +22,6 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"google.golang.org/protobuf/proto" "google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/timestamppb" "google.golang.org/protobuf/types/known/timestamppb"
"gorm.io/gorm"
) )
func TestDb_UpdateUnsetField(t *testing.T) { func TestDb_UpdateUnsetField(t *testing.T) {
@@ -1270,7 +1269,7 @@ func TestDb_Delete(t *testing.T) {
} }
tests := []struct { tests := []struct {
name string name string
underlying *gorm.DB underlying *DB
wrapper wrapping.Wrapper wrapper wrapping.Wrapper
args args args args
want int want int
@@ -1540,7 +1539,7 @@ func TestDb_CreateItems(t *testing.T) {
} }
tests := []struct { tests := []struct {
name string name string
underlying *gorm.DB underlying *DB
args args args args
wantOplogId string wantOplogId string
wantOplogMsgs bool wantOplogMsgs bool
@@ -1741,7 +1740,7 @@ func TestDb_DeleteItems(t *testing.T) {
} }
tests := []struct { tests := []struct {
name string name string
underlying *gorm.DB underlying *DB
args args args args
wantRowsDeleted int wantRowsDeleted int
wantOplogId string wantOplogId string
@@ -1914,7 +1913,7 @@ func TestDb_DeleteItems(t *testing.T) {
} }
} }
func testUser(t *testing.T, conn *gorm.DB, name, email, phoneNumber string) *db_test.TestUser { func testUser(t *testing.T, conn *DB, name, email, phoneNumber string) *db_test.TestUser {
t.Helper() t.Helper()
require := require.New(t) require := require.New(t)
@@ -1935,7 +1934,7 @@ func testUser(t *testing.T, conn *gorm.DB, name, email, phoneNumber string) *db_
return u return u
} }
func testCar(t *testing.T, conn *gorm.DB, name, model string, mpg int32) *db_test.TestCar { func testCar(t *testing.T, conn *DB, name, model string, mpg int32) *db_test.TestCar {
t.Helper() t.Helper()
require := require.New(t) require := require.New(t)
@@ -1964,7 +1963,7 @@ func testId(t *testing.T) string {
return id return id
} }
func testScooter(t *testing.T, conn *gorm.DB, model string, mpg int32) *db_test.TestScooter { func testScooter(t *testing.T, conn *DB, model string, mpg int32) *db_test.TestScooter {
t.Helper() t.Helper()
require := require.New(t) require := require.New(t)
@@ -1995,7 +1994,7 @@ func TestDb_LookupById(t *testing.T) {
} }
tests := []struct { tests := []struct {
name string name string
underlying *gorm.DB underlying *DB
args args args args
wantErr bool wantErr bool
want proto.Message want proto.Message
@@ -2095,7 +2094,7 @@ func TestDb_GetTicket(t *testing.T) {
type notReplayable struct{} type notReplayable struct{}
tests := []struct { tests := []struct {
name string name string
underlying *gorm.DB underlying *DB
aggregateType interface{} aggregateType interface{}
wantErr bool wantErr bool
wantErrIs errors.Code wantErrIs errors.Code
@@ -2181,7 +2180,7 @@ func TestDb_WriteOplogEntryWith(t *testing.T) {
} }
tests := []struct { tests := []struct {
name string name string
underlying *gorm.DB underlying *DB
args args args args
wantErr bool wantErr bool
wantErrIs errors.Code wantErrIs errors.Code
@@ -2889,7 +2888,7 @@ func TestDb_lookupAfterWrite(t *testing.T) {
} }
tests := []struct { tests := []struct {
name string name string
underlying *gorm.DB underlying *DB
args args args args
wantErr bool wantErr bool
want proto.Message want proto.Message
+12 -11
View File
@@ -7,6 +7,7 @@ import (
"strings" "strings"
"testing" "testing"
"github.com/hashicorp/boundary/internal/db/common"
"github.com/hashicorp/boundary/internal/db/schema/postgres" "github.com/hashicorp/boundary/internal/db/schema/postgres"
"github.com/hashicorp/boundary/internal/errors" "github.com/hashicorp/boundary/internal/errors"
"github.com/hashicorp/boundary/testing/dbtest" "github.com/hashicorp/boundary/testing/dbtest"
@@ -22,7 +23,7 @@ func TestNewManager(t *testing.T) {
t.Cleanup(func() { t.Cleanup(func() {
require.NoError(t, c()) require.NoError(t, c())
}) })
d, err := sql.Open(dialect, u) d, err := common.SqlOpen(dialect, u)
require.NoError(t, err) require.NoError(t, err)
ctx := context.Background() ctx := context.Background()
@@ -47,7 +48,7 @@ func TestCurrentState(t *testing.T) {
}) })
require.NoError(t, err) require.NoError(t, err)
ctx := context.Background() ctx := context.Background()
d, err := sql.Open(dialect, u) d, err := common.SqlOpen(dialect, u)
require.NoError(t, err) require.NoError(t, err)
m, err := NewManager(ctx, dialect, d) m, err := NewManager(ctx, dialect, d)
@@ -83,7 +84,7 @@ func TestRollForward(t *testing.T) {
t.Cleanup(func() { t.Cleanup(func() {
require.NoError(t, c()) require.NoError(t, c())
}) })
d, err := sql.Open(dialect, u) d, err := common.SqlOpen(dialect, u)
require.NoError(t, err) require.NoError(t, err)
ctx := context.Background() ctx := context.Background()
@@ -112,7 +113,7 @@ func TestRollForward_NotFromFresh(t *testing.T) {
t.Cleanup(func() { t.Cleanup(func() {
require.NoError(t, c()) require.NoError(t, c())
}) })
d, err := sql.Open(dialect, u) d, err := common.SqlOpen(dialect, u)
require.NoError(t, err) require.NoError(t, err)
// Initialize the DB with only a portion of the current sql scripts. // Initialize the DB with only a portion of the current sql scripts.
@@ -146,7 +147,7 @@ func TestRunMigration_canceledContext(t *testing.T) {
t.Cleanup(func() { t.Cleanup(func() {
require.NoError(t, c()) require.NoError(t, c())
}) })
d, err := sql.Open(dialect, u) d, err := common.SqlOpen(dialect, u)
require.NoError(t, err) require.NoError(t, err)
ctx := context.Background() ctx := context.Background()
@@ -174,7 +175,7 @@ func TestRollForward_BadSQL(t *testing.T) {
t.Cleanup(func() { t.Cleanup(func() {
require.NoError(t, c()) require.NoError(t, c())
}) })
d, err := sql.Open(dialect, u) d, err := common.SqlOpen(dialect, u)
require.NoError(t, err) require.NoError(t, err)
// Initialize the DB with only a portion of the current sql scripts. // Initialize the DB with only a portion of the current sql scripts.
@@ -198,12 +199,12 @@ func TestManager_ExclusiveLock(t *testing.T) {
t.Cleanup(func() { t.Cleanup(func() {
require.NoError(t, c()) require.NoError(t, c())
}) })
d1, err := sql.Open(dialect, u) d1, err := common.SqlOpen(dialect, u)
require.NoError(t, err) require.NoError(t, err)
m1, err := NewManager(ctx, dialect, d1) m1, err := NewManager(ctx, dialect, d1)
require.NoError(t, err) require.NoError(t, err)
d2, err := sql.Open(dialect, u) d2, err := common.SqlOpen(dialect, u)
require.NoError(t, err) require.NoError(t, err)
m2, err := NewManager(ctx, dialect, d2) m2, err := NewManager(ctx, dialect, d2)
require.NoError(t, err) require.NoError(t, err)
@@ -223,12 +224,12 @@ func TestManager_SharedLock(t *testing.T) {
t.Cleanup(func() { t.Cleanup(func() {
require.NoError(t, c()) require.NoError(t, c())
}) })
d1, err := sql.Open("postgres", u) d1, err := common.SqlOpen("postgres", u)
require.NoError(t, err) require.NoError(t, err)
m1, err := NewManager(ctx, "postgres", d1) m1, err := NewManager(ctx, "postgres", d1)
require.NoError(t, err) require.NoError(t, err)
d2, err := sql.Open("postgres", u) d2, err := common.SqlOpen("postgres", u)
require.NoError(t, err) require.NoError(t, err)
m2, err := NewManager(ctx, "postgres", d2) m2, err := NewManager(ctx, "postgres", d2)
require.NoError(t, err) require.NoError(t, err)
@@ -252,7 +253,7 @@ func Test_GetMigrationLog(t *testing.T) {
t.Cleanup(func() { t.Cleanup(func() {
require.NoError(t, c()) require.NoError(t, c())
}) })
d, err := sql.Open("postgres", u) d, err := common.SqlOpen("postgres", u)
require.NoError(t, err) require.NoError(t, err)
m, err := NewManager(ctx, "postgres", d) m, err := NewManager(ctx, "postgres", d)
require.NoError(t, err) require.NoError(t, err)
@@ -6,6 +6,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/hashicorp/boundary/internal/db/common"
"github.com/hashicorp/boundary/internal/db/schema" "github.com/hashicorp/boundary/internal/db/schema"
"github.com/hashicorp/boundary/testing/dbtest" "github.com/hashicorp/boundary/testing/dbtest"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@@ -14,8 +15,8 @@ import (
const ( const (
insertServerQuery = "insert into server (private_id, type, address) values ($1, $2, $3)" insertServerQuery = "insert into server (private_id, type, address) values ($1, $2, $3)"
selectServerQuery = "select * from server where private_id = $1" selectServerQuery = "select * from server where private_id = $1"
expectEnumConstraintErr = `pq: new row for relation "server_type_enm" violates check constraint "only_predefined_server_types_allowed"` expectEnumConstraintErr = `ERROR: new row for relation "server_type_enm" violates check constraint "only_predefined_server_types_allowed" (SQLSTATE 23514)`
expectServerConstraintErr = `pq: insert or update on table "server" violates foreign key constraint "server_type_enm_fkey"` expectServerConstraintErr = `ERROR: insert or update on table "server" violates foreign key constraint "server_type_enm_fkey" (SQLSTATE 23503)`
) )
type testServer struct { type testServer struct {
@@ -48,7 +49,7 @@ func Test_ServerEnumChanges(t *testing.T) {
t.Cleanup(func() { t.Cleanup(func() {
require.NoError(c()) require.NoError(c())
}) })
d, err := sql.Open(dialect, u) d, err := common.SqlOpen(dialect, u)
require.NoError(err) require.NoError(err)
// migration to the prior migration (before the one we want to test) // migration to the prior migration (before the one we want to test)
@@ -6,6 +6,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/hashicorp/boundary/internal/db/common"
"github.com/hashicorp/boundary/internal/db/schema" "github.com/hashicorp/boundary/internal/db/schema"
"github.com/hashicorp/boundary/testing/dbtest" "github.com/hashicorp/boundary/testing/dbtest"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@@ -41,7 +42,7 @@ func testSetupDb(ctx context.Context, t *testing.T) *sql.DB {
t.Cleanup(func() { t.Cleanup(func() {
require.NoError(c()) require.NoError(c())
}) })
d, err := sql.Open(dialect, u) d, err := common.SqlOpen(dialect, u)
require.NoError(err) require.NoError(err)
oState := schema.TestCloneMigrationStates(t) oState := schema.TestCloneMigrationStates(t)
@@ -2,12 +2,12 @@ package migration
import ( import (
"context" "context"
"database/sql"
"testing" "testing"
"github.com/hashicorp/boundary/internal/auth/oidc" "github.com/hashicorp/boundary/internal/auth/oidc"
"github.com/hashicorp/boundary/internal/authtoken" "github.com/hashicorp/boundary/internal/authtoken"
"github.com/hashicorp/boundary/internal/db" "github.com/hashicorp/boundary/internal/db"
"github.com/hashicorp/boundary/internal/db/common"
"github.com/hashicorp/boundary/internal/db/schema" "github.com/hashicorp/boundary/internal/db/schema"
"github.com/hashicorp/boundary/internal/host/static" "github.com/hashicorp/boundary/internal/host/static"
"github.com/hashicorp/boundary/internal/iam" "github.com/hashicorp/boundary/internal/iam"
@@ -18,7 +18,6 @@ import (
wrapping "github.com/hashicorp/go-kms-wrapping" wrapping "github.com/hashicorp/go-kms-wrapping"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gorm.io/gorm"
) )
func TestMigrations_UserDimension(t *testing.T) { func TestMigrations_UserDimension(t *testing.T) {
@@ -37,7 +36,7 @@ func TestMigrations_UserDimension(t *testing.T) {
t.Cleanup(func() { t.Cleanup(func() {
require.NoError(c()) require.NoError(c())
}) })
d, err := sql.Open(dialect, u) d, err := common.SqlOpen(dialect, u)
require.NoError(err) require.NoError(err)
// migration to the prior migration (before the one we want to test) // migration to the prior migration (before the one we want to test)
@@ -139,7 +138,7 @@ func TestMigrations_UserDimension(t *testing.T) {
assert.False(state.Dirty) assert.False(state.Dirty)
} }
func testOidcAuthToken(t *testing.T, conn *gorm.DB, kms *kms.Kms, wrapper wrapping.Wrapper, scopeId string) *authtoken.AuthToken { func testOidcAuthToken(t *testing.T, conn *db.DB, kms *kms.Kms, wrapper wrapping.Wrapper, scopeId string) *authtoken.AuthToken {
t.Helper() t.Helper()
authMethod := oidc.TestAuthMethod( authMethod := oidc.TestAuthMethod(
@@ -20,7 +20,6 @@ import (
wrapping "github.com/hashicorp/go-kms-wrapping" wrapping "github.com/hashicorp/go-kms-wrapping"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gorm.io/gorm"
) )
func TestMigrations_CredentialDimension(t *testing.T) { func TestMigrations_CredentialDimension(t *testing.T) {
@@ -144,7 +143,7 @@ func TestMigrations_CredentialDimension(t *testing.T) {
assert.False(state.Dirty) assert.False(state.Dirty)
} }
func testOidcAuthToken(t *testing.T, conn *gorm.DB, kms *kms.Kms, wrapper wrapping.Wrapper, scopeId string) *authtoken.AuthToken { func testOidcAuthToken(t *testing.T, conn *db.DB, kms *kms.Kms, wrapper wrapping.Wrapper, scopeId string) *authtoken.AuthToken {
t.Helper() t.Helper()
authMethod := oidc.TestAuthMethod( authMethod := oidc.TestAuthMethod(
@@ -171,7 +170,7 @@ func testOidcAuthToken(t *testing.T, conn *gorm.DB, kms *kms.Kms, wrapper wrappi
return at return at
} }
func testSessionCredentialParams(t *testing.T, conn *gorm.DB, kms *kms.Kms, wrapper wrapping.Wrapper, tar *target.TcpTarget) []*session.DynamicCredential { func testSessionCredentialParams(t *testing.T, conn *db.DB, kms *kms.Kms, wrapper wrapping.Wrapper, tar *target.TcpTarget) []*session.DynamicCredential {
t.Helper() t.Helper()
rw := db.New(conn) rw := db.New(conn)
@@ -2,11 +2,11 @@ package migration
import ( import (
"context" "context"
"database/sql"
"testing" "testing"
"github.com/hashicorp/boundary/internal/auth/password" "github.com/hashicorp/boundary/internal/auth/password"
"github.com/hashicorp/boundary/internal/db" "github.com/hashicorp/boundary/internal/db"
"github.com/hashicorp/boundary/internal/db/common"
"github.com/hashicorp/boundary/internal/db/schema" "github.com/hashicorp/boundary/internal/db/schema"
"github.com/hashicorp/boundary/internal/iam" "github.com/hashicorp/boundary/internal/iam"
"github.com/hashicorp/boundary/testing/dbtest" "github.com/hashicorp/boundary/testing/dbtest"
@@ -38,7 +38,7 @@ func Test_PrimaryAuthMethodChanges(t *testing.T) {
t.Cleanup(func() { t.Cleanup(func() {
require.NoError(c()) require.NoError(c())
}) })
d, err := sql.Open(dialect, u) d, err := common.SqlOpen(dialect, u)
require.NoError(err) require.NoError(err)
// migration to the prior migration (before the one we want to test) // migration to the prior migration (before the one we want to test)
@@ -1,6 +1,7 @@
package migration package migration
import ( import (
"context"
"database/sql" "database/sql"
"testing" "testing"
@@ -37,9 +38,9 @@ func TestMigration(t *testing.T) {
` `
selectQuery = `select session_id, server_id from session_connection_testing order by session_id` selectQuery = `select session_id, server_id from session_connection_testing order by session_id`
) )
ctx := context.Background()
conn, _ := db.TestSetup(t, "postgres", db.WithTemplate("template1")) conn, _ := db.TestSetup(t, "postgres", db.WithTemplate("template1"))
db, err := conn.DB() db, err := conn.SqlDB(ctx)
require.NoError(err) require.NoError(err)
_, err = db.Exec(createTables) _, err = db.Exec(createTables)
require.NoError(err) require.NoError(err)
+14 -13
View File
@@ -34,12 +34,11 @@ import (
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"strconv"
"strings" "strings"
"github.com/hashicorp/boundary/internal/errors" "github.com/hashicorp/boundary/internal/errors"
"github.com/hashicorp/go-multierror" "github.com/hashicorp/go-multierror"
"github.com/lib/pq" "github.com/jackc/pgconn"
) )
// schemaAccessLockId is a Lock key used to ensure a single boundary binary is operating // schemaAccessLockId is a Lock key used to ensure a single boundary binary is operating
@@ -232,14 +231,12 @@ func (p *Postgres) Run(ctx context.Context, migration io.Reader, version int) er
if rollbackErr := rollback(); rollbackErr != nil { if rollbackErr := rollback(); rollbackErr != nil {
err = multierror.Append(err, rollbackErr) err = multierror.Append(err, rollbackErr)
} }
if pgErr, ok := err.(*pq.Error); ok { if pgErr, ok := err.(*pgconn.PgError); ok {
var line uint var line uint
var col uint var col uint
var lineColOK bool var lineColOK bool
if pgErr.Position != "" { if pgErr.Position != 0 {
if pos, err := strconv.ParseUint(pgErr.Position, 10, 64); err == nil { line, col, lineColOK = computeLineFromPos(query, int(pgErr.Position))
line, col, lineColOK = computeLineFromPos(query, int(pos))
}
} }
message := "migration failed" message := "migration failed"
if lineColOK { if lineColOK {
@@ -308,8 +305,7 @@ func (p *Postgres) setVersion(ctx context.Context, version int, dirty bool) erro
defer func() { p.tx = nil }() defer func() { p.tx = nil }()
return tx.Rollback() return tx.Rollback()
} }
query := `truncate ` + quoteIdentifier(defaultMigrationsTable)
query := `truncate ` + pq.QuoteIdentifier(defaultMigrationsTable)
if _, err := tx.ExecContext(ctx, query); err != nil { if _, err := tx.ExecContext(ctx, query); err != nil {
if errRollback := rollback(); errRollback != nil { if errRollback := rollback(); errRollback != nil {
err = multierror.Append(err, errRollback) err = multierror.Append(err, errRollback)
@@ -321,7 +317,7 @@ func (p *Postgres) setVersion(ctx context.Context, version int, dirty bool) erro
// empty schema Version for failed down migration on the first migration // empty schema Version for failed down migration on the first migration
// See: https://github.com/golang-migrate/migrate/issues/330 // See: https://github.com/golang-migrate/migrate/issues/330
if version >= 0 || (version == nilVersion && dirty) { if version >= 0 || (version == nilVersion && dirty) {
query = `insert into ` + pq.QuoteIdentifier(defaultMigrationsTable) + query = `insert into ` + quoteIdentifier(defaultMigrationsTable) +
` (version, dirty) values ($1, $2)` ` (version, dirty) values ($1, $2)`
if _, err := tx.ExecContext(ctx, query, version, dirty); err != nil { if _, err := tx.ExecContext(ctx, query, version, dirty); err != nil {
if errRollback := rollback(); errRollback != nil { if errRollback := rollback(); errRollback != nil {
@@ -368,7 +364,7 @@ func (p *Postgres) CurrentState(ctx context.Context) (version int, previouslyRan
return nilVersion, previouslyRan, dirty, errors.New(ctx, errors.MigrationIntegrity, op, "both old and new migration tables exist") return nilVersion, previouslyRan, dirty, errors.New(ctx, errors.MigrationIntegrity, op, "both old and new migration tables exist")
} }
query := `select version, dirty from ` + pq.QuoteIdentifier(tableName) query := `select version, dirty from ` + quoteIdentifier(tableName)
results, err := p.conn.QueryContext(ctx, query) results, err := p.conn.QueryContext(ctx, query)
if err != nil { if err != nil {
return nilVersion, previouslyRan, dirty, errors.Wrap(ctx, err, op) return nilVersion, previouslyRan, dirty, errors.Wrap(ctx, err, op)
@@ -420,7 +416,7 @@ func (p *Postgres) drop(ctx context.Context) (err error) {
if len(tableNames) > 0 { if len(tableNames) > 0 {
// delete one by one ... // delete one by one ...
for _, t := range tableNames { for _, t := range tableNames {
query = `drop table if exists ` + pq.QuoteIdentifier(t) + ` cascade` query = `drop table if exists ` + quoteIdentifier(t) + ` cascade`
if _, err := p.conn.ExecContext(ctx, query); err != nil { if _, err := p.conn.ExecContext(ctx, query); err != nil {
return errors.Wrap(ctx, err, op) return errors.Wrap(ctx, err, op)
} }
@@ -464,7 +460,7 @@ func (p *Postgres) EnsureVersionTable(ctx context.Context) (err error) {
return errors.Wrap(ctx, err, op) return errors.Wrap(ctx, err, op)
} }
createStmt := `create table if not exists ` + pq.QuoteIdentifier(defaultMigrationsTable) + ` (version bigint primary key, dirty boolean not null)` createStmt := `create table if not exists ` + quoteIdentifier(defaultMigrationsTable) + ` (version bigint primary key, dirty boolean not null)`
if _, err = extr.ExecContext(ctx, createStmt); err != nil { if _, err = extr.ExecContext(ctx, createStmt); err != nil {
if wpErr := rollback(); wpErr != nil { if wpErr := rollback(); wpErr != nil {
err = multierror.Append(err, wpErr) err = multierror.Append(err, wpErr)
@@ -474,3 +470,8 @@ func (p *Postgres) EnsureVersionTable(ctx context.Context) (err error) {
return nil return nil
} }
func quoteIdentifier(input string) (output string) {
output = `"` + strings.Replace(input, `"`, `""`, -1) + `"`
return
}
+1 -1
View File
@@ -28,7 +28,7 @@
package postgres package postgres
// error codes https://github.com/lib/pq/blob/master/error.go // errors: https://pkg.go.dev/github.com/jackc/pgconn#PgError
import ( import (
"bytes" "bytes"
+2 -2
View File
@@ -31,11 +31,11 @@ package postgres
import ( import (
"bytes" "bytes"
"context" "context"
"database/sql"
"testing" "testing"
"time" "time"
"github.com/golang-migrate/migrate/v4/database" "github.com/golang-migrate/migrate/v4/database"
"github.com/hashicorp/boundary/internal/db/common"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@@ -123,7 +123,7 @@ func testSetVersion(t *testing.T, d *Postgres) {
func open(t *testing.T, ctx context.Context, u string) (*Postgres, error) { func open(t *testing.T, ctx context.Context, u string) (*Postgres, error) {
t.Helper() t.Helper()
db, err := sql.Open("postgres", u) db, err := common.SqlOpen("postgres", u)
require.NoError(t, err) require.NoError(t, err)
px, err := New(ctx, db) px, err := New(ctx, db)
+2 -2
View File
@@ -2,8 +2,8 @@ package schema
import ( import (
"context" "context"
"database/sql"
"github.com/hashicorp/boundary/internal/db/common"
"github.com/hashicorp/boundary/internal/errors" "github.com/hashicorp/boundary/internal/errors"
) )
@@ -13,7 +13,7 @@ import (
func MigrateStore(ctx context.Context, dialect string, url string, opt ...Option) (bool, error) { func MigrateStore(ctx context.Context, dialect string, url string, opt ...Option) (bool, error) {
const op = "schema.MigrateStore" const op = "schema.MigrateStore"
d, err := sql.Open(dialect, url) d, err := common.SqlOpen(dialect, url)
if err != nil { if err != nil {
return false, errors.Wrap(ctx, err, op) return false, errors.Wrap(ctx, err, op)
} }
+2 -2
View File
@@ -2,9 +2,9 @@ package schema
import ( import (
"context" "context"
"database/sql"
"testing" "testing"
"github.com/hashicorp/boundary/internal/db/common"
"github.com/hashicorp/boundary/testing/dbtest" "github.com/hashicorp/boundary/testing/dbtest"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@@ -53,7 +53,7 @@ func Test_MigrateStore_WithMigrationStates(t *testing.T) {
t.Cleanup(func() { t.Cleanup(func() {
require.NoError(c()) require.NoError(c())
}) })
d, err := sql.Open(dialect, u) d, err := common.SqlOpen(dialect, u)
require.NoError(err) require.NoError(err)
// migration to the prior migration (before the one we want to test) // migration to the prior migration (before the one we want to test)
+2 -3
View File
@@ -17,12 +17,11 @@ import (
wrapping "github.com/hashicorp/go-kms-wrapping" wrapping "github.com/hashicorp/go-kms-wrapping"
"github.com/hashicorp/go-kms-wrapping/wrappers/aead" "github.com/hashicorp/go-kms-wrapping/wrappers/aead"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"gorm.io/gorm"
"gorm.io/gorm/logger" "gorm.io/gorm/logger"
) )
// setup the tests (initialize the database one-time and intialized testDatabaseURL). Do not close the returned db. // setup the tests (initialize the database one-time and intialized testDatabaseURL). Do not close the returned db.
func TestSetup(t *testing.T, dialect string, opt ...TestOption) (*gorm.DB, string) { func TestSetup(t *testing.T, dialect string, opt ...TestOption) (*DB, string) {
var cleanup func() error var cleanup func() error
var url string var url string
var err error var err error
@@ -57,7 +56,7 @@ func TestSetup(t *testing.T, dialect string, opt ...TestOption) (*gorm.DB, strin
} }
db.Logger.LogMode(logger.Error) db.Logger.LogMode(logger.Error)
t.Cleanup(func() { t.Cleanup(func() {
sqlDB, err := db.DB() sqlDB, err := db.SqlDB(ctx)
assert.NoError(t, err) assert.NoError(t, err)
assert.NoError(t, sqlDB.Close(), "Got error closing gorm db.") assert.NoError(t, sqlDB.Close(), "Got error closing gorm db.")
}) })
+3 -3
View File
@@ -44,7 +44,7 @@ func TestError_IsUnique(t *testing.T) {
want: true, want: true,
}, },
{ {
name: "wrapped-pq-is-unique", name: "wrapped-pg-is-unique",
in: errors.E( in: errors.E(
context.TODO(), context.TODO(),
errors.WithWrap(&pgconn.PgError{ errors.WithWrap(&pgconn.PgError{
@@ -107,7 +107,7 @@ func TestError_IsCheckConstraint(t *testing.T) {
want: true, want: true,
}, },
{ {
name: "wrapped-pq-is-check-constraint", name: "wrapped-pg-is-check-constraint",
in: errors.E(context.TODO(), errors.WithCode(errors.CheckConstraint), in: errors.E(context.TODO(), errors.WithCode(errors.CheckConstraint),
errors.WithWrap(&pgconn.PgError{ errors.WithWrap(&pgconn.PgError{
Code: "23514", Code: "23514",
@@ -176,7 +176,7 @@ func TestError_IsNotNullError(t *testing.T) {
want: true, want: true,
}, },
{ {
name: "wrapped-pq-is-not-null", name: "wrapped-pg-is-not-null",
in: errors.E(context.TODO(), errors.WithCode(errors.NotNull), in: errors.E(context.TODO(), errors.WithCode(errors.NotNull),
errors.WithWrap(&pgconn.PgError{ errors.WithWrap(&pgconn.PgError{
Code: "23502", Code: "23502",
+1 -2
View File
@@ -6,7 +6,6 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gorm.io/gorm"
"github.com/hashicorp/boundary/internal/db" "github.com/hashicorp/boundary/internal/db"
"github.com/hashicorp/boundary/internal/host/static/store" "github.com/hashicorp/boundary/internal/host/static/store"
@@ -109,7 +108,7 @@ func TestHostCatalog_New(t *testing.T) {
} }
} }
func testCatalog(t *testing.T, conn *gorm.DB, scopeId string) *HostCatalog { func testCatalog(t *testing.T, conn *db.DB, scopeId string) *HostCatalog {
t.Helper() t.Helper()
cats := TestCatalogs(t, conn, scopeId, 1) cats := TestCatalogs(t, conn, scopeId, 1)
return cats[0] return cats[0]
@@ -179,6 +179,7 @@ func TestRepository_UpdateCatalog(t *testing.T) {
conn, _ := db.TestSetup(t, "postgres") conn, _ := db.TestSetup(t, "postgres")
rw := db.New(conn) rw := db.New(conn)
wrapper := db.TestWrapper(t) wrapper := db.TestWrapper(t)
ctx := context.Background()
changeName := func(s string) func(*HostCatalog) *HostCatalog { changeName := func(s string) func(*HostCatalog) *HostCatalog {
return func(c *HostCatalog) *HostCatalog { return func(c *HostCatalog) *HostCatalog {
@@ -461,7 +462,7 @@ func TestRepository_UpdateCatalog(t *testing.T) {
assert.Equal(tt.wantCount, gotCount, "row count") assert.Equal(tt.wantCount, gotCount, "row count")
assert.NotSame(tt.orig, got) assert.NotSame(tt.orig, got)
assert.Equal(tt.orig.ScopeId, got.ScopeId) assert.Equal(tt.orig.ScopeId, got.ScopeId)
underlyingDB, err := conn.DB() underlyingDB, err := conn.SqlDB(ctx)
require.NoError(t, err) require.NoError(t, err)
dbassert := dbassert.New(t, underlyingDB) dbassert := dbassert.New(t, underlyingDB)
if tt.want.Name == "" { if tt.want.Name == "" {
@@ -202,6 +202,7 @@ func TestRepository_CreateSet(t *testing.T) {
} }
func TestRepository_UpdateSet(t *testing.T) { func TestRepository_UpdateSet(t *testing.T) {
ctx := context.Background()
conn, _ := db.TestSetup(t, "postgres") conn, _ := db.TestSetup(t, "postgres")
rw := db.New(conn) rw := db.New(conn)
wrapper := db.TestWrapper(t) wrapper := db.TestWrapper(t)
@@ -493,7 +494,7 @@ func TestRepository_UpdateSet(t *testing.T) {
assert.Equal(tt.wantCount, gotCount, "row count") assert.Equal(tt.wantCount, gotCount, "row count")
assert.NotSame(tt.orig, got) assert.NotSame(tt.orig, got)
assert.Equal(tt.orig.CatalogId, got.CatalogId) assert.Equal(tt.orig.CatalogId, got.CatalogId)
underlyingDB, err := conn.DB() underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err) require.NoError(err)
dbassert := dbassert.New(t, underlyingDB) dbassert := dbassert.New(t, underlyingDB)
if tt.want.Name == "" { if tt.want.Name == "" {
+2 -1
View File
@@ -251,6 +251,7 @@ func TestRepository_CreateHost(t *testing.T) {
} }
func TestRepository_UpdateHost(t *testing.T) { func TestRepository_UpdateHost(t *testing.T) {
ctx := context.Background()
conn, _ := db.TestSetup(t, "postgres") conn, _ := db.TestSetup(t, "postgres")
rw := db.New(conn) rw := db.New(conn)
wrapper := db.TestWrapper(t) wrapper := db.TestWrapper(t)
@@ -620,7 +621,7 @@ func TestRepository_UpdateHost(t *testing.T) {
assert.Equal(tt.wantCount, gotCount, "row count") assert.Equal(tt.wantCount, gotCount, "row count")
assert.NotSame(tt.orig, got) assert.NotSame(tt.orig, got)
assert.Equal(tt.orig.CatalogId, got.CatalogId) assert.Equal(tt.orig.CatalogId, got.CatalogId)
underlyingDB, err := conn.DB() underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err) require.NoError(err)
dbassert := dbassert.New(t, underlyingDB) dbassert := dbassert.New(t, underlyingDB)
if tt.want.Name == "" { if tt.want.Name == "" {
+4 -5
View File
@@ -7,13 +7,12 @@ import (
"github.com/hashicorp/boundary/internal/db" "github.com/hashicorp/boundary/internal/db"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"gorm.io/gorm"
) )
// TestCatalogs creates count number of static host catalogs to the provided DB // TestCatalogs creates count number of static host catalogs to the provided DB
// with the provided scope id. If any errors are encountered during the creation of // with the provided scope id. If any errors are encountered during the creation of
// the host catalog, the test will fail. // the host catalog, the test will fail.
func TestCatalogs(t *testing.T, conn *gorm.DB, scopeId string, count int) []*HostCatalog { func TestCatalogs(t *testing.T, conn *db.DB, scopeId string, count int) []*HostCatalog {
t.Helper() t.Helper()
assert := assert.New(t) assert := assert.New(t)
var cats []*HostCatalog var cats []*HostCatalog
@@ -37,7 +36,7 @@ func TestCatalogs(t *testing.T, conn *gorm.DB, scopeId string, count int) []*Hos
// TestHosts creates count number of static hosts to the provided DB // TestHosts creates count number of static hosts to the provided DB
// with the provided catalog id. The catalog must have been created previously. // with the provided catalog id. The catalog must have been created previously.
// If any errors are encountered during the creation of the host, the test will fail. // If any errors are encountered during the creation of the host, the test will fail.
func TestHosts(t *testing.T, conn *gorm.DB, catalogId string, count int) []*Host { func TestHosts(t *testing.T, conn *db.DB, catalogId string, count int) []*Host {
t.Helper() t.Helper()
assert := assert.New(t) assert := assert.New(t)
var hosts []*Host var hosts []*Host
@@ -63,7 +62,7 @@ func TestHosts(t *testing.T, conn *gorm.DB, catalogId string, count int) []*Host
// TestSets creates count number of static host sets in the provided DB // TestSets creates count number of static host sets in the provided DB
// with the provided catalog id. The catalog must have been created // with the provided catalog id. The catalog must have been created
// previously. The test will fail if any errors are encountered. // previously. The test will fail if any errors are encountered.
func TestSets(t *testing.T, conn *gorm.DB, catalogId string, count int) []*HostSet { func TestSets(t *testing.T, conn *db.DB, catalogId string, count int) []*HostSet {
t.Helper() t.Helper()
assert := assert.New(t) assert := assert.New(t)
var sets []*HostSet var sets []*HostSet
@@ -88,7 +87,7 @@ func TestSets(t *testing.T, conn *gorm.DB, catalogId string, count int) []*HostS
// TestSetMembers adds hosts to the specified setId in the provided DB. // TestSetMembers adds hosts to the specified setId in the provided DB.
// The set and hosts must have been created previously and belong to the // The set and hosts must have been created previously and belong to the
// same catalog. The test will fail if any errors are encountered. // same catalog. The test will fail if any errors are encountered.
func TestSetMembers(t *testing.T, conn *gorm.DB, setId string, hosts []*Host) []*HostSetMember { func TestSetMembers(t *testing.T, conn *db.DB, setId string, hosts []*Host) []*HostSetMember {
t.Helper() t.Helper()
assert := assert.New(t) assert := assert.New(t)
+2 -1
View File
@@ -65,6 +65,7 @@ func TestAccount_GetScope(t *testing.T) {
func TestAccount_Clone(t *testing.T) { func TestAccount_Clone(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
conn, _ := db.TestSetup(t, "postgres") conn, _ := db.TestSetup(t, "postgres")
wrapper := db.TestWrapper(t) wrapper := db.TestWrapper(t)
repo := TestRepo(t, conn, wrapper) repo := TestRepo(t, conn, wrapper)
@@ -83,7 +84,7 @@ func TestAccount_Clone(t *testing.T) {
authMethodPublicId := testAuthMethod(t, conn, org.PublicId) authMethodPublicId := testAuthMethod(t, conn, org.PublicId)
acct := testAccount(t, conn, org.PublicId, authMethodPublicId, u.PublicId) acct := testAccount(t, conn, org.PublicId, authMethodPublicId, u.PublicId)
acct2 := testAccount(t, conn, org.PublicId, authMethodPublicId, "") acct2 := testAccount(t, conn, org.PublicId, authMethodPublicId, "")
underlyingDB, err := conn.DB() underlyingDB, err := conn.SqlDB(ctx)
require.NoError(t, err) require.NoError(t, err)
dbassert := dbassert.New(t, underlyingDB) dbassert := dbassert.New(t, underlyingDB)
dbassert.IsNull(acct2, "IamUserId") dbassert.IsNull(acct2, "IamUserId")
+2 -1
View File
@@ -206,6 +206,7 @@ func Test_GroupCreate(t *testing.T) {
func Test_GroupUpdate(t *testing.T) { func Test_GroupUpdate(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
conn, _ := db.TestSetup(t, "postgres") conn, _ := db.TestSetup(t, "postgres")
wrapper := db.TestWrapper(t) wrapper := db.TestWrapper(t)
repo := TestRepo(t, conn, wrapper) repo := TestRepo(t, conn, wrapper)
@@ -351,7 +352,7 @@ func Test_GroupUpdate(t *testing.T) {
require.NoError(err) require.NoError(err)
assert.True(proto.Equal(updateGrp, foundGrp)) assert.True(proto.Equal(updateGrp, foundGrp))
if len(tt.args.nullPaths) != 0 { if len(tt.args.nullPaths) != 0 {
underlyingDB, err := conn.DB() underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err) require.NoError(err)
dbassert := dbassert.New(t, underlyingDB) dbassert := dbassert.New(t, underlyingDB)
for _, f := range tt.args.nullPaths { for _, f := range tt.args.nullPaths {
+2 -1
View File
@@ -92,10 +92,11 @@ func TestConcreteScope_ImmutableFields(t *testing.T) {
update = `update {{rep}} set scope_id = $1 where scope_id = $2;` update = `update {{rep}} set scope_id = $1 where scope_id = $2;`
) )
t.Parallel() t.Parallel()
ctx := context.Background()
conn, _ := db.TestSetup(t, "postgres") conn, _ := db.TestSetup(t, "postgres")
wrapper := db.TestWrapper(t) wrapper := db.TestWrapper(t)
repo := TestRepo(t, conn, wrapper) repo := TestRepo(t, conn, wrapper)
db, err := conn.DB() db, err := conn.SqlDB(ctx)
require.NoError(t, err) require.NoError(t, err)
org, proj := TestScopes(t, repo) org, proj := TestScopes(t, repo)
+2 -1
View File
@@ -173,6 +173,7 @@ func TestRepository_CreateGroup(t *testing.T) {
func TestRepository_UpdateGroup(t *testing.T) { func TestRepository_UpdateGroup(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
conn, _ := db.TestSetup(t, "postgres") conn, _ := db.TestSetup(t, "postgres")
a := assert.New(t) a := assert.New(t)
rw := db.New(conn) rw := db.New(conn)
@@ -450,7 +451,7 @@ func TestRepository_UpdateGroup(t *testing.T) {
foundGrp, _, err := repo.LookupGroup(context.Background(), u.PublicId) foundGrp, _, err := repo.LookupGroup(context.Background(), u.PublicId)
require.NoError(err) require.NoError(err)
assert.True(proto.Equal(groupAfterUpdate, foundGrp)) assert.True(proto.Equal(groupAfterUpdate, foundGrp))
underlyingDB, err := conn.DB() underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err) require.NoError(err)
dbassert := dbassert.New(t, underlyingDB) dbassert := dbassert.New(t, underlyingDB)
if tt.args.name == "" { if tt.args.name == "" {
+2 -1
View File
@@ -174,6 +174,7 @@ func TestRepository_CreateRole(t *testing.T) {
func TestRepository_UpdateRole(t *testing.T) { func TestRepository_UpdateRole(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
conn, _ := db.TestSetup(t, "postgres") conn, _ := db.TestSetup(t, "postgres")
rw := db.New(conn) rw := db.New(conn)
wrapper := db.TestWrapper(t) wrapper := db.TestWrapper(t)
@@ -447,7 +448,7 @@ func TestRepository_UpdateRole(t *testing.T) {
foundRole, _, _, err := repo.LookupRole(context.Background(), r.PublicId) foundRole, _, _, err := repo.LookupRole(context.Background(), r.PublicId)
assert.NoError(err) assert.NoError(err)
assert.True(proto.Equal(roleAfterUpdate, foundRole)) assert.True(proto.Equal(roleAfterUpdate, foundRole))
underlyingDB, err := conn.DB() underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err) require.NoError(err)
dbassert := dbassert.New(t, underlyingDB) dbassert := dbassert.New(t, underlyingDB)
if tt.args.name == "" { if tt.args.name == "" {
+2 -1
View File
@@ -184,6 +184,7 @@ func TestRepository_associateUserWithAccounts(t *testing.T) {
func TestRepository_dissociateUserWithAccount(t *testing.T) { func TestRepository_dissociateUserWithAccount(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
conn, _ := db.TestSetup(t, "postgres") conn, _ := db.TestSetup(t, "postgres")
rw := db.New(conn) rw := db.New(conn)
wrapper := db.TestWrapper(t) wrapper := db.TestWrapper(t)
@@ -309,7 +310,7 @@ func TestRepository_dissociateUserWithAccount(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t) assert, require := assert.New(t), require.New(t)
underlyingDB, err := conn.DB() underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err) require.NoError(err)
dbassert := dbassert.New(t, underlyingDB) dbassert := dbassert.New(t, underlyingDB)
err = dissociateUserFromAccounts(context.Background(), kms, rw, rw, tt.args.Ids.user, tt.args.Ids.accts, tt.args.opt...) err = dissociateUserFromAccounts(context.Background(), kms, rw, rw, tt.args.Ids.user, tt.args.Ids.accts, tt.args.opt...)
+4 -2
View File
@@ -198,6 +198,7 @@ func TestRepository_LookupUser_WithDifferentPrimaryAuthMethods(t *testing.T) {
func TestRepository_UpdateUser(t *testing.T) { func TestRepository_UpdateUser(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
conn, _ := db.TestSetup(t, "postgres") conn, _ := db.TestSetup(t, "postgres")
rw := db.New(conn) rw := db.New(conn)
wrapper := db.TestWrapper(t) wrapper := db.TestWrapper(t)
@@ -475,7 +476,7 @@ func TestRepository_UpdateUser(t *testing.T) {
assert.True(proto.Equal(userAfterUpdate, foundUser)) assert.True(proto.Equal(userAfterUpdate, foundUser))
sort.Strings(foundAccountIds) sort.Strings(foundAccountIds)
assert.Equal(accountIds, foundAccountIds) assert.Equal(accountIds, foundAccountIds)
underlyingDB, err := conn.DB() underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err) require.NoError(err)
dbassert := dbassert.New(t, underlyingDB) dbassert := dbassert.New(t, underlyingDB)
if tt.args.name == "" { if tt.args.name == "" {
@@ -710,6 +711,7 @@ func TestRepository_ListUsers_Multiple_Scopes(t *testing.T) {
func TestRepository_LookupUserWithLogin(t *testing.T) { func TestRepository_LookupUserWithLogin(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
conn, _ := db.TestSetup(t, "postgres") conn, _ := db.TestSetup(t, "postgres")
rw := db.New(conn) rw := db.New(conn)
wrapper := db.TestWrapper(t) wrapper := db.TestWrapper(t)
@@ -847,7 +849,7 @@ func TestRepository_LookupUserWithLogin(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t) assert, require := assert.New(t), require.New(t)
underlyingDB, err := conn.DB() underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err) require.NoError(err)
dbassert := dbassert.New(t, underlyingDB) dbassert := dbassert.New(t, underlyingDB)
got, err := repo.LookupUserWithLogin(context.Background(), tt.args.withAccountId, tt.args.opt...) got, err := repo.LookupUserWithLogin(context.Background(), tt.args.withAccountId, tt.args.opt...)
+2 -1
View File
@@ -206,6 +206,7 @@ func Test_RoleCreate(t *testing.T) {
func Test_RoleUpdate(t *testing.T) { func Test_RoleUpdate(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
conn, _ := db.TestSetup(t, "postgres") conn, _ := db.TestSetup(t, "postgres")
wrapper := db.TestWrapper(t) wrapper := db.TestWrapper(t)
repo := TestRepo(t, conn, wrapper) repo := TestRepo(t, conn, wrapper)
@@ -440,7 +441,7 @@ func Test_RoleUpdate(t *testing.T) {
} }
assert.True(proto.Equal(updateRole, foundRole)) assert.True(proto.Equal(updateRole, foundRole))
if len(tt.args.nullPaths) != 0 { if len(tt.args.nullPaths) != 0 {
underlyingDB, err := conn.DB() underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err) require.NoError(err)
dbassert := dbassert.New(t, underlyingDB) dbassert := dbassert.New(t, underlyingDB)
for _, f := range tt.args.nullPaths { for _, f := range tt.args.nullPaths {
+14 -13
View File
@@ -13,12 +13,11 @@ import (
wrapping "github.com/hashicorp/go-kms-wrapping" wrapping "github.com/hashicorp/go-kms-wrapping"
"github.com/hashicorp/go-uuid" "github.com/hashicorp/go-uuid"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gorm.io/gorm"
) )
// TestRepo creates a repo that can be used for various purposes. Crucially, it // TestRepo creates a repo that can be used for various purposes. Crucially, it
// ensures that the global scope contains a valid root key. // ensures that the global scope contains a valid root key.
func TestRepo(t *testing.T, conn *gorm.DB, rootWrapper wrapping.Wrapper, opt ...Option) *Repository { func TestRepo(t *testing.T, conn *db.DB, rootWrapper wrapping.Wrapper, opt ...Option) *Repository {
require := require.New(t) require := require.New(t)
rw := db.New(conn) rw := db.New(conn)
kmsCache := kms.TestKms(t, conn, rootWrapper) kmsCache := kms.TestKms(t, conn, rootWrapper)
@@ -156,7 +155,7 @@ func TestUser(t *testing.T, repo *Repository, scopeId string, opt ...Option) *Us
} }
// TestRole creates a role suitable for testing. // TestRole creates a role suitable for testing.
func TestRole(t *testing.T, conn *gorm.DB, scopeId string, opt ...Option) *Role { func TestRole(t *testing.T, conn *db.DB, scopeId string, opt ...Option) *Role {
t.Helper() t.Helper()
require := require.New(t) require := require.New(t)
rw := db.New(conn) rw := db.New(conn)
@@ -176,7 +175,7 @@ func TestRole(t *testing.T, conn *gorm.DB, scopeId string, opt ...Option) *Role
return role return role
} }
func TestRoleGrant(t *testing.T, conn *gorm.DB, roleId, grant string, opt ...Option) *RoleGrant { func TestRoleGrant(t *testing.T, conn *db.DB, roleId, grant string, opt ...Option) *RoleGrant {
t.Helper() t.Helper()
require := require.New(t) require := require.New(t)
rw := db.New(conn) rw := db.New(conn)
@@ -189,7 +188,7 @@ func TestRoleGrant(t *testing.T, conn *gorm.DB, roleId, grant string, opt ...Opt
} }
// TestGroup creates a group suitable for testing. // TestGroup creates a group suitable for testing.
func TestGroup(t *testing.T, conn *gorm.DB, scopeId string, opt ...Option) *Group { func TestGroup(t *testing.T, conn *db.DB, scopeId string, opt ...Option) *Group {
t.Helper() t.Helper()
require := require.New(t) require := require.New(t)
rw := db.New(conn) rw := db.New(conn)
@@ -205,7 +204,7 @@ func TestGroup(t *testing.T, conn *gorm.DB, scopeId string, opt ...Option) *Grou
return grp return grp
} }
func TestGroupMember(t *testing.T, conn *gorm.DB, groupId, userId string, opt ...Option) *GroupMemberUser { func TestGroupMember(t *testing.T, conn *db.DB, groupId, userId string, opt ...Option) *GroupMemberUser {
t.Helper() t.Helper()
require := require.New(t) require := require.New(t)
rw := db.New(conn) rw := db.New(conn)
@@ -218,7 +217,7 @@ func TestGroupMember(t *testing.T, conn *gorm.DB, groupId, userId string, opt ..
return gm return gm
} }
func TestUserRole(t *testing.T, conn *gorm.DB, roleId, userId string, opt ...Option) *UserRole { func TestUserRole(t *testing.T, conn *db.DB, roleId, userId string, opt ...Option) *UserRole {
t.Helper() t.Helper()
require := require.New(t) require := require.New(t)
rw := db.New(conn) rw := db.New(conn)
@@ -230,7 +229,7 @@ func TestUserRole(t *testing.T, conn *gorm.DB, roleId, userId string, opt ...Opt
return r return r
} }
func TestGroupRole(t *testing.T, conn *gorm.DB, roleId, grpId string, opt ...Option) *GroupRole { func TestGroupRole(t *testing.T, conn *db.DB, roleId, grpId string, opt ...Option) *GroupRole {
t.Helper() t.Helper()
require := require.New(t) require := require.New(t)
rw := db.New(conn) rw := db.New(conn)
@@ -242,7 +241,7 @@ func TestGroupRole(t *testing.T, conn *gorm.DB, roleId, grpId string, opt ...Opt
return r return r
} }
func TestManagedGroupRole(t *testing.T, conn *gorm.DB, roleId, managedGrpId string, opt ...Option) *ManagedGroupRole { func TestManagedGroupRole(t *testing.T, conn *db.DB, roleId, managedGrpId string, opt ...Option) *ManagedGroupRole {
t.Helper() t.Helper()
require := require.New(t) require := require.New(t)
rw := db.New(conn) rw := db.New(conn)
@@ -257,11 +256,13 @@ func TestManagedGroupRole(t *testing.T, conn *gorm.DB, roleId, managedGrpId stri
// testAccount is a temporary test function. TODO - replace with an auth // testAccount is a temporary test function. TODO - replace with an auth
// subsystem testAccount function. If userId is zero value, then an auth // subsystem testAccount function. If userId is zero value, then an auth
// account will be created with a null IamUserId // account will be created with a null IamUserId
func testAccount(t *testing.T, conn *gorm.DB, scopeId, authMethodId, userId string) *authAccount { func testAccount(t *testing.T, conn *db.DB, scopeId, authMethodId, userId string) *authAccount {
const ( const (
accountPrefix = "aa_" accountPrefix = "aa_"
) )
t.Helper() t.Helper()
ctx := context.Background()
rw := db.New(conn) rw := db.New(conn)
require := require.New(t) require := require.New(t)
require.NotNil(conn) require.NotNil(conn)
@@ -277,7 +278,7 @@ func testAccount(t *testing.T, conn *gorm.DB, scopeId, authMethodId, userId stri
} }
var count int var count int
underlyingDB, err := conn.DB() underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err) require.NoError(err)
err = underlyingDB.QueryRow(whereValidAuthMethod, authMethodId, scopeId).Scan(&count) err = underlyingDB.QueryRow(whereValidAuthMethod, authMethodId, scopeId).Scan(&count)
require.NoError(err) require.NoError(err)
@@ -299,7 +300,7 @@ func testAccount(t *testing.T, conn *gorm.DB, scopeId, authMethodId, userId stri
require.NotEmpty(acct.PublicId) require.NotEmpty(acct.PublicId)
if userId == "" { if userId == "" {
underlyingDB, err := conn.DB() underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err) require.NoError(err)
dbassert := dbassert.New(t, underlyingDB) dbassert := dbassert.New(t, underlyingDB)
dbassert.IsNull(acct, "IamUserId") dbassert.IsNull(acct, "IamUserId")
@@ -309,7 +310,7 @@ func testAccount(t *testing.T, conn *gorm.DB, scopeId, authMethodId, userId stri
// testAuthMethod is a temporary test function. TODO - replace with an auth // testAuthMethod is a temporary test function. TODO - replace with an auth
// subsystem testAuthMethod function. // subsystem testAuthMethod function.
func testAuthMethod(t *testing.T, conn *gorm.DB, scopeId string) string { func testAuthMethod(t *testing.T, conn *db.DB, scopeId string) string {
const ( const (
authMethodPrefix = "am_" authMethodPrefix = "am_"
) )
+13 -14
View File
@@ -8,10 +8,9 @@ import (
wrapping "github.com/hashicorp/go-kms-wrapping" wrapping "github.com/hashicorp/go-kms-wrapping"
"github.com/hashicorp/go-kms-wrapping/wrappers/aead" "github.com/hashicorp/go-kms-wrapping/wrappers/aead"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gorm.io/gorm"
) )
func TestRootKey(t *testing.T, conn *gorm.DB, scopeId string) *RootKey { func TestRootKey(t *testing.T, conn *db.DB, scopeId string) *RootKey {
t.Helper() t.Helper()
require := require.New(t) require := require.New(t)
rw := db.New(conn) rw := db.New(conn)
@@ -26,7 +25,7 @@ func TestRootKey(t *testing.T, conn *gorm.DB, scopeId string) *RootKey {
return k return k
} }
func TestRootKeyVersion(t *testing.T, conn *gorm.DB, wrapper wrapping.Wrapper, rootId string) (kv *RootKeyVersion, kvWrapper wrapping.Wrapper) { func TestRootKeyVersion(t *testing.T, conn *db.DB, wrapper wrapping.Wrapper, rootId string) (kv *RootKeyVersion, kvWrapper wrapping.Wrapper) {
t.Helper() t.Helper()
require := require.New(t) require := require.New(t)
rw := db.New(conn) rw := db.New(conn)
@@ -48,7 +47,7 @@ func TestRootKeyVersion(t *testing.T, conn *gorm.DB, wrapper wrapping.Wrapper, r
return k, rootKeyVersionWrapper return k, rootKeyVersionWrapper
} }
func TestKms(t *testing.T, conn *gorm.DB, rootWrapper wrapping.Wrapper) *Kms { func TestKms(t *testing.T, conn *db.DB, rootWrapper wrapping.Wrapper) *Kms {
t.Helper() t.Helper()
require := require.New(t) require := require.New(t)
rw := db.New(conn) rw := db.New(conn)
@@ -61,7 +60,7 @@ func TestKms(t *testing.T, conn *gorm.DB, rootWrapper wrapping.Wrapper) *Kms {
return kms return kms
} }
func TestDatabaseKey(t *testing.T, conn *gorm.DB, rootKeyId string) *DatabaseKey { func TestDatabaseKey(t *testing.T, conn *db.DB, rootKeyId string) *DatabaseKey {
t.Helper() t.Helper()
require := require.New(t) require := require.New(t)
rw := db.New(conn) rw := db.New(conn)
@@ -77,7 +76,7 @@ func TestDatabaseKey(t *testing.T, conn *gorm.DB, rootKeyId string) *DatabaseKey
return k return k
} }
func TestDatabaseKeyVersion(t *testing.T, conn *gorm.DB, rootKeyVersionWrapper wrapping.Wrapper, databaseKeyId string, key []byte) *DatabaseKeyVersion { func TestDatabaseKeyVersion(t *testing.T, conn *db.DB, rootKeyVersionWrapper wrapping.Wrapper, databaseKeyId string, key []byte) *DatabaseKeyVersion {
t.Helper() t.Helper()
require := require.New(t) require := require.New(t)
rw := db.New(conn) rw := db.New(conn)
@@ -95,7 +94,7 @@ func TestDatabaseKeyVersion(t *testing.T, conn *gorm.DB, rootKeyVersionWrapper w
return k return k
} }
func TestOplogKey(t *testing.T, conn *gorm.DB, rootKeyId string) *OplogKey { func TestOplogKey(t *testing.T, conn *db.DB, rootKeyId string) *OplogKey {
t.Helper() t.Helper()
require := require.New(t) require := require.New(t)
rw := db.New(conn) rw := db.New(conn)
@@ -111,7 +110,7 @@ func TestOplogKey(t *testing.T, conn *gorm.DB, rootKeyId string) *OplogKey {
return k return k
} }
func TestOplogKeyVersion(t *testing.T, conn *gorm.DB, rootKeyVersionWrapper wrapping.Wrapper, oplogKeyId string, key []byte) *OplogKeyVersion { func TestOplogKeyVersion(t *testing.T, conn *db.DB, rootKeyVersionWrapper wrapping.Wrapper, oplogKeyId string, key []byte) *OplogKeyVersion {
t.Helper() t.Helper()
require := require.New(t) require := require.New(t)
rw := db.New(conn) rw := db.New(conn)
@@ -129,7 +128,7 @@ func TestOplogKeyVersion(t *testing.T, conn *gorm.DB, rootKeyVersionWrapper wrap
return k return k
} }
func TestTokenKey(t *testing.T, conn *gorm.DB, rootKeyId string) *TokenKey { func TestTokenKey(t *testing.T, conn *db.DB, rootKeyId string) *TokenKey {
t.Helper() t.Helper()
require := require.New(t) require := require.New(t)
rw := db.New(conn) rw := db.New(conn)
@@ -145,7 +144,7 @@ func TestTokenKey(t *testing.T, conn *gorm.DB, rootKeyId string) *TokenKey {
return k return k
} }
func TestTokenKeyVersion(t *testing.T, conn *gorm.DB, rootKeyVersionWrapper wrapping.Wrapper, tokenKeyId string, key []byte) *TokenKeyVersion { func TestTokenKeyVersion(t *testing.T, conn *db.DB, rootKeyVersionWrapper wrapping.Wrapper, tokenKeyId string, key []byte) *TokenKeyVersion {
t.Helper() t.Helper()
require := require.New(t) require := require.New(t)
rw := db.New(conn) rw := db.New(conn)
@@ -163,7 +162,7 @@ func TestTokenKeyVersion(t *testing.T, conn *gorm.DB, rootKeyVersionWrapper wrap
return k return k
} }
func TestSessionKey(t *testing.T, conn *gorm.DB, rootKeyId string) *SessionKey { func TestSessionKey(t *testing.T, conn *db.DB, rootKeyId string) *SessionKey {
t.Helper() t.Helper()
require := require.New(t) require := require.New(t)
rw := db.New(conn) rw := db.New(conn)
@@ -179,7 +178,7 @@ func TestSessionKey(t *testing.T, conn *gorm.DB, rootKeyId string) *SessionKey {
return k return k
} }
func TestSessionKeyVersion(t *testing.T, conn *gorm.DB, rootKeyVersionWrapper wrapping.Wrapper, sessionKeyId string, key []byte) *SessionKeyVersion { func TestSessionKeyVersion(t *testing.T, conn *db.DB, rootKeyVersionWrapper wrapping.Wrapper, sessionKeyId string, key []byte) *SessionKeyVersion {
t.Helper() t.Helper()
require := require.New(t) require := require.New(t)
rw := db.New(conn) rw := db.New(conn)
@@ -197,7 +196,7 @@ func TestSessionKeyVersion(t *testing.T, conn *gorm.DB, rootKeyVersionWrapper wr
return k return k
} }
func TestOidcKey(t *testing.T, conn *gorm.DB, rootKeyId string) *OidcKey { func TestOidcKey(t *testing.T, conn *db.DB, rootKeyId string) *OidcKey {
t.Helper() t.Helper()
require := require.New(t) require := require.New(t)
rw := db.New(conn) rw := db.New(conn)
@@ -213,7 +212,7 @@ func TestOidcKey(t *testing.T, conn *gorm.DB, rootKeyId string) *OidcKey {
return k return k
} }
func TestOidcKeyVersion(t *testing.T, conn *gorm.DB, rootKeyVersionWrapper wrapping.Wrapper, oidcKeyId string, key []byte) *OidcKeyVersion { func TestOidcKeyVersion(t *testing.T, conn *db.DB, rootKeyVersionWrapper wrapping.Wrapper, oidcKeyId string, key []byte) *OidcKeyVersion {
t.Helper() t.Helper()
require := require.New(t) require := require.New(t)
rw := db.New(conn) rw := db.New(conn)
+2 -2
View File
@@ -3,9 +3,9 @@ package oplog
import ( import (
"context" "context"
"crypto/rand" "crypto/rand"
"database/sql"
"testing" "testing"
"github.com/hashicorp/boundary/internal/db/common"
"github.com/hashicorp/boundary/internal/db/schema" "github.com/hashicorp/boundary/internal/db/schema"
"github.com/hashicorp/boundary/internal/oplog/oplog_test" "github.com/hashicorp/boundary/internal/oplog/oplog_test"
"github.com/hashicorp/boundary/testing/dbtest" "github.com/hashicorp/boundary/testing/dbtest"
@@ -86,7 +86,7 @@ func testInitStore(t *testing.T, cleanup func() error, url string) {
ctx := context.Background() ctx := context.Background()
dialect := "postgres" dialect := "postgres"
d, err := sql.Open(dialect, url) d, err := common.SqlOpen(dialect, url)
require.NoError(t, err) require.NoError(t, err)
sm, err := schema.NewManager(ctx, dialect, d) sm, err := schema.NewManager(ctx, dialect, d)
require.NoError(t, err) require.NoError(t, err)
+2 -2
View File
@@ -1,9 +1,9 @@
package oplog package oplog
import ( import (
"database/sql"
"testing" "testing"
"github.com/hashicorp/boundary/internal/db/common"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@@ -77,7 +77,7 @@ func Test_testInitStore(t *testing.T) {
const query = ` const query = `
select count(*) from information_schema."tables" t where table_name = 'db_test_user'; select count(*) from information_schema."tables" t where table_name = 'db_test_user';
` `
db, err := sql.Open("postgres", url) db, err := common.SqlOpen("postgres", url)
require.NoError(err) require.NoError(err)
var cnt int var cnt int
+4 -5
View File
@@ -12,10 +12,9 @@ import (
wrapping "github.com/hashicorp/go-kms-wrapping" wrapping "github.com/hashicorp/go-kms-wrapping"
"github.com/hashicorp/go-uuid" "github.com/hashicorp/go-uuid"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gorm.io/gorm"
) )
func testJob(t *testing.T, conn *gorm.DB, name, description string, wrapper wrapping.Wrapper, opt ...Option) *Job { func testJob(t *testing.T, conn *db.DB, name, description string, wrapper wrapping.Wrapper, opt ...Option) *Job {
t.Helper() t.Helper()
require := require.New(t) require := require.New(t)
rw := db.New(conn) rw := db.New(conn)
@@ -31,7 +30,7 @@ func testJob(t *testing.T, conn *gorm.DB, name, description string, wrapper wrap
return job return job
} }
func testRun(conn *gorm.DB, pluginId, name, cId string) (*Run, error) { func testRun(conn *db.DB, pluginId, name, cId string) (*Run, error) {
query := ` query := `
insert into job_run ( insert into job_run (
job_plugin_id, job_name, server_id job_plugin_id, job_name, server_id
@@ -59,7 +58,7 @@ func testRun(conn *gorm.DB, pluginId, name, cId string) (*Run, error) {
return run, nil return run, nil
} }
func testRunWithUpdateTime(conn *gorm.DB, pluginId, name, cId string, updateTime time.Time) (*Run, error) { func testRunWithUpdateTime(conn *db.DB, pluginId, name, cId string, updateTime time.Time) (*Run, error) {
query := ` query := `
insert into job_run ( insert into job_run (
job_plugin_id, job_name, server_id, update_time job_plugin_id, job_name, server_id, update_time
@@ -87,7 +86,7 @@ func testRunWithUpdateTime(conn *gorm.DB, pluginId, name, cId string, updateTime
return run, nil return run, nil
} }
func testController(t *testing.T, conn *gorm.DB, wrapper wrapping.Wrapper) *servers.Server { func testController(t *testing.T, conn *db.DB, wrapper wrapping.Wrapper) *servers.Server {
t.Helper() t.Helper()
rw := db.New(conn) rw := db.New(conn)
kms := kms.TestKms(t, conn, wrapper) kms := kms.TestKms(t, conn, wrapper)
+1 -2
View File
@@ -14,7 +14,6 @@ import (
wrapping "github.com/hashicorp/go-kms-wrapping" wrapping "github.com/hashicorp/go-kms-wrapping"
"github.com/hashicorp/go-uuid" "github.com/hashicorp/go-uuid"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gorm.io/gorm"
) )
// TestScheduler creates a mock controller and a new Scheduler attached to that controller id. // TestScheduler creates a mock controller and a new Scheduler attached to that controller id.
@@ -22,7 +21,7 @@ import (
// //
// WithRunJobsLimit, WithRunJobsInterval, WithMonitorInterval and WithInterruptThreshold are // WithRunJobsLimit, WithRunJobsInterval, WithMonitorInterval and WithInterruptThreshold are
// the only valid options. // the only valid options.
func TestScheduler(t *testing.T, conn *gorm.DB, wrapper wrapping.Wrapper, opt ...Option) *Scheduler { func TestScheduler(t *testing.T, conn *db.DB, wrapper wrapping.Wrapper, opt ...Option) *Scheduler {
t.Helper() t.Helper()
rw := db.New(conn) rw := db.New(conn)
@@ -41,12 +41,11 @@ import (
"google.golang.org/protobuf/types/known/structpb" "google.golang.org/protobuf/types/known/structpb"
"google.golang.org/protobuf/types/known/timestamppb" "google.golang.org/protobuf/types/known/timestamppb"
"google.golang.org/protobuf/types/known/wrapperspb" "google.golang.org/protobuf/types/known/wrapperspb"
"gorm.io/gorm"
) )
type setup struct { type setup struct {
ctx context.Context ctx context.Context
conn *gorm.DB conn *db.DB
rw *db.Db rw *db.Db
rootWrapper wrapping.Wrapper rootWrapper wrapping.Wrapper
kmsCache *kms.Kms kmsCache *kms.Kms
@@ -47,7 +47,6 @@ import (
"google.golang.org/protobuf/types/known/structpb" "google.golang.org/protobuf/types/known/structpb"
"google.golang.org/protobuf/types/known/timestamppb" "google.golang.org/protobuf/types/known/timestamppb"
"google.golang.org/protobuf/types/known/wrapperspb" "google.golang.org/protobuf/types/known/wrapperspb"
"gorm.io/gorm"
) )
var testAuthorizedActions = []string{ var testAuthorizedActions = []string{
@@ -67,7 +66,7 @@ var testAuthorizedActions = []string{
"authorize-session", "authorize-session",
} }
func testService(t *testing.T, conn *gorm.DB, kms *kms.Kms, wrapper wrapping.Wrapper) (targets.Service, error) { func testService(t *testing.T, conn *db.DB, kms *kms.Kms, wrapper wrapping.Wrapper) (targets.Service, error) {
rw := db.New(conn) rw := db.New(conn)
sche := scheduler.TestScheduler(t, conn, wrapper) sche := scheduler.TestScheduler(t, conn, wrapper)
repoFn := func() (*target.Repository, error) { repoFn := func() (*target.Repository, error) {
+5 -5
View File
@@ -16,6 +16,7 @@ import (
"github.com/hashicorp/boundary/internal/authtoken" "github.com/hashicorp/boundary/internal/authtoken"
"github.com/hashicorp/boundary/internal/cmd/base" "github.com/hashicorp/boundary/internal/cmd/base"
"github.com/hashicorp/boundary/internal/cmd/config" "github.com/hashicorp/boundary/internal/cmd/config"
"github.com/hashicorp/boundary/internal/db"
"github.com/hashicorp/boundary/internal/db/schema" "github.com/hashicorp/boundary/internal/db/schema"
"github.com/hashicorp/boundary/internal/iam" "github.com/hashicorp/boundary/internal/iam"
"github.com/hashicorp/boundary/internal/intglobals" "github.com/hashicorp/boundary/internal/intglobals"
@@ -26,7 +27,6 @@ import (
wrapping "github.com/hashicorp/go-kms-wrapping" wrapping "github.com/hashicorp/go-kms-wrapping"
"github.com/hashicorp/go-secure-stdlib/base62" "github.com/hashicorp/go-secure-stdlib/base62"
"github.com/hashicorp/go-secure-stdlib/strutil" "github.com/hashicorp/go-secure-stdlib/strutil"
"gorm.io/gorm"
) )
const ( const (
@@ -126,7 +126,7 @@ func (tc *TestController) ClusterAddrs() []string {
return tc.addrs("cluster") return tc.addrs("cluster")
} }
func (tc *TestController) DbConn() *gorm.DB { func (tc *TestController) DbConn() *db.DB {
return tc.b.Database return tc.b.Database
} }
@@ -272,8 +272,8 @@ func (tc *TestController) Shutdown() {
tc.t.Error(err) tc.t.Error(err)
} }
if !tc.opts.DisableDatabaseDestruction { if !tc.opts.DisableDatabaseDestruction {
if tc.b.DestroyDevDatabase() != nil { if tc.b.DestroyDevDatabase(tc.ctx) != nil {
if err := tc.b.DestroyDevDatabase(); err != nil { if err := tc.b.DestroyDevDatabase(tc.ctx); err != nil {
tc.t.Error(err) tc.t.Error(err)
} }
} }
@@ -536,7 +536,7 @@ func NewTestController(t *testing.T, opts *TestControllerOpts) *TestController {
if _, err := schema.MigrateStore(ctx, "postgres", tc.b.DatabaseUrl); err != nil { if _, err := schema.MigrateStore(ctx, "postgres", tc.b.DatabaseUrl); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if err := tc.b.ConnectToDatabase("postgres"); err != nil { if err := tc.b.ConnectToDatabase(tc.ctx, "postgres"); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if !opts.DisableKmsKeyCreation { if !opts.DisableKmsKeyCreation {
+8 -9
View File
@@ -19,7 +19,6 @@ import (
wrapping "github.com/hashicorp/go-kms-wrapping" wrapping "github.com/hashicorp/go-kms-wrapping"
"github.com/jackc/pgconn" "github.com/jackc/pgconn"
"google.golang.org/protobuf/types/known/timestamppb" "google.golang.org/protobuf/types/known/timestamppb"
"gorm.io/gorm"
"github.com/hashicorp/boundary/internal/errors" "github.com/hashicorp/boundary/internal/errors"
"github.com/hashicorp/boundary/internal/iam" "github.com/hashicorp/boundary/internal/iam"
@@ -1408,13 +1407,13 @@ func TestRepository_CancelSessionViaFKNull(t *testing.T) {
rowsDeleted, err := rw.Delete(context.Background(), tt.cancelFk.fkType) rowsDeleted, err := rw.Delete(context.Background(), tt.cancelFk.fkType)
if err != nil { if err != nil {
var pqError *pgconn.PgError var pgError *pgconn.PgError
if errors.As(err, &pqError) { if errors.As(err, &pgError) {
t.Log(pqError.Message) t.Log(pgError.Message)
t.Log(pqError.Detail) t.Log(pgError.Detail)
t.Log(pqError.Where) t.Log(pgError.Where)
t.Log(pqError.ConstraintName) t.Log(pgError.ConstraintName)
t.Log(pqError.TableName) t.Log(pgError.TableName)
} }
} }
require.NoError(err) require.NoError(err)
@@ -1642,7 +1641,7 @@ func TestRepository_DeleteSession(t *testing.T) {
} }
} }
func testSessionCredentialParams(t *testing.T, conn *gorm.DB, wrapper wrapping.Wrapper, iamRepo *iam.Repository) ComposedOf { func testSessionCredentialParams(t *testing.T, conn *db.DB, wrapper wrapping.Wrapper, iamRepo *iam.Repository) ComposedOf {
t.Helper() t.Helper()
params := TestSessionParams(t, conn, wrapper, iamRepo) params := TestSessionParams(t, conn, wrapper, iamRepo)
require := require.New(t) require := require.New(t)
+7 -8
View File
@@ -20,11 +20,10 @@ import (
"github.com/hashicorp/go-uuid" "github.com/hashicorp/go-uuid"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"google.golang.org/protobuf/types/known/timestamppb" "google.golang.org/protobuf/types/known/timestamppb"
"gorm.io/gorm"
) )
// TestConnection creates a test connection for the sessionId in the repository. // TestConnection creates a test connection for the sessionId in the repository.
func TestConnection(t *testing.T, conn *gorm.DB, sessionId, clientTcpAddr string, clientTcpPort uint32, endpointTcpAddr string, endpointTcpPort uint32) *Connection { func TestConnection(t *testing.T, conn *db.DB, sessionId, clientTcpAddr string, clientTcpPort uint32, endpointTcpAddr string, endpointTcpPort uint32) *Connection {
t.Helper() t.Helper()
require := require.New(t) require := require.New(t)
rw := db.New(conn) rw := db.New(conn)
@@ -44,7 +43,7 @@ func TestConnection(t *testing.T, conn *gorm.DB, sessionId, clientTcpAddr string
} }
// TestConnectionState creates a test connection state for the connectionId in the repository. // TestConnectionState creates a test connection state for the connectionId in the repository.
func TestConnectionState(t *testing.T, conn *gorm.DB, connectionId string, state ConnectionStatus) *ConnectionState { func TestConnectionState(t *testing.T, conn *db.DB, connectionId string, state ConnectionStatus) *ConnectionState {
t.Helper() t.Helper()
require := require.New(t) require := require.New(t)
rw := db.New(conn) rw := db.New(conn)
@@ -56,7 +55,7 @@ func TestConnectionState(t *testing.T, conn *gorm.DB, connectionId string, state
} }
// TestState creates a test state for the sessionId in the repository. // TestState creates a test state for the sessionId in the repository.
func TestState(t *testing.T, conn *gorm.DB, sessionId string, state Status) *State { func TestState(t *testing.T, conn *db.DB, sessionId string, state Status) *State {
t.Helper() t.Helper()
require := require.New(t) require := require.New(t)
rw := db.New(conn) rw := db.New(conn)
@@ -69,7 +68,7 @@ func TestState(t *testing.T, conn *gorm.DB, sessionId string, state Status) *Sta
// TestSession creates a test session composed of c in the repository. Options // TestSession creates a test session composed of c in the repository. Options
// are passed into New, and withServerId is handled locally. // are passed into New, and withServerId is handled locally.
func TestSession(t *testing.T, conn *gorm.DB, wrapper wrapping.Wrapper, c ComposedOf, opt ...Option) *Session { func TestSession(t *testing.T, conn *db.DB, wrapper wrapping.Wrapper, c ComposedOf, opt ...Option) *Session {
t.Helper() t.Helper()
ctx := context.Background() ctx := context.Background()
opts := getOpts(opt...) opts := getOpts(opt...)
@@ -110,7 +109,7 @@ func TestSession(t *testing.T, conn *gorm.DB, wrapper wrapping.Wrapper, c Compos
} }
// TestDefaultSession creates a test session in the repository using defaults. // TestDefaultSession creates a test session in the repository using defaults.
func TestDefaultSession(t *testing.T, conn *gorm.DB, wrapper wrapping.Wrapper, iamRepo *iam.Repository, opt ...Option) *Session { func TestDefaultSession(t *testing.T, conn *db.DB, wrapper wrapping.Wrapper, iamRepo *iam.Repository, opt ...Option) *Session {
t.Helper() t.Helper()
composedOf := TestSessionParams(t, conn, wrapper, iamRepo) composedOf := TestSessionParams(t, conn, wrapper, iamRepo)
future := timestamppb.New(time.Now().Add(time.Hour)) future := timestamppb.New(time.Now().Add(time.Hour))
@@ -120,7 +119,7 @@ func TestDefaultSession(t *testing.T, conn *gorm.DB, wrapper wrapping.Wrapper, i
// TestSessionParams returns an initialized ComposedOf which can be used to // TestSessionParams returns an initialized ComposedOf which can be used to
// create a session in the repository. // create a session in the repository.
func TestSessionParams(t *testing.T, conn *gorm.DB, wrapper wrapping.Wrapper, iamRepo *iam.Repository) ComposedOf { func TestSessionParams(t *testing.T, conn *db.DB, wrapper wrapping.Wrapper, iamRepo *iam.Repository) ComposedOf {
t.Helper() t.Helper()
ctx := context.Background() ctx := context.Background()
@@ -176,7 +175,7 @@ func TestTofu(t *testing.T) []byte {
// TestWorker inserts a worker into the db to satisfy foreign key constraints. // TestWorker inserts a worker into the db to satisfy foreign key constraints.
// Supports the WithServerId option. // Supports the WithServerId option.
func TestWorker(t *testing.T, conn *gorm.DB, wrapper wrapping.Wrapper, opt ...Option) *servers.Server { func TestWorker(t *testing.T, conn *db.DB, wrapper wrapping.Wrapper, opt ...Option) *servers.Server {
t.Helper() t.Helper()
rw := db.New(conn) rw := db.New(conn)
kms := kms.TestKms(t, conn, wrapper) kms := kms.TestKms(t, conn, wrapper)
@@ -219,6 +219,7 @@ func TestRepository_CreateTcpTarget(t *testing.T) {
func TestRepository_UpdateTcpTarget(t *testing.T) { func TestRepository_UpdateTcpTarget(t *testing.T) {
t.Parallel() t.Parallel()
ctx := context.Background()
conn, _ := db.TestSetup(t, "postgres") conn, _ := db.TestSetup(t, "postgres")
rw := db.New(conn) rw := db.New(conn)
wrapper := db.TestWrapper(t) wrapper := db.TestWrapper(t)
@@ -491,7 +492,7 @@ func TestRepository_UpdateTcpTarget(t *testing.T) {
foundTarget, _, _, err := repo.LookupTarget(context.Background(), target.PublicId) foundTarget, _, _, err := repo.LookupTarget(context.Background(), target.PublicId)
assert.NoError(err) assert.NoError(err)
assert.True(proto.Equal(targetAfterUpdate.((*TcpTarget)), foundTarget.((*TcpTarget)))) assert.True(proto.Equal(targetAfterUpdate.((*TcpTarget)), foundTarget.((*TcpTarget))))
underlyingDB, err := conn.DB() underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err) require.NoError(err)
dbassert := dbassert.New(t, underlyingDB) dbassert := dbassert.New(t, underlyingDB)
if tt.args.description == "" { if tt.args.description == "" {
+2 -1
View File
@@ -146,6 +146,7 @@ func TestTcpTarget_Delete(t *testing.T) {
func TestTcpTarget_Update(t *testing.T) { func TestTcpTarget_Update(t *testing.T) {
t.Parallel() t.Parallel()
id := testId(t) id := testId(t)
ctx := context.Background()
conn, _ := db.TestSetup(t, "postgres") conn, _ := db.TestSetup(t, "postgres")
rw := db.New(conn) rw := db.New(conn)
wrapper := db.TestWrapper(t) wrapper := db.TestWrapper(t)
@@ -279,7 +280,7 @@ func TestTcpTarget_Update(t *testing.T) {
require.NoError(err) require.NoError(err)
assert.True(proto.Equal(updateTarget, foundTarget)) assert.True(proto.Equal(updateTarget, foundTarget))
if len(tt.args.nullPaths) != 0 { if len(tt.args.nullPaths) != 0 {
underlyingDB, err := conn.DB() underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err) require.NoError(err)
dbassert := dbassert.New(t, underlyingDB) dbassert := dbassert.New(t, underlyingDB)
for _, f := range tt.args.nullPaths { for _, f := range tt.args.nullPaths {
+2 -3
View File
@@ -8,10 +8,9 @@ import (
"github.com/hashicorp/boundary/internal/db" "github.com/hashicorp/boundary/internal/db"
"github.com/hashicorp/go-uuid" "github.com/hashicorp/go-uuid"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"gorm.io/gorm"
) )
func TestTcpTarget(t *testing.T, conn *gorm.DB, scopeId, name string, opt ...Option) *TcpTarget { func TestTcpTarget(t *testing.T, conn *db.DB, scopeId, name string, opt ...Option) *TcpTarget {
t.Helper() t.Helper()
opt = append(opt, WithName(name)) opt = append(opt, WithName(name))
opts := getOpts(opt...) opts := getOpts(opt...)
@@ -62,7 +61,7 @@ func testId(t *testing.T) string {
// TestCredentialLibrary creates a CredentialLibrary for targetId and // TestCredentialLibrary creates a CredentialLibrary for targetId and
// libraryId. // libraryId.
func TestCredentialLibrary(t *testing.T, conn *gorm.DB, targetId, libraryId string) *CredentialLibrary { func TestCredentialLibrary(t *testing.T, conn *db.DB, targetId, libraryId string) *CredentialLibrary {
t.Helper() t.Helper()
require := require.New(t) require := require.New(t)
rw := db.New(conn) rw := db.New(conn)
+1 -1
View File
@@ -12,7 +12,7 @@
// require.NoError(t, c()) // require.NoError(t, c())
// }) // })
// // use u to get a connection to the new database // // use u to get a connection to the new database
// dBase, err := sql.Open("postgres", u) // dBase, err := common.SqlOpen("postgres", u)
// //
// By default this uses a template that already has all of the boundary // By default this uses a template that already has all of the boundary
// migrations run. If a test needs a database without any migrations, like in // migrations run. If a test needs a database without any migrations, like in
+9 -5
View File
@@ -1,14 +1,15 @@
package dbtest package dbtest
import ( import (
"database/sql"
"fmt" "fmt"
"math/rand" "math/rand"
"os" "os"
"time" "time"
// postgres dialect // postgres dialect
_ "github.com/lib/pq"
"github.com/hashicorp/boundary/internal/db/common"
_ "github.com/jackc/pgx/v4/stdlib"
) )
var testDBPort = "5432" var testDBPort = "5432"
@@ -75,7 +76,10 @@ func startUsingTemplate(dialect string, opt ...Option) (cleanup func() error, re
return func() error { return nil }, "", "", fmt.Errorf("unsupported dialect: %s", dialect) return func() error { return nil }, "", "", fmt.Errorf("unsupported dialect: %s", dialect)
} }
db, err := sql.Open(dialect, fmt.Sprintf("postgres://boundary:boundary@127.0.0.1:%s/boundary?sslmode=disable", testDBPort)) if dialect == "postgres" {
dialect = "pgx"
}
db, err := common.SqlOpen(dialect, fmt.Sprintf("postgres://boundary:boundary@127.0.0.1:%s/boundary?sslmode=disable", testDBPort))
if err != nil { if err != nil {
return func() error { return nil }, "", "", fmt.Errorf("could not connect to source database: %w", err) return func() error { return nil }, "", "", fmt.Errorf("could not connect to source database: %w", err)
} }
@@ -103,7 +107,7 @@ func startUsingTemplate(dialect string, opt ...Option) (cleanup func() error, re
return dropDatabase(dialect, dbname) return dropDatabase(dialect, dbname)
} }
tdb, err := sql.Open(dialect, url) tdb, err := common.SqlOpen(dialect, url)
if err != nil { if err != nil {
return func() error { return nil }, "", "", fmt.Errorf("could not create test database: %w", err) return func() error { return nil }, "", "", fmt.Errorf("could not create test database: %w", err)
} }
@@ -130,7 +134,7 @@ func dropDatabase(dialect, dbname string) error {
return fmt.Errorf("empty dbname") return fmt.Errorf("empty dbname")
} }
db, err := sql.Open(dialect, fmt.Sprintf("postgres://boundary:boundary@127.0.0.1:%s/boundary?sslmode=disable", testDBPort)) db, err := common.SqlOpen(dialect, fmt.Sprintf("postgres://boundary:boundary@127.0.0.1:%s/boundary?sslmode=disable", testDBPort))
if err != nil { if err != nil {
return err return err
} }
+3 -3
View File
@@ -1,10 +1,10 @@
package dbtest_test package dbtest_test
import ( import (
"database/sql"
"errors" "errors"
"testing" "testing"
"github.com/hashicorp/boundary/internal/db/common"
"github.com/hashicorp/boundary/testing/dbtest" "github.com/hashicorp/boundary/testing/dbtest"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@@ -56,7 +56,7 @@ func TestStartUsingTemplate(t *testing.T) {
} else { } else {
require.NoError(t, err) require.NoError(t, err)
db, err := sql.Open(tt.dialect, u) db, err := common.SqlOpen(tt.dialect, u)
require.NoError(t, err) require.NoError(t, err)
require.NoError(t, db.Ping()) require.NoError(t, db.Ping())
db.Close() db.Close()
@@ -64,7 +64,7 @@ func TestStartUsingTemplate(t *testing.T) {
require.NoError(t, c()) require.NoError(t, c())
// ensure that database is gone after calling c // ensure that database is gone after calling c
db, _ = sql.Open(tt.dialect, u) db, _ = common.SqlOpen(tt.dialect, u)
require.Error(t, db.Ping()) require.Error(t, db.Ping())
} }
}) })