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
* Jeff
* github.com/lib/pq
* Jim
* Mike
* github.com/jackc/pgx
* Jim
* Mike
* github.com/mattn/go-colorable
+1 -2
View File
@@ -52,12 +52,11 @@ require (
github.com/hashicorp/vault/sdk v0.2.1
github.com/iancoleman/strcase v0.2.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/jinzhu/gorm v1.9.12
github.com/json-iterator/go v1.1.10 // indirect
github.com/kr/pretty v0.3.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-isatty v0.0.13 // indirect
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.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.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg=
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-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
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.NotSame(tt.orig, got)
assert.Equal(tt.orig.AuthMethodId, got.AuthMethodId)
underlyingDB, err := conn.DB()
underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err)
dbassert := dbassert.New(t, underlyingDB)
if tt.want.Name == "" {
@@ -952,7 +952,7 @@ func TestRepository_UpdateManagedGroup(t *testing.T) {
assert.Equal(tt.wantCount, gotCount, "row count")
assert.NotSame(tt.orig, got)
assert.Equal(tt.orig.AuthMethodId, got.AuthMethodId)
underlyingDB, err := conn.DB()
underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err)
dbassert := dbassert.New(t, underlyingDB)
if tt.want.Name == "" {
+4 -5
View File
@@ -31,7 +31,6 @@ import (
wrapping "github.com/hashicorp/go-kms-wrapping"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/types/known/timestamppb"
"gorm.io/gorm"
)
const TestFakeManagedGroupFilter = `"/foo" == "bar"`
@@ -41,7 +40,7 @@ const TestFakeManagedGroupFilter = `"/foo" == "bar"`
// WithSigningAlgs options are supported.
func TestAuthMethod(
t *testing.T,
conn *gorm.DB,
conn *db.DB,
databaseWrapper wrapping.Wrapper,
scopeId string,
state AuthMethodState,
@@ -158,7 +157,7 @@ func TestSortAuthMethods(t *testing.T, methods []*AuthMethod) {
}
// 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()
require := require.New(t)
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.
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()
require := require.New(t)
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
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()
require := require.New(t)
rw := db.New(conn)
+1 -2
View File
@@ -10,7 +10,6 @@ import (
"github.com/hashicorp/boundary/internal/iam"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gorm.io/gorm"
)
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()
assert, require := assert.New(t), require.New(t)
rw := db.New(conn)
@@ -589,6 +589,7 @@ func TestRepository_UpdateAccount(t *testing.T) {
wrapper := db.TestWrapper(t)
kms := kms.TestKms(t, conn, wrapper)
iamRepo := iam.TestRepo(t, conn, wrapper)
ctx := context.Background()
changeLoginName := func(s string) func(*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.NotSame(tt.orig, got)
assert.Equal(tt.orig.AuthMethodId, got.AuthMethodId)
underlyingDB, err := conn.DB()
underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err)
dbassert := dbassert.New(t, underlyingDB)
if tt.want.Name == "" {
@@ -769,7 +769,7 @@ func TestRepository_UpdateAuthMethod(t *testing.T) {
require.NoError(err)
assert.Empty(cmp.Diff(updatedAM, foundAuthMethod, protocmp.Transform()))
underlyingDB, err := conn.DB()
underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err)
dbassert := dbassert.New(t, underlyingDB)
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/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gorm.io/gorm"
)
// 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
// 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()
assert, require := assert.New(t), require.New(t)
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
// with the provided scope id. If any errors are encountered during the creation of
// 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()
var auts []*AuthMethod
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
// 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.
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()
var auts []*Account
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
// 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.
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()
assert, require := assert.New(t), require.New(t)
require.NotEmpty(loginName)
+1 -2
View File
@@ -9,10 +9,9 @@ import (
"github.com/hashicorp/boundary/internal/iam"
"github.com/hashicorp/boundary/internal/kms"
"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()
authMethod := password.TestAuthMethods(t, conn, scopeId, 1)[0]
// 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, "/")
}
if err := b.ConnectToDatabase(dialect); err != nil {
if err := b.ConnectToDatabase(ctx, dialect); err != nil {
if c != nil {
err = multierror.Append(err, c())
}
@@ -4,11 +4,12 @@
package docker
import (
"database/sql"
"fmt"
"os"
"strings"
"github.com/hashicorp/boundary/internal/db/common"
_ "github.com/jackc/pgx/v4/stdlib"
"github.com/ory/dockertest/v3"
)
@@ -37,7 +38,7 @@ func startDbInDockerSupported(dialect string, opt ...Option) (cleanup func() err
}
switch dialect {
case "postgres":
case "postgres", "pgx":
switch {
case 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 {
db, err := sql.Open(dialect, url)
db, err := common.SqlOpen(dialect, url)
if err != nil {
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/mitchellh/cli"
"google.golang.org/grpc/grpclog"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
const (
@@ -120,7 +118,7 @@ type Server struct {
DatabaseMaxOpenConnections int
DevDatabaseCleanupFunc func() error
Database *gorm.DB
Database *db.DB
// StatusGracePeriodDuration represents the period of time (as a
// duration) that the controller will wait before marking
@@ -548,38 +546,22 @@ func (b *Server) RunShutdownFuncs() error {
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)
if err != nil {
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 {
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
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
}
@@ -618,13 +600,11 @@ func (b *Server) CreateGlobalKmsKeys(ctx context.Context) error {
return nil
}
func (b *Server) DestroyDevDatabase() error {
func (b *Server) DestroyDevDatabase(ctx context.Context) error {
if b.Database != nil {
underlyingDB, err := b.Database.DB()
if err != nil {
if err := b.Database.Close(ctx); err != nil {
return err
}
underlyingDB.Close()
}
if b.DevDatabaseCleanupFunc != nil {
return b.DevDatabaseCleanupFunc()
+2 -2
View File
@@ -2,10 +2,10 @@ package database
import (
"context"
"database/sql"
"fmt"
"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/errors"
"github.com/mitchellh/cli"
@@ -20,7 +20,7 @@ func migrateDatabase(ctx context.Context, ui cli.Ui, dialect, u string, initiali
noop := func() {}
// This database is used to keep an exclusive lock on the database for the
// remainder of the command
dBase, err := sql.Open(dialect, u)
dBase, err := common.SqlOpen(dialect, u)
if err != nil {
ui.Error(fmt.Errorf("Error establishing db connection: %w", err).Error())
return noop, 2
+10 -10
View File
@@ -2,10 +2,10 @@ package database
import (
"context"
"database/sql"
"testing"
"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/testing/dbtest"
"github.com/mitchellh/cli"
@@ -49,7 +49,7 @@ func TestMigrateDatabase(t *testing.T) {
require.NoError(t, c())
})
dBase, err := sql.Open(dialect, u)
dBase, err := common.SqlOpen(dialect, u)
require.NoError(t, err)
earlyMigrationVersion := 2000
@@ -75,7 +75,7 @@ func TestMigrateDatabase(t *testing.T) {
require.NoError(t, c())
})
dBase, err := sql.Open(dialect, u)
dBase, err := common.SqlOpen(dialect, u)
require.NoError(t, err)
earlyMigrationVersion := 2000
@@ -100,7 +100,7 @@ func TestMigrateDatabase(t *testing.T) {
t.Cleanup(func() {
require.NoError(t, c())
})
dBase, err := sql.Open(dialect, u)
dBase, err := common.SqlOpen(dialect, u)
require.NoError(t, err)
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() {
require.NoError(t, c())
})
dBase, err := sql.Open(dialect, u)
dBase, err := common.SqlOpen(dialect, u)
require.NoError(t, err)
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() {
require.NoError(t, c())
})
dBase, err := sql.Open(dialect, u)
dBase, err := common.SqlOpen(dialect, u)
require.NoError(t, err)
man, err := schema.NewManager(ctx, dialect, dBase)
@@ -177,7 +177,7 @@ func TestMigrateDatabase(t *testing.T) {
t.Cleanup(func() {
require.NoError(t, c())
})
dBase, err := sql.Open(dialect, u)
dBase, err := common.SqlOpen(dialect, u)
require.NoError(t, err)
man, err := schema.NewManager(ctx, dialect, dBase)
@@ -217,7 +217,7 @@ func TestVerifyOplogIsEmpty(t *testing.T) {
})
_ = c
dBase, err := sql.Open(dialect, u)
dBase, err := common.SqlOpen(dialect, u)
require.NoError(t, err)
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.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
import (
"context"
"fmt"
"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) {
ctx := context.Background()
if result := c.ParseFlagsAndConfig(args); result > 0 {
return result
}
@@ -277,11 +279,11 @@ func (c *InitCommand) Run(args []string) (retCode int) {
return base.CommandUserError
}
// 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())
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))
return base.CommandCliError
}
@@ -491,9 +493,9 @@ func (c *InitCommand) ParseFlagsAndConfig(args []string) int {
return base.CommandSuccess
}
func (c *InitCommand) verifyOplogIsEmpty() error {
func (c *InitCommand) verifyOplogIsEmpty(ctx context.Context) error {
const op = "database.(InitCommand).verifyOplogIsEmpty"
underlyingDB, err := c.srv.Database.DB()
underlyingDB, err := c.srv.Database.SqlDB(ctx)
if err != nil {
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 {
c.ShutdownFuncs = append(c.ShutdownFuncs, c.DestroyDevDatabase)
c.ShutdownFuncs = append(c.ShutdownFuncs, func() error { return c.DestroyDevDatabase(ctx) })
}
default:
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
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())
return base.CommandCliError
}
underlyingDB, err := c.Database.DB()
underlyingDB, err := c.Database.SqlDB(ctx)
if err != nil {
c.UI.Error(fmt.Errorf("Can't get db: %w.", err).Error())
return base.CommandCliError
+2 -3
View File
@@ -21,7 +21,6 @@ import (
vault "github.com/hashicorp/vault/api"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gorm.io/gorm"
)
const testUpdateTokenStatusExpirationQuery = `
@@ -33,7 +32,7 @@ update credential_vault_token
`
func testVaultToken(t *testing.T,
conn *gorm.DB,
conn *db.DB,
wrapper wrapping.Wrapper,
v *TestVaultServer,
cs *CredentialStore,
@@ -87,7 +86,7 @@ func testVaultToken(t *testing.T,
}
func testVaultCred(t *testing.T,
conn *gorm.DB,
conn *db.DB,
v *TestVaultServer,
cl *CredentialLibrary,
sess *session.Session,
@@ -795,7 +795,7 @@ func TestRepository_UpdateCredentialLibrary(t *testing.T) {
assert.Equal(tt.wantCount, gotCount, "row count")
assert.NotSame(tt.orig, got)
assert.Equal(tt.orig.StoreId, got.StoreId)
underlyingDB, err := conn.DB()
underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err)
dbassert := dbassert.New(t, underlyingDB)
if tt.want.Name == "" {
@@ -23,7 +23,6 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/testing/protocmp"
"gorm.io/gorm"
)
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.NotSame(tt.orig, got)
assert.Equal(tt.orig.ScopeId, got.ScopeId)
underlyingDB, err := conn.DB()
underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err)
dbassert := dbassert.New(t, underlyingDB)
if tt.want.Name == "" {
@@ -887,7 +886,7 @@ func TestRepository_UpdateCredentialStore_Attributes(t *testing.T) {
assert.Equal(1, gotCount2, "count of updated records")
require.NotNil(got2)
assert.Nil(got2.CaCert)
underlyingDB, err := conn.DB()
underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err)
dbassert := dbassert.New(t, underlyingDB)
dbassert.IsNull(got2, "CaCert")
@@ -1270,9 +1269,9 @@ func TestRepository_DeleteCredentialStore(t *testing.T) {
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)
kms := kms.TestKms(t, conn, wrapper)
sche := scheduler.TestScheduler(t, conn, wrapper)
@@ -1286,7 +1285,7 @@ func TestRepository_DeleteCredentialStore(t *testing.T) {
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 {
tokens = make(tokenMap)
}
@@ -1299,13 +1298,13 @@ func TestRepository_DeleteCredentialStore(t *testing.T) {
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)
tokens[storeId].maintaining = count
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)
const query = `
update credential_vault_token
@@ -1327,7 +1326,7 @@ update credential_vault_token
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)
const query = `
update credential_vault_token
@@ -1349,7 +1348,7 @@ update credential_vault_token
return tokens
}
assertTokens := func(t *testing.T, conn *gorm.DB, want tokenMap) {
assertTokens := func(t *testing.T, conn *db.DB, want tokenMap) {
const query = `
select store_id, status, count(token_hmac)
from credential_vault_token
@@ -1399,7 +1398,7 @@ group by store_id, status;
}{
{
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)
css, tokens := testStores(t, conn, wrapper, nil, scopeId, 1)
cs := css[0]
@@ -1409,7 +1408,7 @@ group by store_id, status;
},
{
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)
css, tokens := testStores(t, conn, wrapper, nil, scopeId, 1)
cs := css[0]
@@ -1421,7 +1420,7 @@ group by store_id, status;
},
{
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)
css, tokens := testStores(t, conn, wrapper, nil, scopeId, 1)
cs := css[0]
@@ -1434,7 +1433,7 @@ group by store_id, status;
},
{
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)
css, tokens := testStores(t, conn, wrapper, nil, scopeId, 1)
cs := css[0]
@@ -1447,7 +1446,7 @@ group by store_id, status;
},
{
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)
css, tokens := testStores(t, conn, wrapper, nil, scopeId, 1)
cs := css[0]
@@ -1460,7 +1459,7 @@ group by store_id, status;
},
{
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)
css, tokens := testStores(t, conn, wrapper, nil, scopeId, 1)
cs := css[0]
+4 -3
View File
@@ -5,7 +5,6 @@ package vault
import (
"crypto/tls"
"database/sql"
"fmt"
"io/ioutil"
"net/http"
@@ -16,8 +15,10 @@ import (
"testing"
"time"
"github.com/hashicorp/boundary/internal/db/common"
"github.com/hashicorp/go-rootcerts"
vault "github.com/hashicorp/vault/api"
_ "github.com/jackc/pgx/v4/stdlib"
"github.com/ory/dockertest/v3"
"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")
err = pool.Retry(func() error {
var err error
db, err := sql.Open("postgres", dburl)
db, err := common.SqlOpen("postgres", dburl)
if err != nil {
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`
)
db, err := sql.Open("postgres", dburl)
db, err := common.SqlOpen("postgres", dburl)
require.NoError(err)
defer db.Close()
+8 -9
View File
@@ -7,7 +7,6 @@ import (
"crypto/rand"
"crypto/x509"
"crypto/x509/pkix"
"database/sql"
"encoding/pem"
"fmt"
"math/big"
@@ -19,6 +18,7 @@ import (
"testing"
"time"
"github.com/hashicorp/boundary/internal/db/common"
"github.com/hashicorp/boundary/internal/errors"
"github.com/hashicorp/boundary/internal/db"
@@ -28,14 +28,13 @@ import (
vault "github.com/hashicorp/vault/api"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gorm.io/gorm"
)
// TestCredentialStore creates a vault credential store in the provided DB with
// the provided scope, vault address, token, and accessor and any values passed
// in through the Options vargs. If any errors are encountered during the
// 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()
ctx := context.Background()
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
// encountered during the creation of the credential stores, the test will
// 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()
ctx := context.Background()
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
// are encountered during the creation of the credential libraries, the
// 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()
assert, require := assert.New(t), require.New(t)
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
// the provided library id and session id. If any errors are encountered
// 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()
assert, require := assert.New(t), require.New(t)
rw := db.New(conn)
@@ -189,7 +188,7 @@ func TestCredentials(t *testing.T, conn *gorm.DB, wrapper wrapping.Wrapper, libr
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()
w := db.New(conn)
ctx := context.Background()
@@ -211,7 +210,7 @@ func createTestToken(t *testing.T, conn *gorm.DB, wrapper wrapping.Wrapper, scop
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()
assert, require := assert.New(t), require.New(t)
w := db.New(conn)
@@ -871,7 +870,7 @@ func (d *TestDatabase) ValidateCredential(t *testing.T, s *vault.Secret) error {
require := require.New(t)
require.NotNil(s)
dburl := d.URL.Encode(t, s)
db, err := sql.Open("postgres", dburl)
db, err := common.SqlOpen("postgres", dburl)
if err != nil {
return err
}
+7 -5
View File
@@ -1,6 +1,7 @@
package dbassert
import (
"context"
"testing"
"github.com/hashicorp/boundary/internal/db"
@@ -10,7 +11,6 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gorm.io/gorm"
)
func Test_FieldDomain(t *testing.T) {
@@ -59,11 +59,12 @@ func Test_FieldNullable(t *testing.T) {
func Test_FieldIsNull(t *testing.T) {
t.Parallel()
ctx := context.Background()
assert := assert.New(t)
conn, _ := db.TestSetup(t, "postgres")
initStore(t, conn)
require := require.New(t)
underlyingDB, err := conn.DB()
underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err)
assert.NoError(err)
mockery := new(dbassert.MockTesting)
@@ -82,10 +83,11 @@ func Test_FieldIsNull(t *testing.T) {
func Test_FieldNotNull(t *testing.T) {
t.Parallel()
ctx := context.Background()
conn, _ := db.TestSetup(t, "postgres")
initStore(t, conn)
require := require.New(t)
underlyingDB, err := conn.DB()
underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err)
mockery := new(dbassert.MockTesting)
dbassert := New(mockery, underlyingDB)
@@ -113,7 +115,7 @@ type testModel struct {
func (*testModel) TableName() string { return "test_table_dbasserts" }
// 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)
assert.NoError(t, err)
m := testModel{
@@ -126,7 +128,7 @@ func createTestModel(t dbassert.TestingT, db *gorm.DB, nullable *string, typeInt
return &m
}
func initStore(t *testing.T, db *gorm.DB) {
func initStore(t *testing.T, db *db.DB) {
t.Helper()
const (
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 (
"context"
"database/sql"
stderrors "errors"
"fmt"
"github.com/hashicorp/boundary/internal/errors"
"github.com/hashicorp/boundary/internal/observability/event"
"github.com/hashicorp/go-hclog"
"github.com/jackc/pgconn"
_ "github.com/jackc/pgx/v4"
"gorm.io/driver/postgres"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
type DbType int
@@ -34,9 +38,44 @@ func StringToDbType(dialect string) (DbType, error) {
}
}
// Open a database connection which is long-lived.
// You need to call Close() on the returned gorm.DB
func Open(dbType DbType, connectionUrl string) (*gorm.DB, error) {
// DB is a wrapper around the ORM
type DB struct {
*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
switch dbType {
case Postgres:
@@ -52,7 +91,28 @@ func Open(dbType DbType, connectionUrl string) (*gorm.DB, error) {
if err != nil {
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{}) {
@@ -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}
}
+3 -1
View File
@@ -1,6 +1,7 @@
package db
import (
"context"
"testing"
"github.com/hashicorp/boundary/testing/dbtest"
@@ -8,6 +9,7 @@ import (
)
func TestOpen(t *testing.T) {
ctx := context.Background()
cleanup, url, _, err := dbtest.StartUsingTemplate(dbtest.Postgres)
if err != nil {
t.Fatal(err)
@@ -48,7 +50,7 @@ func TestOpen(t *testing.T) {
got, err := Open(tt.args.dbType, tt.args.connectionUrl)
defer func() {
if err == nil {
sqlDB, err := got.DB()
sqlDB, err := got.SqlDB(ctx)
require.NoError(t, err)
err = sqlDB.Close()
require.NoError(t, err)
+36 -31
View File
@@ -1,6 +1,7 @@
package db
import (
"context"
"strings"
"testing"
"time"
@@ -25,8 +26,10 @@ returning id;
`
)
ctx := context.Background()
conn, _ := TestSetup(t, "postgres")
db, err := conn.DB()
db, err := conn.SqlDB(ctx)
require.NoError(t, err)
for _, typ := range []string{"public", "private", "role", "scope"} {
@@ -107,9 +110,9 @@ insert into test_table
values ($1);
`
)
ctx := context.Background()
conn, _ := TestSetup(t, "postgres")
db, err := conn.DB()
db, err := conn.SqlDB(ctx)
require.NoError(t, err)
if _, err := db.Exec(createTable); err != nil {
@@ -179,9 +182,9 @@ insert into test_table
values ($1);
`
)
ctx := context.Background()
conn, _ := TestSetup(t, "postgres")
db, err := conn.DB()
db, err := conn.SqlDB(ctx)
require.NoError(t, err)
if _, err := db.Exec(createTable); err != nil {
@@ -256,8 +259,9 @@ returning id;
`
)
ctx := context.Background()
conn, _ := TestSetup(t, "postgres")
db, err := conn.DB()
db, err := conn.SqlDB(ctx)
require.NoError(t, err)
if _, err := db.Exec(createTable); err != nil {
t.Fatalf("query: \n%s\n error: %s", createTable, err)
@@ -322,9 +326,9 @@ update test_update_time_column
set update_time = null;
`
)
ctx := context.Background()
conn, _ := TestSetup(t, "postgres")
db, err := conn.DB()
db, err := conn.SqlDB(ctx)
require.NoError(t, err)
_, err = db.Exec(createTable)
assert.NoError(err)
@@ -396,8 +400,8 @@ returning public_id;
)
conn, _ := TestSetup(t, "postgres")
assert, require := assert.New(t), require.New(t)
db, err := conn.DB()
ctx := context.Background()
db, err := conn.SqlDB(ctx)
require.NoError(err)
_, err = db.Exec(createTable)
@@ -457,8 +461,8 @@ returning private_id;
)
conn, _ := TestSetup(t, "postgres")
assert, require := assert.New(t), require.New(t)
db, err := conn.DB()
ctx := context.Background()
db, err := conn.SqlDB(ctx)
require.NoError(err)
_, err = db.Exec(createTable)
@@ -491,8 +495,9 @@ returning private_id;
}
func TestDomain_DefaultUsersExist(t *testing.T) {
ctx := context.Background()
conn, _ := TestSetup(t, "postgres")
db, err := conn.DB()
db, err := conn.SqlDB(ctx)
require.NoError(t, err)
for _, val := range []string{"u_anon", "u_auth"} {
rows, err := db.Query(`select from iam_user where public_id = $1`, val)
@@ -579,9 +584,9 @@ set id = null;
Name string
Updatable string
}
ctx := context.Background()
conn, _ := TestSetup(t, "postgres")
db, err := conn.DB()
db, err := conn.SqlDB(ctx)
require.NoError(t, err)
_, err = db.Exec(createTable)
assert.NoError(t, err)
@@ -693,9 +698,9 @@ values ($1)
returning id;
`
)
ctx := context.Background()
conn, _ := TestSetup(t, "postgres")
db, err := conn.DB()
db, err := conn.SqlDB(ctx)
require.NoError(t, err)
if _, err := db.Exec(createTable); err != nil {
@@ -741,9 +746,9 @@ values ($1)
returning id;
`
)
ctx := context.Background()
conn, _ := TestSetup(t, "postgres")
db, err := conn.DB()
db, err := conn.SqlDB(ctx)
require.NoError(t, err)
if _, err := db.Exec(createTable); err != nil {
@@ -788,9 +793,9 @@ values ($1)
returning id;
`
)
ctx := context.Background()
conn, _ := TestSetup(t, "postgres")
db, err := conn.DB()
db, err := conn.SqlDB(ctx)
require.NoError(t, err)
if _, err := db.Exec(createTable); err != nil {
@@ -835,9 +840,9 @@ values ($1)
returning id;
`
)
ctx := context.Background()
conn, _ := TestSetup(t, "postgres")
db, err := conn.DB()
db, err := conn.SqlDB(ctx)
require.NoError(t, err)
if _, err := db.Exec(createTable); err != nil {
@@ -882,9 +887,9 @@ values ($1)
returning id;
`
)
ctx := context.Background()
conn, _ := TestSetup(t, "postgres")
db, err := conn.DB()
db, err := conn.SqlDB(ctx)
require.NoError(t, err)
if _, err := db.Exec(createTable); err != nil {
@@ -929,9 +934,9 @@ values ($1)
returning id;
`
)
ctx := context.Background()
conn, _ := TestSetup(t, "postgres")
db, err := conn.DB()
db, err := conn.SqlDB(ctx)
require.NoError(t, err)
if _, err := db.Exec(createTable); err != nil {
@@ -980,9 +985,9 @@ func TestDomain_wt_is_sentinel(t *testing.T) {
select wt_is_sentinel($1);
`
)
ctx := context.Background()
conn, _ := TestSetup(t, "postgres")
db, err := conn.DB()
db, err := conn.SqlDB(ctx)
require.NoError(t, err)
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`
)
ctx := context.Background()
conn, _ := TestSetup(t, "postgres")
db, err := conn.DB()
db, err := conn.SqlDB(ctx)
assert.NoError(t, err)
_, err = db.Exec(createTable)
+20
View File
@@ -2,6 +2,7 @@ package db
import (
"github.com/hashicorp/boundary/internal/oplog"
"github.com/hashicorp/go-hclog"
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 []string
withGormFormatter hclog.Logger
withMaxOpenConnections int
}
type oplogOpts struct {
@@ -165,3 +169,19 @@ func WithPrngValues(withPrngValues []string) Option {
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"
"github.com/hashicorp/boundary/internal/oplog"
"github.com/hashicorp/go-hclog"
"github.com/stretchr/testify/assert"
)
@@ -175,4 +176,30 @@ func Test_getOpts(t *testing.T) {
testOpts.withOrder = "version desc"
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
type Db struct {
underlying *gorm.DB
underlying *DB
}
// ensure that Db implements the interfaces of: Reader and Writer
@@ -199,7 +199,7 @@ var (
_ Writer = (*Db)(nil)
)
func New(underlying *gorm.DB) *Db {
func New(underlying *DB) *Db {
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"))
}
}
db := rw.underlying
db := rw.underlying.DB
if opts.withWhereClause != "" {
db = db.Where(opts.withWhereClause, opts.withWhereClauseArgs...)
}
@@ -713,7 +713,7 @@ func (rw *Db) getTicketFor(aggregateName string) (*store.Ticket, error) {
if rw.underlying == nil {
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 {
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 {
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 {
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(
ctx,
&oplog.GormWriter{Tx: rw.underlying},
&oplog.GormWriter{Tx: rw.underlying.DB},
ticket,
oplogMsgs...,
); err != nil {
@@ -827,7 +827,7 @@ func (rw *Db) addOplog(ctx context.Context, opType OpType, opts Options, ticket
if ticket == nil {
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 {
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(
ctx,
&oplog.GormWriter{Tx: rw.underlying},
&oplog.GormWriter{Tx: rw.underlying.DB},
ticket,
msg,
)
@@ -876,7 +876,7 @@ func (rw *Db) WriteOplogEntryWith(ctx context.Context, wrapper wrapping.Wrapper,
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 {
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(
ctx,
&oplog.GormWriter{Tx: rw.underlying},
&oplog.GormWriter{Tx: rw.underlying.DB},
ticket,
msgs...,
)
@@ -947,7 +947,7 @@ func (w *Db) DoTx(ctx context.Context, retries uint, backOff Backoff, Handler Tx
newTx := w.underlying.WithContext(ctx)
newTx = newTx.Begin()
rw := &Db{newTx}
rw := &Db{underlying: &DB{newTx}}
if err := Handler(rw, rw); err != nil {
if err := newTx.Rollback().Error; err != nil {
return info, errors.Wrap(ctx, err, op, errors.WithoutEvent())
+10 -11
View File
@@ -22,7 +22,6 @@ import (
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/timestamppb"
"gorm.io/gorm"
)
func TestDb_UpdateUnsetField(t *testing.T) {
@@ -1270,7 +1269,7 @@ func TestDb_Delete(t *testing.T) {
}
tests := []struct {
name string
underlying *gorm.DB
underlying *DB
wrapper wrapping.Wrapper
args args
want int
@@ -1540,7 +1539,7 @@ func TestDb_CreateItems(t *testing.T) {
}
tests := []struct {
name string
underlying *gorm.DB
underlying *DB
args args
wantOplogId string
wantOplogMsgs bool
@@ -1741,7 +1740,7 @@ func TestDb_DeleteItems(t *testing.T) {
}
tests := []struct {
name string
underlying *gorm.DB
underlying *DB
args args
wantRowsDeleted int
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()
require := require.New(t)
@@ -1935,7 +1934,7 @@ func testUser(t *testing.T, conn *gorm.DB, name, email, phoneNumber string) *db_
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()
require := require.New(t)
@@ -1964,7 +1963,7 @@ func testId(t *testing.T) string {
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()
require := require.New(t)
@@ -1995,7 +1994,7 @@ func TestDb_LookupById(t *testing.T) {
}
tests := []struct {
name string
underlying *gorm.DB
underlying *DB
args args
wantErr bool
want proto.Message
@@ -2095,7 +2094,7 @@ func TestDb_GetTicket(t *testing.T) {
type notReplayable struct{}
tests := []struct {
name string
underlying *gorm.DB
underlying *DB
aggregateType interface{}
wantErr bool
wantErrIs errors.Code
@@ -2181,7 +2180,7 @@ func TestDb_WriteOplogEntryWith(t *testing.T) {
}
tests := []struct {
name string
underlying *gorm.DB
underlying *DB
args args
wantErr bool
wantErrIs errors.Code
@@ -2889,7 +2888,7 @@ func TestDb_lookupAfterWrite(t *testing.T) {
}
tests := []struct {
name string
underlying *gorm.DB
underlying *DB
args args
wantErr bool
want proto.Message
+12 -11
View File
@@ -7,6 +7,7 @@ import (
"strings"
"testing"
"github.com/hashicorp/boundary/internal/db/common"
"github.com/hashicorp/boundary/internal/db/schema/postgres"
"github.com/hashicorp/boundary/internal/errors"
"github.com/hashicorp/boundary/testing/dbtest"
@@ -22,7 +23,7 @@ func TestNewManager(t *testing.T) {
t.Cleanup(func() {
require.NoError(t, c())
})
d, err := sql.Open(dialect, u)
d, err := common.SqlOpen(dialect, u)
require.NoError(t, err)
ctx := context.Background()
@@ -47,7 +48,7 @@ func TestCurrentState(t *testing.T) {
})
require.NoError(t, err)
ctx := context.Background()
d, err := sql.Open(dialect, u)
d, err := common.SqlOpen(dialect, u)
require.NoError(t, err)
m, err := NewManager(ctx, dialect, d)
@@ -83,7 +84,7 @@ func TestRollForward(t *testing.T) {
t.Cleanup(func() {
require.NoError(t, c())
})
d, err := sql.Open(dialect, u)
d, err := common.SqlOpen(dialect, u)
require.NoError(t, err)
ctx := context.Background()
@@ -112,7 +113,7 @@ func TestRollForward_NotFromFresh(t *testing.T) {
t.Cleanup(func() {
require.NoError(t, c())
})
d, err := sql.Open(dialect, u)
d, err := common.SqlOpen(dialect, u)
require.NoError(t, err)
// 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() {
require.NoError(t, c())
})
d, err := sql.Open(dialect, u)
d, err := common.SqlOpen(dialect, u)
require.NoError(t, err)
ctx := context.Background()
@@ -174,7 +175,7 @@ func TestRollForward_BadSQL(t *testing.T) {
t.Cleanup(func() {
require.NoError(t, c())
})
d, err := sql.Open(dialect, u)
d, err := common.SqlOpen(dialect, u)
require.NoError(t, err)
// 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() {
require.NoError(t, c())
})
d1, err := sql.Open(dialect, u)
d1, err := common.SqlOpen(dialect, u)
require.NoError(t, err)
m1, err := NewManager(ctx, dialect, d1)
require.NoError(t, err)
d2, err := sql.Open(dialect, u)
d2, err := common.SqlOpen(dialect, u)
require.NoError(t, err)
m2, err := NewManager(ctx, dialect, d2)
require.NoError(t, err)
@@ -223,12 +224,12 @@ func TestManager_SharedLock(t *testing.T) {
t.Cleanup(func() {
require.NoError(t, c())
})
d1, err := sql.Open("postgres", u)
d1, err := common.SqlOpen("postgres", u)
require.NoError(t, err)
m1, err := NewManager(ctx, "postgres", d1)
require.NoError(t, err)
d2, err := sql.Open("postgres", u)
d2, err := common.SqlOpen("postgres", u)
require.NoError(t, err)
m2, err := NewManager(ctx, "postgres", d2)
require.NoError(t, err)
@@ -252,7 +253,7 @@ func Test_GetMigrationLog(t *testing.T) {
t.Cleanup(func() {
require.NoError(t, c())
})
d, err := sql.Open("postgres", u)
d, err := common.SqlOpen("postgres", u)
require.NoError(t, err)
m, err := NewManager(ctx, "postgres", d)
require.NoError(t, err)
@@ -6,6 +6,7 @@ import (
"testing"
"time"
"github.com/hashicorp/boundary/internal/db/common"
"github.com/hashicorp/boundary/internal/db/schema"
"github.com/hashicorp/boundary/testing/dbtest"
"github.com/stretchr/testify/require"
@@ -14,8 +15,8 @@ import (
const (
insertServerQuery = "insert into server (private_id, type, address) values ($1, $2, $3)"
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"`
expectServerConstraintErr = `pq: insert or update on table "server" violates foreign key constraint "server_type_enm_fkey"`
expectEnumConstraintErr = `ERROR: new row for relation "server_type_enm" violates check constraint "only_predefined_server_types_allowed" (SQLSTATE 23514)`
expectServerConstraintErr = `ERROR: insert or update on table "server" violates foreign key constraint "server_type_enm_fkey" (SQLSTATE 23503)`
)
type testServer struct {
@@ -48,7 +49,7 @@ func Test_ServerEnumChanges(t *testing.T) {
t.Cleanup(func() {
require.NoError(c())
})
d, err := sql.Open(dialect, u)
d, err := common.SqlOpen(dialect, u)
require.NoError(err)
// migration to the prior migration (before the one we want to test)
@@ -6,6 +6,7 @@ import (
"testing"
"time"
"github.com/hashicorp/boundary/internal/db/common"
"github.com/hashicorp/boundary/internal/db/schema"
"github.com/hashicorp/boundary/testing/dbtest"
"github.com/stretchr/testify/require"
@@ -41,7 +42,7 @@ func testSetupDb(ctx context.Context, t *testing.T) *sql.DB {
t.Cleanup(func() {
require.NoError(c())
})
d, err := sql.Open(dialect, u)
d, err := common.SqlOpen(dialect, u)
require.NoError(err)
oState := schema.TestCloneMigrationStates(t)
@@ -2,12 +2,12 @@ package migration
import (
"context"
"database/sql"
"testing"
"github.com/hashicorp/boundary/internal/auth/oidc"
"github.com/hashicorp/boundary/internal/authtoken"
"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/host/static"
"github.com/hashicorp/boundary/internal/iam"
@@ -18,7 +18,6 @@ import (
wrapping "github.com/hashicorp/go-kms-wrapping"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gorm.io/gorm"
)
func TestMigrations_UserDimension(t *testing.T) {
@@ -37,7 +36,7 @@ func TestMigrations_UserDimension(t *testing.T) {
t.Cleanup(func() {
require.NoError(c())
})
d, err := sql.Open(dialect, u)
d, err := common.SqlOpen(dialect, u)
require.NoError(err)
// 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)
}
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()
authMethod := oidc.TestAuthMethod(
@@ -20,7 +20,6 @@ import (
wrapping "github.com/hashicorp/go-kms-wrapping"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gorm.io/gorm"
)
func TestMigrations_CredentialDimension(t *testing.T) {
@@ -144,7 +143,7 @@ func TestMigrations_CredentialDimension(t *testing.T) {
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()
authMethod := oidc.TestAuthMethod(
@@ -171,7 +170,7 @@ func testOidcAuthToken(t *testing.T, conn *gorm.DB, kms *kms.Kms, wrapper wrappi
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()
rw := db.New(conn)
@@ -2,11 +2,11 @@ package migration
import (
"context"
"database/sql"
"testing"
"github.com/hashicorp/boundary/internal/auth/password"
"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/iam"
"github.com/hashicorp/boundary/testing/dbtest"
@@ -38,7 +38,7 @@ func Test_PrimaryAuthMethodChanges(t *testing.T) {
t.Cleanup(func() {
require.NoError(c())
})
d, err := sql.Open(dialect, u)
d, err := common.SqlOpen(dialect, u)
require.NoError(err)
// migration to the prior migration (before the one we want to test)
@@ -1,6 +1,7 @@
package migration
import (
"context"
"database/sql"
"testing"
@@ -37,9 +38,9 @@ func TestMigration(t *testing.T) {
`
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"))
db, err := conn.DB()
db, err := conn.SqlDB(ctx)
require.NoError(err)
_, err = db.Exec(createTables)
require.NoError(err)
+14 -13
View File
@@ -34,12 +34,11 @@ import (
"fmt"
"io"
"io/ioutil"
"strconv"
"strings"
"github.com/hashicorp/boundary/internal/errors"
"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
@@ -232,14 +231,12 @@ func (p *Postgres) Run(ctx context.Context, migration io.Reader, version int) er
if rollbackErr := rollback(); rollbackErr != nil {
err = multierror.Append(err, rollbackErr)
}
if pgErr, ok := err.(*pq.Error); ok {
if pgErr, ok := err.(*pgconn.PgError); ok {
var line uint
var col uint
var lineColOK bool
if pgErr.Position != "" {
if pos, err := strconv.ParseUint(pgErr.Position, 10, 64); err == nil {
line, col, lineColOK = computeLineFromPos(query, int(pos))
}
if pgErr.Position != 0 {
line, col, lineColOK = computeLineFromPos(query, int(pgErr.Position))
}
message := "migration failed"
if lineColOK {
@@ -308,8 +305,7 @@ func (p *Postgres) setVersion(ctx context.Context, version int, dirty bool) erro
defer func() { p.tx = nil }()
return tx.Rollback()
}
query := `truncate ` + pq.QuoteIdentifier(defaultMigrationsTable)
query := `truncate ` + quoteIdentifier(defaultMigrationsTable)
if _, err := tx.ExecContext(ctx, query); err != nil {
if errRollback := rollback(); errRollback != nil {
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
// See: https://github.com/golang-migrate/migrate/issues/330
if version >= 0 || (version == nilVersion && dirty) {
query = `insert into ` + pq.QuoteIdentifier(defaultMigrationsTable) +
query = `insert into ` + quoteIdentifier(defaultMigrationsTable) +
` (version, dirty) values ($1, $2)`
if _, err := tx.ExecContext(ctx, query, version, dirty); err != 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")
}
query := `select version, dirty from ` + pq.QuoteIdentifier(tableName)
query := `select version, dirty from ` + quoteIdentifier(tableName)
results, err := p.conn.QueryContext(ctx, query)
if err != nil {
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 {
// delete one by one ...
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 {
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)
}
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 wpErr := rollback(); wpErr != nil {
err = multierror.Append(err, wpErr)
@@ -474,3 +470,8 @@ func (p *Postgres) EnsureVersionTable(ctx context.Context) (err error) {
return nil
}
func quoteIdentifier(input string) (output string) {
output = `"` + strings.Replace(input, `"`, `""`, -1) + `"`
return
}
+1 -1
View File
@@ -28,7 +28,7 @@
package postgres
// error codes https://github.com/lib/pq/blob/master/error.go
// errors: https://pkg.go.dev/github.com/jackc/pgconn#PgError
import (
"bytes"
+2 -2
View File
@@ -31,11 +31,11 @@ package postgres
import (
"bytes"
"context"
"database/sql"
"testing"
"time"
"github.com/golang-migrate/migrate/v4/database"
"github.com/hashicorp/boundary/internal/db/common"
"github.com/stretchr/testify/assert"
"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) {
t.Helper()
db, err := sql.Open("postgres", u)
db, err := common.SqlOpen("postgres", u)
require.NoError(t, err)
px, err := New(ctx, db)
+2 -2
View File
@@ -2,8 +2,8 @@ package schema
import (
"context"
"database/sql"
"github.com/hashicorp/boundary/internal/db/common"
"github.com/hashicorp/boundary/internal/errors"
)
@@ -13,7 +13,7 @@ import (
func MigrateStore(ctx context.Context, dialect string, url string, opt ...Option) (bool, error) {
const op = "schema.MigrateStore"
d, err := sql.Open(dialect, url)
d, err := common.SqlOpen(dialect, url)
if err != nil {
return false, errors.Wrap(ctx, err, op)
}
+2 -2
View File
@@ -2,9 +2,9 @@ package schema
import (
"context"
"database/sql"
"testing"
"github.com/hashicorp/boundary/internal/db/common"
"github.com/hashicorp/boundary/testing/dbtest"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -53,7 +53,7 @@ func Test_MigrateStore_WithMigrationStates(t *testing.T) {
t.Cleanup(func() {
require.NoError(c())
})
d, err := sql.Open(dialect, u)
d, err := common.SqlOpen(dialect, u)
require.NoError(err)
// 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"
"github.com/hashicorp/go-kms-wrapping/wrappers/aead"
"github.com/stretchr/testify/assert"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
// 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 url string
var err error
@@ -57,7 +56,7 @@ func TestSetup(t *testing.T, dialect string, opt ...TestOption) (*gorm.DB, strin
}
db.Logger.LogMode(logger.Error)
t.Cleanup(func() {
sqlDB, err := db.DB()
sqlDB, err := db.SqlDB(ctx)
assert.NoError(t, err)
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,
},
{
name: "wrapped-pq-is-unique",
name: "wrapped-pg-is-unique",
in: errors.E(
context.TODO(),
errors.WithWrap(&pgconn.PgError{
@@ -107,7 +107,7 @@ func TestError_IsCheckConstraint(t *testing.T) {
want: true,
},
{
name: "wrapped-pq-is-check-constraint",
name: "wrapped-pg-is-check-constraint",
in: errors.E(context.TODO(), errors.WithCode(errors.CheckConstraint),
errors.WithWrap(&pgconn.PgError{
Code: "23514",
@@ -176,7 +176,7 @@ func TestError_IsNotNullError(t *testing.T) {
want: true,
},
{
name: "wrapped-pq-is-not-null",
name: "wrapped-pg-is-not-null",
in: errors.E(context.TODO(), errors.WithCode(errors.NotNull),
errors.WithWrap(&pgconn.PgError{
Code: "23502",
+1 -2
View File
@@ -6,7 +6,6 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gorm.io/gorm"
"github.com/hashicorp/boundary/internal/db"
"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()
cats := TestCatalogs(t, conn, scopeId, 1)
return cats[0]
@@ -179,6 +179,7 @@ func TestRepository_UpdateCatalog(t *testing.T) {
conn, _ := db.TestSetup(t, "postgres")
rw := db.New(conn)
wrapper := db.TestWrapper(t)
ctx := context.Background()
changeName := func(s string) func(*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.NotSame(tt.orig, got)
assert.Equal(tt.orig.ScopeId, got.ScopeId)
underlyingDB, err := conn.DB()
underlyingDB, err := conn.SqlDB(ctx)
require.NoError(t, err)
dbassert := dbassert.New(t, underlyingDB)
if tt.want.Name == "" {
@@ -202,6 +202,7 @@ func TestRepository_CreateSet(t *testing.T) {
}
func TestRepository_UpdateSet(t *testing.T) {
ctx := context.Background()
conn, _ := db.TestSetup(t, "postgres")
rw := db.New(conn)
wrapper := db.TestWrapper(t)
@@ -493,7 +494,7 @@ func TestRepository_UpdateSet(t *testing.T) {
assert.Equal(tt.wantCount, gotCount, "row count")
assert.NotSame(tt.orig, got)
assert.Equal(tt.orig.CatalogId, got.CatalogId)
underlyingDB, err := conn.DB()
underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err)
dbassert := dbassert.New(t, underlyingDB)
if tt.want.Name == "" {
+2 -1
View File
@@ -251,6 +251,7 @@ func TestRepository_CreateHost(t *testing.T) {
}
func TestRepository_UpdateHost(t *testing.T) {
ctx := context.Background()
conn, _ := db.TestSetup(t, "postgres")
rw := db.New(conn)
wrapper := db.TestWrapper(t)
@@ -620,7 +621,7 @@ func TestRepository_UpdateHost(t *testing.T) {
assert.Equal(tt.wantCount, gotCount, "row count")
assert.NotSame(tt.orig, got)
assert.Equal(tt.orig.CatalogId, got.CatalogId)
underlyingDB, err := conn.DB()
underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err)
dbassert := dbassert.New(t, underlyingDB)
if tt.want.Name == "" {
+4 -5
View File
@@ -7,13 +7,12 @@ import (
"github.com/hashicorp/boundary/internal/db"
"github.com/stretchr/testify/assert"
"gorm.io/gorm"
)
// 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
// 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()
assert := assert.New(t)
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
// 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.
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()
assert := assert.New(t)
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
// with the provided catalog id. The catalog must have been created
// 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()
assert := assert.New(t)
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.
// The set and hosts must have been created previously and belong to the
// 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()
assert := assert.New(t)
+2 -1
View File
@@ -65,6 +65,7 @@ func TestAccount_GetScope(t *testing.T) {
func TestAccount_Clone(t *testing.T) {
t.Parallel()
ctx := context.Background()
conn, _ := db.TestSetup(t, "postgres")
wrapper := db.TestWrapper(t)
repo := TestRepo(t, conn, wrapper)
@@ -83,7 +84,7 @@ func TestAccount_Clone(t *testing.T) {
authMethodPublicId := testAuthMethod(t, conn, org.PublicId)
acct := testAccount(t, conn, org.PublicId, authMethodPublicId, u.PublicId)
acct2 := testAccount(t, conn, org.PublicId, authMethodPublicId, "")
underlyingDB, err := conn.DB()
underlyingDB, err := conn.SqlDB(ctx)
require.NoError(t, err)
dbassert := dbassert.New(t, underlyingDB)
dbassert.IsNull(acct2, "IamUserId")
+2 -1
View File
@@ -206,6 +206,7 @@ func Test_GroupCreate(t *testing.T) {
func Test_GroupUpdate(t *testing.T) {
t.Parallel()
ctx := context.Background()
conn, _ := db.TestSetup(t, "postgres")
wrapper := db.TestWrapper(t)
repo := TestRepo(t, conn, wrapper)
@@ -351,7 +352,7 @@ func Test_GroupUpdate(t *testing.T) {
require.NoError(err)
assert.True(proto.Equal(updateGrp, foundGrp))
if len(tt.args.nullPaths) != 0 {
underlyingDB, err := conn.DB()
underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err)
dbassert := dbassert.New(t, underlyingDB)
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;`
)
t.Parallel()
ctx := context.Background()
conn, _ := db.TestSetup(t, "postgres")
wrapper := db.TestWrapper(t)
repo := TestRepo(t, conn, wrapper)
db, err := conn.DB()
db, err := conn.SqlDB(ctx)
require.NoError(t, err)
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) {
t.Parallel()
ctx := context.Background()
conn, _ := db.TestSetup(t, "postgres")
a := assert.New(t)
rw := db.New(conn)
@@ -450,7 +451,7 @@ func TestRepository_UpdateGroup(t *testing.T) {
foundGrp, _, err := repo.LookupGroup(context.Background(), u.PublicId)
require.NoError(err)
assert.True(proto.Equal(groupAfterUpdate, foundGrp))
underlyingDB, err := conn.DB()
underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err)
dbassert := dbassert.New(t, underlyingDB)
if tt.args.name == "" {
+2 -1
View File
@@ -174,6 +174,7 @@ func TestRepository_CreateRole(t *testing.T) {
func TestRepository_UpdateRole(t *testing.T) {
t.Parallel()
ctx := context.Background()
conn, _ := db.TestSetup(t, "postgres")
rw := db.New(conn)
wrapper := db.TestWrapper(t)
@@ -447,7 +448,7 @@ func TestRepository_UpdateRole(t *testing.T) {
foundRole, _, _, err := repo.LookupRole(context.Background(), r.PublicId)
assert.NoError(err)
assert.True(proto.Equal(roleAfterUpdate, foundRole))
underlyingDB, err := conn.DB()
underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err)
dbassert := dbassert.New(t, underlyingDB)
if tt.args.name == "" {
+2 -1
View File
@@ -184,6 +184,7 @@ func TestRepository_associateUserWithAccounts(t *testing.T) {
func TestRepository_dissociateUserWithAccount(t *testing.T) {
t.Parallel()
ctx := context.Background()
conn, _ := db.TestSetup(t, "postgres")
rw := db.New(conn)
wrapper := db.TestWrapper(t)
@@ -309,7 +310,7 @@ func TestRepository_dissociateUserWithAccount(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
underlyingDB, err := conn.DB()
underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err)
dbassert := dbassert.New(t, underlyingDB)
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) {
t.Parallel()
ctx := context.Background()
conn, _ := db.TestSetup(t, "postgres")
rw := db.New(conn)
wrapper := db.TestWrapper(t)
@@ -475,7 +476,7 @@ func TestRepository_UpdateUser(t *testing.T) {
assert.True(proto.Equal(userAfterUpdate, foundUser))
sort.Strings(foundAccountIds)
assert.Equal(accountIds, foundAccountIds)
underlyingDB, err := conn.DB()
underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err)
dbassert := dbassert.New(t, underlyingDB)
if tt.args.name == "" {
@@ -710,6 +711,7 @@ func TestRepository_ListUsers_Multiple_Scopes(t *testing.T) {
func TestRepository_LookupUserWithLogin(t *testing.T) {
t.Parallel()
ctx := context.Background()
conn, _ := db.TestSetup(t, "postgres")
rw := db.New(conn)
wrapper := db.TestWrapper(t)
@@ -847,7 +849,7 @@ func TestRepository_LookupUserWithLogin(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
underlyingDB, err := conn.DB()
underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err)
dbassert := dbassert.New(t, underlyingDB)
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) {
t.Parallel()
ctx := context.Background()
conn, _ := db.TestSetup(t, "postgres")
wrapper := db.TestWrapper(t)
repo := TestRepo(t, conn, wrapper)
@@ -440,7 +441,7 @@ func Test_RoleUpdate(t *testing.T) {
}
assert.True(proto.Equal(updateRole, foundRole))
if len(tt.args.nullPaths) != 0 {
underlyingDB, err := conn.DB()
underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err)
dbassert := dbassert.New(t, underlyingDB)
for _, f := range tt.args.nullPaths {
+14 -13
View File
@@ -13,12 +13,11 @@ import (
wrapping "github.com/hashicorp/go-kms-wrapping"
"github.com/hashicorp/go-uuid"
"github.com/stretchr/testify/require"
"gorm.io/gorm"
)
// TestRepo creates a repo that can be used for various purposes. Crucially, it
// 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)
rw := db.New(conn)
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.
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()
require := require.New(t)
rw := db.New(conn)
@@ -176,7 +175,7 @@ func TestRole(t *testing.T, conn *gorm.DB, scopeId string, opt ...Option) *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()
require := require.New(t)
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.
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()
require := require.New(t)
rw := db.New(conn)
@@ -205,7 +204,7 @@ func TestGroup(t *testing.T, conn *gorm.DB, scopeId string, opt ...Option) *Grou
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()
require := require.New(t)
rw := db.New(conn)
@@ -218,7 +217,7 @@ func TestGroupMember(t *testing.T, conn *gorm.DB, groupId, userId string, opt ..
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()
require := require.New(t)
rw := db.New(conn)
@@ -230,7 +229,7 @@ func TestUserRole(t *testing.T, conn *gorm.DB, roleId, userId string, opt ...Opt
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()
require := require.New(t)
rw := db.New(conn)
@@ -242,7 +241,7 @@ func TestGroupRole(t *testing.T, conn *gorm.DB, roleId, grpId string, opt ...Opt
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()
require := require.New(t)
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
// subsystem testAccount function. If userId is zero value, then an auth
// 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 (
accountPrefix = "aa_"
)
t.Helper()
ctx := context.Background()
rw := db.New(conn)
require := require.New(t)
require.NotNil(conn)
@@ -277,7 +278,7 @@ func testAccount(t *testing.T, conn *gorm.DB, scopeId, authMethodId, userId stri
}
var count int
underlyingDB, err := conn.DB()
underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err)
err = underlyingDB.QueryRow(whereValidAuthMethod, authMethodId, scopeId).Scan(&count)
require.NoError(err)
@@ -299,7 +300,7 @@ func testAccount(t *testing.T, conn *gorm.DB, scopeId, authMethodId, userId stri
require.NotEmpty(acct.PublicId)
if userId == "" {
underlyingDB, err := conn.DB()
underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err)
dbassert := dbassert.New(t, underlyingDB)
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
// 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 (
authMethodPrefix = "am_"
)
+13 -14
View File
@@ -8,10 +8,9 @@ import (
wrapping "github.com/hashicorp/go-kms-wrapping"
"github.com/hashicorp/go-kms-wrapping/wrappers/aead"
"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()
require := require.New(t)
rw := db.New(conn)
@@ -26,7 +25,7 @@ func TestRootKey(t *testing.T, conn *gorm.DB, scopeId string) *RootKey {
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()
require := require.New(t)
rw := db.New(conn)
@@ -48,7 +47,7 @@ func TestRootKeyVersion(t *testing.T, conn *gorm.DB, wrapper wrapping.Wrapper, r
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()
require := require.New(t)
rw := db.New(conn)
@@ -61,7 +60,7 @@ func TestKms(t *testing.T, conn *gorm.DB, rootWrapper wrapping.Wrapper) *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()
require := require.New(t)
rw := db.New(conn)
@@ -77,7 +76,7 @@ func TestDatabaseKey(t *testing.T, conn *gorm.DB, rootKeyId string) *DatabaseKey
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()
require := require.New(t)
rw := db.New(conn)
@@ -95,7 +94,7 @@ func TestDatabaseKeyVersion(t *testing.T, conn *gorm.DB, rootKeyVersionWrapper w
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()
require := require.New(t)
rw := db.New(conn)
@@ -111,7 +110,7 @@ func TestOplogKey(t *testing.T, conn *gorm.DB, rootKeyId string) *OplogKey {
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()
require := require.New(t)
rw := db.New(conn)
@@ -129,7 +128,7 @@ func TestOplogKeyVersion(t *testing.T, conn *gorm.DB, rootKeyVersionWrapper wrap
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()
require := require.New(t)
rw := db.New(conn)
@@ -145,7 +144,7 @@ func TestTokenKey(t *testing.T, conn *gorm.DB, rootKeyId string) *TokenKey {
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()
require := require.New(t)
rw := db.New(conn)
@@ -163,7 +162,7 @@ func TestTokenKeyVersion(t *testing.T, conn *gorm.DB, rootKeyVersionWrapper wrap
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()
require := require.New(t)
rw := db.New(conn)
@@ -179,7 +178,7 @@ func TestSessionKey(t *testing.T, conn *gorm.DB, rootKeyId string) *SessionKey {
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()
require := require.New(t)
rw := db.New(conn)
@@ -197,7 +196,7 @@ func TestSessionKeyVersion(t *testing.T, conn *gorm.DB, rootKeyVersionWrapper wr
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()
require := require.New(t)
rw := db.New(conn)
@@ -213,7 +212,7 @@ func TestOidcKey(t *testing.T, conn *gorm.DB, rootKeyId string) *OidcKey {
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()
require := require.New(t)
rw := db.New(conn)
+2 -2
View File
@@ -3,9 +3,9 @@ package oplog
import (
"context"
"crypto/rand"
"database/sql"
"testing"
"github.com/hashicorp/boundary/internal/db/common"
"github.com/hashicorp/boundary/internal/db/schema"
"github.com/hashicorp/boundary/internal/oplog/oplog_test"
"github.com/hashicorp/boundary/testing/dbtest"
@@ -86,7 +86,7 @@ func testInitStore(t *testing.T, cleanup func() error, url string) {
ctx := context.Background()
dialect := "postgres"
d, err := sql.Open(dialect, url)
d, err := common.SqlOpen(dialect, url)
require.NoError(t, err)
sm, err := schema.NewManager(ctx, dialect, d)
require.NoError(t, err)
+2 -2
View File
@@ -1,9 +1,9 @@
package oplog
import (
"database/sql"
"testing"
"github.com/hashicorp/boundary/internal/db/common"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@@ -77,7 +77,7 @@ func Test_testInitStore(t *testing.T) {
const query = `
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)
var cnt int
+4 -5
View File
@@ -12,10 +12,9 @@ import (
wrapping "github.com/hashicorp/go-kms-wrapping"
"github.com/hashicorp/go-uuid"
"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()
require := require.New(t)
rw := db.New(conn)
@@ -31,7 +30,7 @@ func testJob(t *testing.T, conn *gorm.DB, name, description string, wrapper wrap
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 := `
insert into job_run (
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
}
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 := `
insert into job_run (
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
}
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()
rw := db.New(conn)
kms := kms.TestKms(t, conn, wrapper)
+1 -2
View File
@@ -14,7 +14,6 @@ import (
wrapping "github.com/hashicorp/go-kms-wrapping"
"github.com/hashicorp/go-uuid"
"github.com/stretchr/testify/require"
"gorm.io/gorm"
)
// 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
// 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()
rw := db.New(conn)
@@ -41,12 +41,11 @@ import (
"google.golang.org/protobuf/types/known/structpb"
"google.golang.org/protobuf/types/known/timestamppb"
"google.golang.org/protobuf/types/known/wrapperspb"
"gorm.io/gorm"
)
type setup struct {
ctx context.Context
conn *gorm.DB
conn *db.DB
rw *db.Db
rootWrapper wrapping.Wrapper
kmsCache *kms.Kms
@@ -47,7 +47,6 @@ import (
"google.golang.org/protobuf/types/known/structpb"
"google.golang.org/protobuf/types/known/timestamppb"
"google.golang.org/protobuf/types/known/wrapperspb"
"gorm.io/gorm"
)
var testAuthorizedActions = []string{
@@ -67,7 +66,7 @@ var testAuthorizedActions = []string{
"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)
sche := scheduler.TestScheduler(t, conn, wrapper)
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/cmd/base"
"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/iam"
"github.com/hashicorp/boundary/internal/intglobals"
@@ -26,7 +27,6 @@ import (
wrapping "github.com/hashicorp/go-kms-wrapping"
"github.com/hashicorp/go-secure-stdlib/base62"
"github.com/hashicorp/go-secure-stdlib/strutil"
"gorm.io/gorm"
)
const (
@@ -126,7 +126,7 @@ func (tc *TestController) ClusterAddrs() []string {
return tc.addrs("cluster")
}
func (tc *TestController) DbConn() *gorm.DB {
func (tc *TestController) DbConn() *db.DB {
return tc.b.Database
}
@@ -272,8 +272,8 @@ func (tc *TestController) Shutdown() {
tc.t.Error(err)
}
if !tc.opts.DisableDatabaseDestruction {
if tc.b.DestroyDevDatabase() != nil {
if err := tc.b.DestroyDevDatabase(); err != nil {
if tc.b.DestroyDevDatabase(tc.ctx) != nil {
if err := tc.b.DestroyDevDatabase(tc.ctx); err != nil {
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 {
t.Fatal(err)
}
if err := tc.b.ConnectToDatabase("postgres"); err != nil {
if err := tc.b.ConnectToDatabase(tc.ctx, "postgres"); err != nil {
t.Fatal(err)
}
if !opts.DisableKmsKeyCreation {
+8 -9
View File
@@ -19,7 +19,6 @@ import (
wrapping "github.com/hashicorp/go-kms-wrapping"
"github.com/jackc/pgconn"
"google.golang.org/protobuf/types/known/timestamppb"
"gorm.io/gorm"
"github.com/hashicorp/boundary/internal/errors"
"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)
if err != nil {
var pqError *pgconn.PgError
if errors.As(err, &pqError) {
t.Log(pqError.Message)
t.Log(pqError.Detail)
t.Log(pqError.Where)
t.Log(pqError.ConstraintName)
t.Log(pqError.TableName)
var pgError *pgconn.PgError
if errors.As(err, &pgError) {
t.Log(pgError.Message)
t.Log(pgError.Detail)
t.Log(pgError.Where)
t.Log(pgError.ConstraintName)
t.Log(pgError.TableName)
}
}
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()
params := TestSessionParams(t, conn, wrapper, iamRepo)
require := require.New(t)
+7 -8
View File
@@ -20,11 +20,10 @@ import (
"github.com/hashicorp/go-uuid"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/types/known/timestamppb"
"gorm.io/gorm"
)
// 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()
require := require.New(t)
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.
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()
require := require.New(t)
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.
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()
require := require.New(t)
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
// 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()
ctx := context.Background()
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.
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()
composedOf := TestSessionParams(t, conn, wrapper, iamRepo)
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
// 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()
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.
// 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()
rw := db.New(conn)
kms := kms.TestKms(t, conn, wrapper)
@@ -219,6 +219,7 @@ func TestRepository_CreateTcpTarget(t *testing.T) {
func TestRepository_UpdateTcpTarget(t *testing.T) {
t.Parallel()
ctx := context.Background()
conn, _ := db.TestSetup(t, "postgres")
rw := db.New(conn)
wrapper := db.TestWrapper(t)
@@ -491,7 +492,7 @@ func TestRepository_UpdateTcpTarget(t *testing.T) {
foundTarget, _, _, err := repo.LookupTarget(context.Background(), target.PublicId)
assert.NoError(err)
assert.True(proto.Equal(targetAfterUpdate.((*TcpTarget)), foundTarget.((*TcpTarget))))
underlyingDB, err := conn.DB()
underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err)
dbassert := dbassert.New(t, underlyingDB)
if tt.args.description == "" {
+2 -1
View File
@@ -146,6 +146,7 @@ func TestTcpTarget_Delete(t *testing.T) {
func TestTcpTarget_Update(t *testing.T) {
t.Parallel()
id := testId(t)
ctx := context.Background()
conn, _ := db.TestSetup(t, "postgres")
rw := db.New(conn)
wrapper := db.TestWrapper(t)
@@ -279,7 +280,7 @@ func TestTcpTarget_Update(t *testing.T) {
require.NoError(err)
assert.True(proto.Equal(updateTarget, foundTarget))
if len(tt.args.nullPaths) != 0 {
underlyingDB, err := conn.DB()
underlyingDB, err := conn.SqlDB(ctx)
require.NoError(err)
dbassert := dbassert.New(t, underlyingDB)
for _, f := range tt.args.nullPaths {
+2 -3
View File
@@ -8,10 +8,9 @@ import (
"github.com/hashicorp/boundary/internal/db"
"github.com/hashicorp/go-uuid"
"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()
opt = append(opt, WithName(name))
opts := getOpts(opt...)
@@ -62,7 +61,7 @@ func testId(t *testing.T) string {
// TestCredentialLibrary creates a CredentialLibrary for targetId and
// 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()
require := require.New(t)
rw := db.New(conn)
+1 -1
View File
@@ -12,7 +12,7 @@
// require.NoError(t, c())
// })
// // 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
// migrations run. If a test needs a database without any migrations, like in
+9 -5
View File
@@ -1,14 +1,15 @@
package dbtest
import (
"database/sql"
"fmt"
"math/rand"
"os"
"time"
// postgres dialect
_ "github.com/lib/pq"
"github.com/hashicorp/boundary/internal/db/common"
_ "github.com/jackc/pgx/v4/stdlib"
)
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)
}
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 {
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)
}
tdb, err := sql.Open(dialect, url)
tdb, err := common.SqlOpen(dialect, url)
if err != nil {
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")
}
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 {
return err
}
+3 -3
View File
@@ -1,10 +1,10 @@
package dbtest_test
import (
"database/sql"
"errors"
"testing"
"github.com/hashicorp/boundary/internal/db/common"
"github.com/hashicorp/boundary/testing/dbtest"
"github.com/stretchr/testify/require"
)
@@ -56,7 +56,7 @@ func TestStartUsingTemplate(t *testing.T) {
} else {
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, db.Ping())
db.Close()
@@ -64,7 +64,7 @@ func TestStartUsingTemplate(t *testing.T) {
require.NoError(t, 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())
}
})