mirror of https://github.com/hashicorp/boundary
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
810 lines
22 KiB
810 lines
22 KiB
package db
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
|
|
"github.com/hashicorp/go-uuid"
|
|
"github.com/hashicorp/watchtower/internal/db/db_test"
|
|
"github.com/hashicorp/watchtower/internal/oplog"
|
|
"github.com/hashicorp/watchtower/internal/oplog/store"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestDb_Update(t *testing.T) {
|
|
// intentionally not run with t.Parallel so we don't need to use DoTx for the Update tests
|
|
cleanup, db := TestSetup(t, "postgres")
|
|
defer cleanup()
|
|
assert := assert.New(t)
|
|
defer db.Close()
|
|
t.Run("simple", func(t *testing.T) {
|
|
w := Db{underlying: db}
|
|
id, err := uuid.GenerateUUID()
|
|
assert.Nil(err)
|
|
user, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
user.Name = "foo-" + id
|
|
err = w.Create(context.Background(), user)
|
|
assert.Nil(err)
|
|
assert.True(user.Id != 0)
|
|
|
|
foundUser, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
foundUser.PublicId = user.PublicId
|
|
err = w.LookupByPublicId(context.Background(), foundUser)
|
|
assert.Nil(err)
|
|
assert.Equal(foundUser.Id, user.Id)
|
|
|
|
user.Name = "friendly-" + id
|
|
err = w.Update(context.Background(), user, []string{"Name"})
|
|
assert.Nil(err)
|
|
|
|
err = w.LookupByPublicId(context.Background(), foundUser)
|
|
assert.Nil(err)
|
|
assert.Equal(foundUser.Name, user.Name)
|
|
})
|
|
t.Run("valid-WithOplog", func(t *testing.T) {
|
|
w := Db{underlying: db}
|
|
id, err := uuid.GenerateUUID()
|
|
assert.Nil(err)
|
|
user, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
user.Name = "foo-" + id
|
|
err = w.Create(context.Background(), user)
|
|
assert.Nil(err)
|
|
assert.True(user.Id != 0)
|
|
|
|
foundUser, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
foundUser.PublicId = user.PublicId
|
|
err = w.LookupByPublicId(context.Background(), foundUser)
|
|
assert.Nil(err)
|
|
assert.Equal(foundUser.Id, user.Id)
|
|
|
|
user.Name = "friendly-" + id
|
|
err = w.Update(context.Background(), user, []string{"Name"},
|
|
// write oplogs for this update
|
|
WithOplog(
|
|
TestWrapper(t),
|
|
oplog.Metadata{
|
|
"key-only": nil,
|
|
"deployment": []string{"amex"},
|
|
"project": []string{"central-info-systems", "local-info-systems"},
|
|
"resource-public-id": []string{user.GetPublicId()},
|
|
}),
|
|
)
|
|
assert.Nil(err)
|
|
|
|
err = w.LookupByPublicId(context.Background(), foundUser)
|
|
assert.Nil(err)
|
|
assert.Equal(foundUser.Name, user.Name)
|
|
|
|
var metadata store.Metadata
|
|
err = db.Where("key = ? and value = ?", "resource-public-id", user.PublicId).First(&metadata).Error
|
|
assert.Nil(err)
|
|
|
|
var foundEntry oplog.Entry
|
|
err = db.Where("id = ?", metadata.EntryId).First(&foundEntry).Error
|
|
assert.Nil(err)
|
|
})
|
|
t.Run("nil-tx", func(t *testing.T) {
|
|
w := Db{underlying: nil}
|
|
id, err := uuid.GenerateUUID()
|
|
assert.Nil(err)
|
|
user, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
user.Name = "foo-" + id
|
|
err = w.Update(context.Background(), user, nil)
|
|
assert.True(err != nil)
|
|
assert.Equal("update tx is nil", err.Error())
|
|
})
|
|
t.Run("no-wrapper-WithOplog", func(t *testing.T) {
|
|
w := Db{underlying: db}
|
|
id, err := uuid.GenerateUUID()
|
|
assert.Nil(err)
|
|
user, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
user.Name = "foo-" + id
|
|
err = w.Create(context.Background(), user)
|
|
assert.Nil(err)
|
|
assert.True(user.Id != 0)
|
|
|
|
foundUser, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
foundUser.PublicId = user.PublicId
|
|
err = w.LookupByPublicId(context.Background(), foundUser)
|
|
assert.Nil(err)
|
|
assert.Equal(foundUser.Id, user.Id)
|
|
|
|
user.Name = "friendly-" + id
|
|
err = w.Update(context.Background(), user, []string{"Name"},
|
|
WithOplog(
|
|
nil,
|
|
oplog.Metadata{
|
|
"key-only": nil,
|
|
"deployment": []string{"amex"},
|
|
"project": []string{"central-info-systems", "local-info-systems"},
|
|
}),
|
|
)
|
|
assert.True(err != nil)
|
|
assert.Equal("error wrapper is nil for WithWrapper", err.Error())
|
|
})
|
|
t.Run("no-metadata-WithOplog", func(t *testing.T) {
|
|
w := Db{underlying: db}
|
|
id, err := uuid.GenerateUUID()
|
|
assert.Nil(err)
|
|
user, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
user.Name = "foo-" + id
|
|
err = w.Create(context.Background(), user)
|
|
assert.Nil(err)
|
|
assert.True(user.Id != 0)
|
|
|
|
foundUser, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
foundUser.PublicId = user.PublicId
|
|
err = w.LookupByPublicId(context.Background(), foundUser)
|
|
assert.Nil(err)
|
|
assert.Equal(foundUser.Id, user.Id)
|
|
|
|
user.Name = "friendly-" + id
|
|
err = w.Update(context.Background(), user, []string{"Name"},
|
|
WithOplog(
|
|
TestWrapper(t),
|
|
nil,
|
|
),
|
|
)
|
|
assert.True(err != nil)
|
|
assert.Equal("error no metadata for WithOplog", err.Error())
|
|
})
|
|
}
|
|
|
|
func TestDb_Create(t *testing.T) {
|
|
// intentionally not run with t.Parallel so we don't need to use DoTx for the Create tests
|
|
cleanup, db := TestSetup(t, "postgres")
|
|
defer cleanup()
|
|
assert := assert.New(t)
|
|
defer db.Close()
|
|
t.Run("simple", func(t *testing.T) {
|
|
w := Db{underlying: db}
|
|
id, err := uuid.GenerateUUID()
|
|
assert.Nil(err)
|
|
user, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
user.Name = "foo-" + id
|
|
err = w.Create(context.Background(), user)
|
|
assert.Nil(err)
|
|
assert.True(user.Id != 0)
|
|
assert.True(user.GetCreateTime() != nil)
|
|
assert.True(user.GetUpdateTime() != nil)
|
|
|
|
foundUser, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
foundUser.PublicId = user.PublicId
|
|
err = w.LookupByPublicId(context.Background(), foundUser)
|
|
assert.Nil(err)
|
|
assert.Equal(foundUser.Id, user.Id)
|
|
})
|
|
t.Run("valid-WithOplog", func(t *testing.T) {
|
|
w := Db{underlying: db}
|
|
id, err := uuid.GenerateUUID()
|
|
assert.Nil(err)
|
|
user, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
user.Name = "foo-" + id
|
|
err = w.Create(
|
|
context.Background(),
|
|
user,
|
|
WithOplog(
|
|
TestWrapper(t),
|
|
oplog.Metadata{
|
|
"key-only": nil,
|
|
"deployment": []string{"amex"},
|
|
"project": []string{"central-info-systems", "local-info-systems"},
|
|
},
|
|
),
|
|
)
|
|
assert.Nil(err)
|
|
assert.True(user.Id != 0)
|
|
|
|
foundUser, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
foundUser.PublicId = user.PublicId
|
|
err = w.LookupByPublicId(context.Background(), foundUser)
|
|
assert.Nil(err)
|
|
assert.Equal(foundUser.Id, user.Id)
|
|
})
|
|
t.Run("no-wrapper-WithOplog", func(t *testing.T) {
|
|
w := Db{underlying: db}
|
|
id, err := uuid.GenerateUUID()
|
|
assert.Nil(err)
|
|
user, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
user.Name = "foo-" + id
|
|
err = w.Create(
|
|
context.Background(),
|
|
user,
|
|
WithOplog(
|
|
nil,
|
|
oplog.Metadata{
|
|
"key-only": nil,
|
|
"deployment": []string{"amex"},
|
|
"project": []string{"central-info-systems", "local-info-systems"},
|
|
},
|
|
),
|
|
)
|
|
assert.True(err != nil)
|
|
assert.Equal("error wrapper is nil for WithWrapper", err.Error())
|
|
})
|
|
t.Run("no-metadata-WithOplog", func(t *testing.T) {
|
|
w := Db{underlying: db}
|
|
id, err := uuid.GenerateUUID()
|
|
assert.Nil(err)
|
|
user, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
user.Name = "foo-" + id
|
|
err = w.Create(
|
|
context.Background(),
|
|
user,
|
|
WithOplog(
|
|
TestWrapper(t),
|
|
nil,
|
|
),
|
|
)
|
|
assert.True(err != nil)
|
|
assert.Equal("error no metadata for WithOplog", err.Error())
|
|
})
|
|
t.Run("nil-tx", func(t *testing.T) {
|
|
w := Db{underlying: nil}
|
|
id, err := uuid.GenerateUUID()
|
|
assert.Nil(err)
|
|
user, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
user.Name = "foo-" + id
|
|
err = w.Create(context.Background(), user)
|
|
assert.True(err != nil)
|
|
assert.Equal("create tx is nil", err.Error())
|
|
})
|
|
}
|
|
|
|
func TestDb_LookupByName(t *testing.T) {
|
|
t.Parallel()
|
|
cleanup, db := TestSetup(t, "postgres")
|
|
defer cleanup()
|
|
assert := assert.New(t)
|
|
defer db.Close()
|
|
t.Run("simple", func(t *testing.T) {
|
|
w := Db{underlying: db}
|
|
id, err := uuid.GenerateUUID()
|
|
assert.Nil(err)
|
|
user, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
user.Name = "fn-" + id
|
|
err = w.Create(context.Background(), user)
|
|
assert.Nil(err)
|
|
assert.True(user.Id != 0)
|
|
|
|
foundUser, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
foundUser.Name = "fn-" + id
|
|
err = w.LookupByName(context.Background(), foundUser)
|
|
assert.Nil(err)
|
|
assert.Equal(foundUser.Id, user.Id)
|
|
})
|
|
t.Run("tx-nil,", func(t *testing.T) {
|
|
w := Db{}
|
|
foundUser, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
foundUser.Name = "fn-name"
|
|
err = w.LookupByName(context.Background(), foundUser)
|
|
assert.True(err != nil)
|
|
assert.Equal("error tx nil for lookup by name", err.Error())
|
|
})
|
|
t.Run("no-friendly-name-set", func(t *testing.T) {
|
|
w := Db{underlying: db}
|
|
foundUser, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
err = w.LookupByName(context.Background(), foundUser)
|
|
assert.True(err != nil)
|
|
assert.Equal("error name empty string for lookup by name", err.Error())
|
|
})
|
|
t.Run("not-found", func(t *testing.T) {
|
|
w := Db{underlying: db}
|
|
id, err := uuid.GenerateUUID()
|
|
assert.Nil(err)
|
|
|
|
foundUser, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
foundUser.Name = "fn-" + id
|
|
err = w.LookupByName(context.Background(), foundUser)
|
|
assert.True(err != nil)
|
|
assert.Equal(ErrRecordNotFound, err)
|
|
})
|
|
}
|
|
|
|
func TestDb_LookupByPublicId(t *testing.T) {
|
|
t.Parallel()
|
|
cleanup, db := TestSetup(t, "postgres")
|
|
defer cleanup()
|
|
assert := assert.New(t)
|
|
defer db.Close()
|
|
t.Run("simple", func(t *testing.T) {
|
|
w := Db{underlying: db}
|
|
id, err := uuid.GenerateUUID()
|
|
assert.Nil(err)
|
|
user, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
user.Name = "foo-" + id
|
|
err = w.Create(context.Background(), user)
|
|
assert.Nil(err)
|
|
assert.True(user.PublicId != "")
|
|
|
|
foundUser, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
foundUser.PublicId = user.PublicId
|
|
err = w.LookupByPublicId(context.Background(), foundUser)
|
|
assert.Nil(err)
|
|
assert.Equal(foundUser.Id, user.Id)
|
|
})
|
|
t.Run("tx-nil,", func(t *testing.T) {
|
|
w := Db{}
|
|
foundUser, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
err = w.LookupByPublicId(context.Background(), foundUser)
|
|
assert.True(err != nil)
|
|
assert.Equal("error tx nil for lookup by public id", err.Error())
|
|
})
|
|
t.Run("no-public-id-set", func(t *testing.T) {
|
|
w := Db{underlying: db}
|
|
foundUser, err := db_test.NewTestUser()
|
|
foundUser.PublicId = ""
|
|
assert.Nil(err)
|
|
err = w.LookupByPublicId(context.Background(), foundUser)
|
|
assert.True(err != nil)
|
|
assert.Equal("error public id empty string for lookup by public id", err.Error())
|
|
})
|
|
t.Run("not-found", func(t *testing.T) {
|
|
w := Db{underlying: db}
|
|
id, err := uuid.GenerateUUID()
|
|
assert.Nil(err)
|
|
|
|
foundUser, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
foundUser.PublicId = id
|
|
err = w.LookupByPublicId(context.Background(), foundUser)
|
|
assert.True(err != nil)
|
|
assert.Equal(ErrRecordNotFound, err)
|
|
})
|
|
}
|
|
|
|
func TestDb_LookupWhere(t *testing.T) {
|
|
t.Parallel()
|
|
cleanup, db := TestSetup(t, "postgres")
|
|
defer cleanup()
|
|
assert := assert.New(t)
|
|
defer db.Close()
|
|
t.Run("simple", func(t *testing.T) {
|
|
w := Db{underlying: db}
|
|
id, err := uuid.GenerateUUID()
|
|
assert.Nil(err)
|
|
user, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
user.Name = "foo-" + id
|
|
err = w.Create(context.Background(), user)
|
|
assert.Nil(err)
|
|
assert.True(user.PublicId != "")
|
|
|
|
var foundUser db_test.TestUser
|
|
err = w.LookupWhere(context.Background(), &foundUser, "public_id = ?", user.PublicId)
|
|
assert.Nil(err)
|
|
assert.Equal(foundUser.Id, user.Id)
|
|
})
|
|
t.Run("tx-nil,", func(t *testing.T) {
|
|
w := Db{}
|
|
var foundUser db_test.TestUser
|
|
err := w.LookupWhere(context.Background(), &foundUser, "public_id = ?", 1)
|
|
assert.True(err != nil)
|
|
assert.Equal("error tx nil for lookup by", err.Error())
|
|
})
|
|
t.Run("not-found", func(t *testing.T) {
|
|
w := Db{underlying: db}
|
|
id, err := uuid.GenerateUUID()
|
|
assert.Nil(err)
|
|
|
|
var foundUser db_test.TestUser
|
|
err = w.LookupWhere(context.Background(), &foundUser, "public_id = ?", id)
|
|
assert.True(err != nil)
|
|
assert.Equal(ErrRecordNotFound, err)
|
|
})
|
|
t.Run("bad-where", func(t *testing.T) {
|
|
w := Db{underlying: db}
|
|
id, err := uuid.GenerateUUID()
|
|
assert.Nil(err)
|
|
|
|
var foundUser db_test.TestUser
|
|
err = w.LookupWhere(context.Background(), &foundUser, "? = ?", id)
|
|
assert.True(err != nil)
|
|
})
|
|
}
|
|
|
|
func TestDb_SearchWhere(t *testing.T) {
|
|
t.Parallel()
|
|
cleanup, db := TestSetup(t, "postgres")
|
|
defer cleanup()
|
|
assert := assert.New(t)
|
|
defer db.Close()
|
|
t.Run("simple", func(t *testing.T) {
|
|
w := Db{underlying: db}
|
|
id, err := uuid.GenerateUUID()
|
|
assert.Nil(err)
|
|
user, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
user.Name = "foo-" + id
|
|
err = w.Create(context.Background(), user)
|
|
assert.Nil(err)
|
|
assert.True(user.PublicId != "")
|
|
|
|
var foundUsers []db_test.TestUser
|
|
err = w.SearchWhere(context.Background(), &foundUsers, "public_id = ?", user.PublicId)
|
|
assert.Nil(err)
|
|
assert.Equal(foundUsers[0].Id, user.Id)
|
|
})
|
|
t.Run("tx-nil,", func(t *testing.T) {
|
|
w := Db{}
|
|
var foundUsers []db_test.TestUser
|
|
err := w.SearchWhere(context.Background(), &foundUsers, "public_id = ?", 1)
|
|
assert.True(err != nil)
|
|
assert.Equal("error tx nil for search by", err.Error())
|
|
})
|
|
t.Run("not-found", func(t *testing.T) {
|
|
w := Db{underlying: db}
|
|
id, err := uuid.GenerateUUID()
|
|
assert.Nil(err)
|
|
|
|
var foundUsers []db_test.TestUser
|
|
err = w.SearchWhere(context.Background(), &foundUsers, "public_id = ?", id)
|
|
assert.Nil(err)
|
|
assert.Equal(0, len(foundUsers))
|
|
})
|
|
t.Run("bad-where", func(t *testing.T) {
|
|
w := Db{underlying: db}
|
|
id, err := uuid.GenerateUUID()
|
|
assert.Nil(err)
|
|
|
|
var foundUsers []db_test.TestUser
|
|
err = w.SearchWhere(context.Background(), &foundUsers, "? = ?", id)
|
|
assert.True(err != nil)
|
|
})
|
|
}
|
|
|
|
func TestDb_DB(t *testing.T) {
|
|
t.Parallel()
|
|
cleanup, db := TestSetup(t, "postgres")
|
|
defer cleanup()
|
|
assert := assert.New(t)
|
|
defer db.Close()
|
|
t.Run("valid", func(t *testing.T) {
|
|
w := Db{underlying: db}
|
|
d, err := w.DB()
|
|
assert.Nil(err)
|
|
assert.True(d != nil)
|
|
err = d.Ping()
|
|
assert.Nil(err)
|
|
})
|
|
t.Run("nil-tx", func(t *testing.T) {
|
|
w := Db{underlying: nil}
|
|
d, err := w.DB()
|
|
assert.True(err != nil)
|
|
assert.True(d == nil)
|
|
assert.Equal("create tx is nil for db", err.Error())
|
|
})
|
|
}
|
|
|
|
func TestDb_DoTx(t *testing.T) {
|
|
t.Parallel()
|
|
cleanup, db := TestSetup(t, "postgres")
|
|
defer cleanup()
|
|
assert := assert.New(t)
|
|
defer db.Close()
|
|
|
|
t.Run("valid-with-10-retries", func(t *testing.T) {
|
|
w := &Db{underlying: db}
|
|
attempts := 0
|
|
got, err := w.DoTx(context.Background(), 10, ExpBackoff{},
|
|
func(Writer) error {
|
|
attempts += 1
|
|
if attempts < 9 {
|
|
return oplog.ErrTicketAlreadyRedeemed
|
|
}
|
|
return nil
|
|
})
|
|
assert.Nil(err)
|
|
assert.Equal(8, got.Retries)
|
|
assert.Equal(9, attempts) // attempted 1 + 8 retries
|
|
})
|
|
t.Run("valid-with-1-retries", func(t *testing.T) {
|
|
w := &Db{underlying: db}
|
|
attempts := 0
|
|
got, err := w.DoTx(context.Background(), 1, ExpBackoff{},
|
|
func(Writer) error {
|
|
attempts += 1
|
|
if attempts < 2 {
|
|
return oplog.ErrTicketAlreadyRedeemed
|
|
}
|
|
return nil
|
|
})
|
|
assert.Nil(err)
|
|
assert.Equal(1, got.Retries)
|
|
assert.Equal(2, attempts) // attempted 1 + 8 retries
|
|
})
|
|
t.Run("valid-with-2-retries", func(t *testing.T) {
|
|
w := &Db{underlying: db}
|
|
attempts := 0
|
|
got, err := w.DoTx(context.Background(), 3, ExpBackoff{},
|
|
func(Writer) error {
|
|
attempts += 1
|
|
if attempts < 3 {
|
|
return oplog.ErrTicketAlreadyRedeemed
|
|
}
|
|
return nil
|
|
})
|
|
assert.Nil(err)
|
|
assert.Equal(2, got.Retries)
|
|
assert.Equal(3, attempts) // attempted 1 + 8 retries
|
|
})
|
|
t.Run("valid-with-4-retries", func(t *testing.T) {
|
|
w := &Db{underlying: db}
|
|
attempts := 0
|
|
got, err := w.DoTx(context.Background(), 4, ExpBackoff{},
|
|
func(Writer) error {
|
|
attempts += 1
|
|
if attempts < 4 {
|
|
return oplog.ErrTicketAlreadyRedeemed
|
|
}
|
|
return nil
|
|
})
|
|
assert.Nil(err)
|
|
assert.Equal(3, got.Retries)
|
|
assert.Equal(4, attempts) // attempted 1 + 8 retries
|
|
})
|
|
t.Run("zero-retries", func(t *testing.T) {
|
|
w := &Db{underlying: db}
|
|
attempts := 0
|
|
got, err := w.DoTx(context.Background(), 0, ExpBackoff{}, func(Writer) error { attempts += 1; return nil })
|
|
assert.Nil(err)
|
|
assert.Equal(RetryInfo{}, got)
|
|
assert.Equal(1, attempts)
|
|
})
|
|
t.Run("nil-tx", func(t *testing.T) {
|
|
w := &Db{nil}
|
|
attempts := 0
|
|
got, err := w.DoTx(context.Background(), 1, ExpBackoff{}, func(Writer) error { attempts += 1; return nil })
|
|
assert.True(err != nil)
|
|
assert.Equal(RetryInfo{}, got)
|
|
assert.Equal("do tx is nil", err.Error())
|
|
})
|
|
t.Run("not-a-retry-err", func(t *testing.T) {
|
|
w := &Db{underlying: db}
|
|
got, err := w.DoTx(context.Background(), 1, ExpBackoff{}, func(Writer) error { return errors.New("not a retry error") })
|
|
assert.True(err != nil)
|
|
assert.Equal(RetryInfo{}, got)
|
|
assert.True(err != oplog.ErrTicketAlreadyRedeemed)
|
|
})
|
|
t.Run("too-many-retries", func(t *testing.T) {
|
|
w := &Db{underlying: db}
|
|
attempts := 0
|
|
got, err := w.DoTx(context.Background(), 2, ExpBackoff{}, func(Writer) error { attempts += 1; return oplog.ErrTicketAlreadyRedeemed })
|
|
assert.True(err != nil)
|
|
assert.Equal(3, got.Retries)
|
|
assert.Equal("Too many retries: 3 of 3", err.Error())
|
|
})
|
|
}
|
|
|
|
func TestDb_Delete(t *testing.T) {
|
|
// intentionally not run with t.Parallel so we don't need to use DoTx for the Create tests
|
|
cleanup, db := TestSetup(t, "postgres")
|
|
defer cleanup()
|
|
assert := assert.New(t)
|
|
defer db.Close()
|
|
t.Run("simple", func(t *testing.T) {
|
|
w := Db{underlying: db}
|
|
id, err := uuid.GenerateUUID()
|
|
assert.Nil(err)
|
|
user, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
user.Name = "foo-" + id
|
|
err = w.Create(context.Background(), user)
|
|
assert.Nil(err)
|
|
assert.True(user.Id != 0)
|
|
assert.True(user.GetCreateTime() != nil)
|
|
assert.True(user.GetUpdateTime() != nil)
|
|
|
|
foundUser, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
foundUser.PublicId = user.PublicId
|
|
err = w.LookupByPublicId(context.Background(), foundUser)
|
|
assert.Nil(err)
|
|
assert.Equal(foundUser.Id, user.Id)
|
|
|
|
err = w.Delete(context.Background(), user)
|
|
assert.Nil(err)
|
|
|
|
err = w.LookupByPublicId(context.Background(), foundUser)
|
|
assert.True(err != nil)
|
|
assert.Equal(ErrRecordNotFound, err)
|
|
})
|
|
t.Run("valid-WithOplog", func(t *testing.T) {
|
|
w := Db{underlying: db}
|
|
id, err := uuid.GenerateUUID()
|
|
assert.Nil(err)
|
|
user, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
user.Name = "foo-" + id
|
|
err = w.Create(
|
|
context.Background(),
|
|
user,
|
|
WithOplog(
|
|
TestWrapper(t),
|
|
oplog.Metadata{
|
|
"key-only": nil,
|
|
"deployment": []string{"amex"},
|
|
"project": []string{"central-info-systems", "local-info-systems"},
|
|
},
|
|
),
|
|
)
|
|
assert.Nil(err)
|
|
assert.True(user.Id != 0)
|
|
|
|
foundUser, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
foundUser.PublicId = user.PublicId
|
|
err = w.LookupByPublicId(context.Background(), foundUser)
|
|
assert.Nil(err)
|
|
assert.Equal(foundUser.Id, user.Id)
|
|
|
|
err = w.Delete(
|
|
context.Background(),
|
|
user,
|
|
WithOplog(
|
|
TestWrapper(t),
|
|
oplog.Metadata{
|
|
"key-only": nil,
|
|
"deployment": []string{"amex"},
|
|
"project": []string{"central-info-systems", "local-info-systems"},
|
|
},
|
|
),
|
|
)
|
|
assert.Nil(err)
|
|
|
|
err = w.LookupByPublicId(context.Background(), foundUser)
|
|
assert.True(err != nil)
|
|
assert.Equal(ErrRecordNotFound, err)
|
|
})
|
|
t.Run("no-wrapper-WithOplog", func(t *testing.T) {
|
|
w := Db{underlying: db}
|
|
id, err := uuid.GenerateUUID()
|
|
assert.Nil(err)
|
|
user, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
user.Name = "foo-" + id
|
|
err = w.Create(
|
|
context.Background(),
|
|
user,
|
|
WithOplog(
|
|
TestWrapper(t),
|
|
oplog.Metadata{
|
|
"key-only": nil,
|
|
"deployment": []string{"amex"},
|
|
"project": []string{"central-info-systems", "local-info-systems"},
|
|
},
|
|
),
|
|
)
|
|
assert.Nil(err)
|
|
assert.True(user.Id != 0)
|
|
|
|
foundUser, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
foundUser.PublicId = user.PublicId
|
|
err = w.LookupByPublicId(context.Background(), foundUser)
|
|
assert.Nil(err)
|
|
assert.Equal(foundUser.Id, user.Id)
|
|
|
|
err = w.Delete(
|
|
context.Background(),
|
|
user,
|
|
WithOplog(
|
|
nil,
|
|
oplog.Metadata{
|
|
"key-only": nil,
|
|
"deployment": []string{"amex"},
|
|
"project": []string{"central-info-systems", "local-info-systems"},
|
|
},
|
|
),
|
|
)
|
|
assert.True(err != nil)
|
|
assert.Equal("error wrapper is nil for WithWrapper", err.Error())
|
|
})
|
|
t.Run("no-metadata-WithOplog", func(t *testing.T) {
|
|
w := Db{underlying: db}
|
|
id, err := uuid.GenerateUUID()
|
|
assert.Nil(err)
|
|
user, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
user.Name = "foo-" + id
|
|
err = w.Create(
|
|
context.Background(),
|
|
user,
|
|
WithOplog(
|
|
TestWrapper(t),
|
|
oplog.Metadata{
|
|
"key-only": nil,
|
|
"deployment": []string{"amex"},
|
|
"project": []string{"central-info-systems", "local-info-systems"},
|
|
},
|
|
),
|
|
)
|
|
assert.Nil(err)
|
|
assert.True(user.Id != 0)
|
|
|
|
foundUser, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
foundUser.PublicId = user.PublicId
|
|
err = w.LookupByPublicId(context.Background(), foundUser)
|
|
assert.Nil(err)
|
|
assert.Equal(foundUser.Id, user.Id)
|
|
|
|
err = w.Delete(
|
|
context.Background(),
|
|
user,
|
|
WithOplog(
|
|
TestWrapper(t),
|
|
nil,
|
|
),
|
|
)
|
|
assert.True(err != nil)
|
|
assert.Equal("error no metadata for WithOplog", err.Error())
|
|
})
|
|
t.Run("nil-tx", func(t *testing.T) {
|
|
w := Db{underlying: nil}
|
|
id, err := uuid.GenerateUUID()
|
|
assert.Nil(err)
|
|
user, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
user.Name = "foo-" + id
|
|
err = w.Create(context.Background(), user)
|
|
assert.True(err != nil)
|
|
assert.Equal("create tx is nil", err.Error())
|
|
})
|
|
}
|
|
|
|
func TestDb_ScanRows(t *testing.T) {
|
|
t.Parallel()
|
|
cleanup, db := TestSetup(t, "postgres")
|
|
defer cleanup()
|
|
assert := assert.New(t)
|
|
defer db.Close()
|
|
t.Run("valid", func(t *testing.T) {
|
|
w := Db{underlying: db}
|
|
user, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
err = w.Create(context.Background(), user)
|
|
assert.Nil(err)
|
|
assert.True(user.Id != 0)
|
|
|
|
tx, err := w.DB()
|
|
where := "select * from db_test_user where name in ($1, $2)"
|
|
rows, err := tx.Query(where, "alice", "bob")
|
|
defer rows.Close()
|
|
for rows.Next() {
|
|
u, err := db_test.NewTestUser()
|
|
assert.Nil(err)
|
|
|
|
// scan the row into your Gorm struct
|
|
err = w.ScanRows(rows, &u)
|
|
assert.Nil(err)
|
|
assert.Equal(user.PublicId, u.PublicId)
|
|
}
|
|
})
|
|
}
|