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.
726 lines
20 KiB
726 lines
20 KiB
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
package static
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
"github.com/google/go-cmp/cmp/cmpopts"
|
|
"github.com/hashicorp/boundary/internal/db"
|
|
"github.com/hashicorp/boundary/internal/errors"
|
|
"github.com/hashicorp/boundary/internal/iam"
|
|
"github.com/hashicorp/boundary/internal/kms"
|
|
"github.com/hashicorp/boundary/internal/oplog"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"google.golang.org/protobuf/testing/protocmp"
|
|
)
|
|
|
|
func TestRepository_AddSetMembers_Parameters(t *testing.T) {
|
|
ctx := context.Background()
|
|
conn, _ := db.TestSetup(t, "postgres")
|
|
rw := db.New(conn)
|
|
wrapper := db.TestWrapper(t)
|
|
kms := kms.TestKms(t, conn, wrapper)
|
|
iamRepo := iam.TestRepo(t, conn, wrapper)
|
|
|
|
_, prj := iam.TestScopes(t, iamRepo)
|
|
c := TestCatalogs(t, conn, prj.PublicId, 1)[0]
|
|
set := TestSets(t, conn, c.PublicId, 1)[0]
|
|
hosts := TestHosts(t, conn, c.PublicId, 5)
|
|
var hostIds []string
|
|
for _, h := range hosts {
|
|
hostIds = append(hostIds, h.PublicId)
|
|
}
|
|
|
|
badVersion := uint32(12345)
|
|
|
|
type args struct {
|
|
projectId string
|
|
setId string
|
|
version uint32
|
|
hostIds []string
|
|
opt []Option
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want []*Host
|
|
wantErr bool
|
|
wantIsErr errors.Code
|
|
}{
|
|
{
|
|
name: "empty-project-id",
|
|
args: args{
|
|
setId: set.PublicId,
|
|
version: set.Version,
|
|
hostIds: hostIds,
|
|
},
|
|
wantIsErr: errors.InvalidParameter,
|
|
},
|
|
{
|
|
name: "empty-set-id",
|
|
args: args{
|
|
projectId: prj.PublicId,
|
|
version: set.Version,
|
|
hostIds: hostIds,
|
|
},
|
|
wantIsErr: errors.InvalidParameter,
|
|
},
|
|
{
|
|
name: "zero-version",
|
|
args: args{
|
|
projectId: prj.PublicId,
|
|
setId: set.PublicId,
|
|
hostIds: hostIds,
|
|
},
|
|
wantIsErr: errors.InvalidParameter,
|
|
},
|
|
{
|
|
name: "empty-host-ids",
|
|
args: args{
|
|
projectId: prj.PublicId,
|
|
setId: set.PublicId,
|
|
version: set.Version,
|
|
},
|
|
wantIsErr: errors.InvalidParameter,
|
|
},
|
|
{
|
|
name: "invalid-version",
|
|
args: args{
|
|
projectId: prj.PublicId,
|
|
setId: set.PublicId,
|
|
version: badVersion,
|
|
hostIds: hostIds,
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "valid",
|
|
args: args{
|
|
projectId: prj.PublicId,
|
|
setId: set.PublicId,
|
|
version: set.Version,
|
|
hostIds: hostIds,
|
|
},
|
|
want: hosts,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
tt := tt
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
assert, require := assert.New(t), require.New(t)
|
|
repo, err := NewRepository(ctx, rw, rw, kms)
|
|
require.NoError(err)
|
|
require.NotNil(repo)
|
|
got, err := repo.AddSetMembers(ctx, tt.args.projectId, tt.args.setId, tt.args.version, tt.args.hostIds, tt.args.opt...)
|
|
if tt.wantIsErr != 0 {
|
|
assert.Truef(errors.Match(errors.T(tt.wantIsErr), err), "want err: %q got: %q", tt.wantIsErr, err)
|
|
assert.Nil(got)
|
|
assert.Error(db.TestVerifyOplog(t, rw, tt.args.setId, db.WithOperation(oplog.OpType_OP_TYPE_CREATE), db.WithCreateNotBefore(10*time.Second)))
|
|
return
|
|
}
|
|
if tt.wantErr {
|
|
assert.Error(err)
|
|
assert.Nil(got)
|
|
assert.Error(db.TestVerifyOplog(t, rw, tt.args.setId, db.WithOperation(oplog.OpType_OP_TYPE_CREATE), db.WithCreateNotBefore(10*time.Second)))
|
|
return
|
|
}
|
|
require.NoError(err)
|
|
opts := []cmp.Option{
|
|
cmpopts.SortSlices(func(x, y *Host) bool { return x.PublicId < y.PublicId }),
|
|
protocmp.Transform(),
|
|
}
|
|
assert.Len(got, len(tt.want))
|
|
assert.Empty(cmp.Diff(tt.want, got, opts...))
|
|
assert.NoError(db.TestVerifyOplog(t, rw, tt.args.setId, db.WithOperation(oplog.OpType_OP_TYPE_CREATE), db.WithCreateNotBefore(10*time.Second)))
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRepository_AddSetMembers_Combinations(t *testing.T) {
|
|
ctx := context.Background()
|
|
conn, _ := db.TestSetup(t, "postgres")
|
|
rw := db.New(conn)
|
|
wrapper := db.TestWrapper(t)
|
|
kms := kms.TestKms(t, conn, wrapper)
|
|
iamRepo := iam.TestRepo(t, conn, wrapper)
|
|
|
|
_, prj := iam.TestScopes(t, iamRepo)
|
|
|
|
assert, require := assert.New(t), require.New(t)
|
|
c := TestCatalogs(t, conn, prj.PublicId, 1)[0]
|
|
set := TestSets(t, conn, c.PublicId, 1)[0]
|
|
|
|
repo, err := NewRepository(ctx, rw, rw, kms)
|
|
require.NoError(err)
|
|
require.NotNil(repo)
|
|
|
|
hosts := TestHosts(t, conn, c.PublicId, 5)
|
|
var hostIds []string
|
|
for _, h := range hosts {
|
|
hostIds = append(hostIds, h.PublicId)
|
|
}
|
|
|
|
// first call - add first set of hosts - should succeed
|
|
got, err := repo.AddSetMembers(context.Background(), prj.PublicId, set.PublicId, set.Version, hostIds)
|
|
require.NoError(err)
|
|
require.NotNil(got)
|
|
|
|
opts := []cmp.Option{
|
|
cmpopts.SortSlices(func(x, y *Host) bool { return x.PublicId < y.PublicId }),
|
|
protocmp.Transform(),
|
|
}
|
|
assert.Len(got, len(hosts))
|
|
assert.Empty(cmp.Diff(hosts, got, opts...))
|
|
assert.NoError(db.TestVerifyOplog(t, rw, set.PublicId, db.WithOperation(oplog.OpType_OP_TYPE_CREATE), db.WithCreateNotBefore(10*time.Second)))
|
|
|
|
// second call - add new set of hosts - should succeed
|
|
set.Version = set.Version + 1
|
|
Hosts := TestHosts(t, conn, c.PublicId, 5)
|
|
var hostIds2 []string
|
|
for _, h := range Hosts {
|
|
hostIds2 = append(hostIds2, h.PublicId)
|
|
}
|
|
got2, err2 := repo.AddSetMembers(ctx, prj.PublicId, set.PublicId, set.Version, hostIds2)
|
|
require.NoError(err2)
|
|
require.NotNil(got2)
|
|
|
|
hosts = append(hosts, Hosts...)
|
|
assert.Len(got2, len(hosts))
|
|
assert.Empty(cmp.Diff(hosts, got2, opts...))
|
|
assert.NoError(db.TestVerifyOplog(t, rw, set.PublicId, db.WithOperation(oplog.OpType_OP_TYPE_CREATE), db.WithCreateNotBefore(10*time.Second)))
|
|
|
|
// third call - add new hosts plus a few existing hosts - should fail
|
|
set.Version = set.Version + 1
|
|
hosts3 := TestHosts(t, conn, c.PublicId, 5)
|
|
var hostIds3 []string
|
|
for _, h := range hosts3 {
|
|
hostIds3 = append(hostIds2, h.PublicId)
|
|
}
|
|
hostIds3 = append(hostIds3, hostIds2...)
|
|
got3, err3 := repo.AddSetMembers(ctx, prj.PublicId, set.PublicId, set.Version, hostIds3)
|
|
require.Error(err3)
|
|
require.Nil(got3)
|
|
}
|
|
|
|
func TestRepository_DeleteSetMembers_Parameters(t *testing.T) {
|
|
ctx := context.Background()
|
|
conn, _ := db.TestSetup(t, "postgres")
|
|
rw := db.New(conn)
|
|
wrapper := db.TestWrapper(t)
|
|
kms := kms.TestKms(t, conn, wrapper)
|
|
iamRepo := iam.TestRepo(t, conn, wrapper)
|
|
|
|
_, prj := iam.TestScopes(t, iamRepo)
|
|
c := TestCatalogs(t, conn, prj.PublicId, 1)[0]
|
|
set := TestSets(t, conn, c.PublicId, 1)[0]
|
|
count := 5
|
|
hosts := TestHosts(t, conn, c.PublicId, count)
|
|
TestSetMembers(t, conn, set.PublicId, hosts)
|
|
|
|
var hostIds []string
|
|
for _, h := range hosts {
|
|
hostIds = append(hostIds, h.PublicId)
|
|
}
|
|
|
|
badVersion := uint32(12345)
|
|
|
|
type args struct {
|
|
projectId string
|
|
setId string
|
|
version uint32
|
|
hostIds []string
|
|
opt []Option
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want int
|
|
wantErr bool
|
|
wantIsErr errors.Code
|
|
}{
|
|
{
|
|
name: "empty-project-id",
|
|
args: args{
|
|
setId: set.PublicId,
|
|
version: set.Version,
|
|
hostIds: hostIds,
|
|
},
|
|
wantIsErr: errors.InvalidParameter,
|
|
},
|
|
{
|
|
name: "empty-set-id",
|
|
args: args{
|
|
projectId: prj.PublicId,
|
|
version: set.Version,
|
|
hostIds: hostIds,
|
|
},
|
|
wantIsErr: errors.InvalidParameter,
|
|
},
|
|
{
|
|
name: "zero-version",
|
|
args: args{
|
|
projectId: prj.PublicId,
|
|
setId: set.PublicId,
|
|
hostIds: hostIds,
|
|
},
|
|
wantIsErr: errors.InvalidParameter,
|
|
},
|
|
{
|
|
name: "empty-host-ids",
|
|
args: args{
|
|
projectId: prj.PublicId,
|
|
setId: set.PublicId,
|
|
version: set.Version,
|
|
},
|
|
wantIsErr: errors.InvalidParameter,
|
|
},
|
|
{
|
|
name: "invalid-version",
|
|
args: args{
|
|
projectId: prj.PublicId,
|
|
setId: set.PublicId,
|
|
version: badVersion,
|
|
hostIds: hostIds,
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "valid",
|
|
args: args{
|
|
projectId: prj.PublicId,
|
|
setId: set.PublicId,
|
|
version: set.Version,
|
|
hostIds: hostIds,
|
|
},
|
|
want: count,
|
|
wantErr: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
tt := tt
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
assert, require := assert.New(t), require.New(t)
|
|
repo, err := NewRepository(ctx, rw, rw, kms)
|
|
require.NoError(err)
|
|
require.NotNil(repo)
|
|
got, err := repo.DeleteSetMembers(ctx, tt.args.projectId, tt.args.setId, tt.args.version, tt.args.hostIds, tt.args.opt...)
|
|
if tt.wantIsErr != 0 {
|
|
assert.Truef(errors.Match(errors.T(tt.wantIsErr), err), "want err: %q got: %q", tt.wantIsErr, err)
|
|
assert.Zero(got)
|
|
assert.Error(db.TestVerifyOplog(t, rw, tt.args.setId, db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second)))
|
|
return
|
|
}
|
|
if tt.wantErr {
|
|
assert.Error(err)
|
|
assert.Zero(got)
|
|
assert.Error(db.TestVerifyOplog(t, rw, tt.args.setId, db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second)))
|
|
return
|
|
}
|
|
assert.NoError(err)
|
|
assert.Equal(tt.want, got)
|
|
assert.NoError(db.TestVerifyOplog(t, rw, tt.args.setId, db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second)))
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRepository_DeleteSetMembers_Combinations(t *testing.T) {
|
|
ctx := context.Background()
|
|
conn, _ := db.TestSetup(t, "postgres")
|
|
rw := db.New(conn)
|
|
wrapper := db.TestWrapper(t)
|
|
kms := kms.TestKms(t, conn, wrapper)
|
|
iamRepo := iam.TestRepo(t, conn, wrapper)
|
|
|
|
_, prj := iam.TestScopes(t, iamRepo)
|
|
|
|
assert, require := assert.New(t), require.New(t)
|
|
c := TestCatalogs(t, conn, prj.PublicId, 1)[0]
|
|
set := TestSets(t, conn, c.PublicId, 1)[0]
|
|
|
|
repo, err := NewRepository(ctx, rw, rw, kms)
|
|
require.NoError(err)
|
|
require.NotNil(repo)
|
|
|
|
count := 10
|
|
hosts := TestHosts(t, conn, c.PublicId, count)
|
|
TestSetMembers(t, conn, set.PublicId, hosts)
|
|
|
|
var hostIds []string
|
|
for _, h := range hosts {
|
|
hostIds = append(hostIds, h.PublicId)
|
|
}
|
|
split := 5
|
|
idsA := hostIds[:split]
|
|
hostsB, idsB := hosts[split:], hostIds[split:]
|
|
|
|
// first call - delete first half of hosts - should succeed
|
|
got, err := repo.DeleteSetMembers(ctx, prj.PublicId, set.PublicId, set.Version, idsA)
|
|
assert.NoError(err)
|
|
require.Equal(len(idsA), got)
|
|
assert.NoError(db.TestVerifyOplog(t, rw, set.PublicId, db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second)))
|
|
|
|
// verify hostsB are still members
|
|
members, err := getHosts(ctx, repo.reader, set.PublicId, unlimited)
|
|
require.NoError(err)
|
|
|
|
opts := []cmp.Option{
|
|
cmpopts.SortSlices(func(x, y *Host) bool { return x.PublicId < y.PublicId }),
|
|
protocmp.Transform(),
|
|
}
|
|
assert.Len(members, len(hostsB))
|
|
assert.Empty(cmp.Diff(hostsB, members, opts...))
|
|
|
|
// second call - delete first half of hosts again - should fail
|
|
set.Version = set.Version + 1
|
|
got2, err2 := repo.DeleteSetMembers(ctx, prj.PublicId, set.PublicId, set.Version, idsA)
|
|
require.Error(err2)
|
|
assert.Zero(got2)
|
|
|
|
// third call - delete first half and second half - should fail
|
|
got3, err3 := repo.DeleteSetMembers(ctx, prj.PublicId, set.PublicId, set.Version, hostIds)
|
|
require.Error(err3)
|
|
assert.Zero(got3)
|
|
|
|
// fourth call - delete second half of hosts - should succeed
|
|
got4, err4 := repo.DeleteSetMembers(ctx, prj.PublicId, set.PublicId, set.Version, idsB)
|
|
assert.NoError(err4)
|
|
require.Equal(len(idsB), got4)
|
|
assert.NoError(db.TestVerifyOplog(t, rw, set.PublicId, db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second)))
|
|
|
|
// verify no members remain
|
|
Members, err := getHosts(ctx, repo.reader, set.PublicId, unlimited)
|
|
require.NoError(err)
|
|
require.Empty(Members)
|
|
}
|
|
|
|
func TestRepository_SetSetMembers_Parameters(t *testing.T) {
|
|
ctx := context.Background()
|
|
conn, _ := db.TestSetup(t, "postgres")
|
|
rw := db.New(conn)
|
|
wrapper := db.TestWrapper(t)
|
|
kms := kms.TestKms(t, conn, wrapper)
|
|
iamRepo := iam.TestRepo(t, conn, wrapper)
|
|
|
|
_, prj := iam.TestScopes(t, iamRepo)
|
|
c := TestCatalogs(t, conn, prj.PublicId, 1)[0]
|
|
set := TestSets(t, conn, c.PublicId, 1)[0]
|
|
|
|
count := 5
|
|
hosts := TestHosts(t, conn, c.PublicId, count)
|
|
|
|
// hostsA has the first 3 hosts, hostsB has the last 3 hosts
|
|
// the middle host is shared in both.
|
|
hostsA, hostsB := hosts[:3], hosts[2:]
|
|
// hostsA is the initial set of hosts in the host set
|
|
TestSetMembers(t, conn, set.PublicId, hostsA)
|
|
|
|
var hostIds []string
|
|
for _, h := range hostsB {
|
|
hostIds = append(hostIds, h.PublicId)
|
|
}
|
|
|
|
badVersion := uint32(12345)
|
|
|
|
type args struct {
|
|
projectId string
|
|
setId string
|
|
version uint32
|
|
hostIds []string
|
|
opt []Option
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want []*Host
|
|
wantCount int
|
|
wantErr bool
|
|
wantIsErr errors.Code
|
|
}{
|
|
{
|
|
name: "empty-project-id",
|
|
args: args{
|
|
setId: set.PublicId,
|
|
version: set.Version,
|
|
hostIds: hostIds,
|
|
},
|
|
wantIsErr: errors.InvalidParameter,
|
|
},
|
|
{
|
|
name: "empty-set-id",
|
|
args: args{
|
|
projectId: prj.PublicId,
|
|
version: set.Version,
|
|
hostIds: hostIds,
|
|
},
|
|
wantIsErr: errors.InvalidParameter,
|
|
},
|
|
{
|
|
name: "zero-version",
|
|
args: args{
|
|
projectId: prj.PublicId,
|
|
setId: set.PublicId,
|
|
hostIds: hostIds,
|
|
},
|
|
wantIsErr: errors.InvalidParameter,
|
|
},
|
|
{
|
|
name: "invalid-version",
|
|
args: args{
|
|
projectId: prj.PublicId,
|
|
setId: set.PublicId,
|
|
version: badVersion,
|
|
hostIds: hostIds,
|
|
},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "valid",
|
|
args: args{
|
|
projectId: prj.PublicId,
|
|
setId: set.PublicId,
|
|
version: set.Version,
|
|
hostIds: hostIds,
|
|
},
|
|
want: hostsB,
|
|
wantCount: 4, // 2 deleted, 2 added
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
tt := tt
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
assert, require := assert.New(t), require.New(t)
|
|
repo, err := NewRepository(ctx, rw, rw, kms)
|
|
require.NoError(err)
|
|
require.NotNil(repo)
|
|
got, gotCount, err := repo.SetSetMembers(ctx, tt.args.projectId, tt.args.setId, tt.args.version, tt.args.hostIds, tt.args.opt...)
|
|
if tt.wantIsErr != 0 {
|
|
assert.Truef(errors.Match(errors.T(tt.wantIsErr), err), "want err: %q got: %q", tt.wantIsErr, err)
|
|
assert.Nil(got)
|
|
assert.Equal(tt.wantCount, gotCount)
|
|
assert.Error(db.TestVerifyOplog(t, rw, tt.args.setId, db.WithOperation(oplog.OpType_OP_TYPE_UPDATE), db.WithCreateNotBefore(10*time.Second)))
|
|
return
|
|
}
|
|
if tt.wantErr {
|
|
assert.Error(err)
|
|
assert.Nil(got)
|
|
assert.Equal(tt.wantCount, gotCount)
|
|
assert.Error(db.TestVerifyOplog(t, rw, tt.args.setId, db.WithOperation(oplog.OpType_OP_TYPE_UPDATE), db.WithCreateNotBefore(10*time.Second)))
|
|
return
|
|
}
|
|
require.NoError(err)
|
|
opts := []cmp.Option{
|
|
cmpopts.SortSlices(func(x, y *Host) bool { return x.PublicId < y.PublicId }),
|
|
protocmp.Transform(),
|
|
}
|
|
assert.Equal(tt.wantCount, gotCount)
|
|
assert.Len(got, len(tt.want))
|
|
assert.Empty(cmp.Diff(tt.want, got, opts...))
|
|
assert.NoError(db.TestVerifyOplog(t, rw, tt.args.setId, db.WithOperation(oplog.OpType_OP_TYPE_UPDATE), db.WithCreateNotBefore(10*time.Second)))
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRepository_SetSetMembers_Combinations(t *testing.T) {
|
|
ctx := context.Background()
|
|
conn, _ := db.TestSetup(t, "postgres")
|
|
rw := db.New(conn)
|
|
wrapper := db.TestWrapper(t)
|
|
kms := kms.TestKms(t, conn, wrapper)
|
|
iamRepo := iam.TestRepo(t, conn, wrapper)
|
|
|
|
_, prj := iam.TestScopes(t, iamRepo)
|
|
|
|
assert, require := assert.New(t), require.New(t)
|
|
c := TestCatalogs(t, conn, prj.PublicId, 1)[0]
|
|
set := TestSets(t, conn, c.PublicId, 1)[0]
|
|
|
|
repo, err := NewRepository(ctx, rw, rw, kms)
|
|
require.NoError(err)
|
|
require.NotNil(repo)
|
|
|
|
count := 5
|
|
hosts := TestHosts(t, conn, c.PublicId, count)
|
|
|
|
var hostIds []string
|
|
for _, h := range hosts {
|
|
hostIds = append(hostIds, h.PublicId)
|
|
}
|
|
|
|
// hostsA has the first 3 hosts, hostsB has the last 3 hosts
|
|
// the middle host is shared in both.
|
|
hostsA, hostsB := hosts[:3], hosts[2:]
|
|
hostIdsA, hostIdsB := hostIds[:3], hostIds[2:]
|
|
|
|
opts := []cmp.Option{
|
|
cmpopts.SortSlices(func(x, y *Host) bool { return x.PublicId < y.PublicId }),
|
|
protocmp.Transform(),
|
|
}
|
|
|
|
// first call - empty set, empty host Ids - no additions no deletions
|
|
got1, gotCount1, err1 := repo.SetSetMembers(ctx, prj.PublicId, set.PublicId, set.Version, nil)
|
|
assert.NoError(err1)
|
|
assert.Empty(got1)
|
|
assert.Zero(gotCount1)
|
|
assert.Error(db.TestVerifyOplog(t, rw, set.PublicId, db.WithOperation(oplog.OpType_OP_TYPE_UPDATE), db.WithCreateNotBefore(10*time.Second)))
|
|
|
|
// second call - all additions
|
|
got2, gotCount2, err2 := repo.SetSetMembers(context.Background(), prj.PublicId, set.PublicId, set.Version, hostIdsA)
|
|
assert.NoError(err2)
|
|
assert.Equal(len(hostsA), gotCount2)
|
|
assert.NoError(db.TestVerifyOplog(t, rw, set.PublicId, db.WithOperation(oplog.OpType_OP_TYPE_UPDATE), db.WithCreateNotBefore(10*time.Second)))
|
|
assert.Len(got2, len(hostsA))
|
|
assert.Empty(cmp.Diff(hostsA, got2, opts...))
|
|
|
|
// third call - mix of additions and deletions
|
|
set.Version = set.Version + 1
|
|
got3, gotCount3, err3 := repo.SetSetMembers(ctx, prj.PublicId, set.PublicId, set.Version, hostIdsB)
|
|
assert.NoError(err3)
|
|
assert.Equal(4, gotCount3)
|
|
assert.NoError(db.TestVerifyOplog(t, rw, set.PublicId, db.WithOperation(oplog.OpType_OP_TYPE_UPDATE), db.WithCreateNotBefore(10*time.Second)))
|
|
assert.Len(got3, len(hostsB))
|
|
assert.Empty(cmp.Diff(hostsB, got3, opts...))
|
|
|
|
// fourth call - all deletions
|
|
set.Version = set.Version + 1
|
|
got4, gotCount4, err4 := repo.SetSetMembers(ctx, prj.PublicId, set.PublicId, set.Version, nil)
|
|
assert.NoError(err4)
|
|
assert.Equal(len(hostsB), gotCount4)
|
|
assert.NoError(db.TestVerifyOplog(t, rw, set.PublicId, db.WithOperation(oplog.OpType_OP_TYPE_UPDATE), db.WithCreateNotBefore(10*time.Second)))
|
|
assert.Empty(got4)
|
|
}
|
|
|
|
func TestRepository_changes(t *testing.T) {
|
|
ctx := context.Background()
|
|
conn, _ := db.TestSetup(t, "postgres")
|
|
rw := db.New(conn)
|
|
wrapper := db.TestWrapper(t)
|
|
kms := kms.TestKms(t, conn, wrapper)
|
|
iamRepo := iam.TestRepo(t, conn, wrapper)
|
|
|
|
_, prj := iam.TestScopes(t, iamRepo)
|
|
|
|
t.Run("all-additions", func(t *testing.T) {
|
|
c := TestCatalogs(t, conn, prj.PublicId, 1)[0]
|
|
set := TestSets(t, conn, c.PublicId, 1)[0]
|
|
count := 5
|
|
hosts := TestHosts(t, conn, c.PublicId, count)
|
|
|
|
var hostIds []string
|
|
for _, h := range hosts {
|
|
hostIds = append(hostIds, h.PublicId)
|
|
}
|
|
|
|
var want []*change
|
|
for _, h := range hosts {
|
|
chg := &change{
|
|
Action: "add",
|
|
HostId: h.PublicId,
|
|
}
|
|
want = append(want, chg)
|
|
}
|
|
|
|
assert, require := assert.New(t), require.New(t)
|
|
repo, err := NewRepository(ctx, rw, rw, kms)
|
|
require.NoError(err)
|
|
require.NotNil(repo)
|
|
|
|
got, err := repo.changes(ctx, set.PublicId, hostIds)
|
|
assert.NoError(err)
|
|
require.NotNil(got)
|
|
opts := []cmp.Option{
|
|
cmpopts.SortSlices(func(x, y *change) bool { return x.HostId < y.HostId }),
|
|
}
|
|
assert.Len(got, len(want))
|
|
assert.Empty(cmp.Diff(want, got, opts...))
|
|
})
|
|
t.Run("all-deletions", func(t *testing.T) {
|
|
c := TestCatalogs(t, conn, prj.PublicId, 1)[0]
|
|
set := TestSets(t, conn, c.PublicId, 1)[0]
|
|
count := 5
|
|
hosts := TestHosts(t, conn, c.PublicId, count)
|
|
TestSetMembers(t, conn, set.PublicId, hosts)
|
|
|
|
var want []*change
|
|
for _, h := range hosts {
|
|
chg := &change{
|
|
Action: "delete",
|
|
HostId: h.PublicId,
|
|
}
|
|
want = append(want, chg)
|
|
}
|
|
|
|
assert, require := assert.New(t), require.New(t)
|
|
repo, err := NewRepository(ctx, rw, rw, kms)
|
|
require.NoError(err)
|
|
require.NotNil(repo)
|
|
|
|
got, err := repo.changes(ctx, set.PublicId, nil)
|
|
assert.NoError(err)
|
|
require.NotNil(got)
|
|
opts := []cmp.Option{
|
|
cmpopts.SortSlices(func(x, y *change) bool { return x.HostId < y.HostId }),
|
|
}
|
|
assert.Len(got, len(want))
|
|
assert.Empty(cmp.Diff(want, got, opts...))
|
|
})
|
|
t.Run("additions-with-deletions", func(t *testing.T) {
|
|
c := TestCatalogs(t, conn, prj.PublicId, 1)[0]
|
|
set := TestSets(t, conn, c.PublicId, 1)[0]
|
|
|
|
count := 5
|
|
hosts := TestHosts(t, conn, c.PublicId, count)
|
|
initialHosts := hosts[:3]
|
|
TestSetMembers(t, conn, set.PublicId, initialHosts)
|
|
targetHosts := hosts[2:]
|
|
deleteHosts := hosts[:2]
|
|
insertHosts := hosts[3:]
|
|
|
|
var targetHostIds []string
|
|
for _, h := range targetHosts {
|
|
targetHostIds = append(targetHostIds, h.PublicId)
|
|
}
|
|
|
|
var want []*change
|
|
for _, h := range deleteHosts {
|
|
chg := &change{
|
|
Action: "delete",
|
|
HostId: h.PublicId,
|
|
}
|
|
want = append(want, chg)
|
|
}
|
|
for _, h := range insertHosts {
|
|
chg := &change{
|
|
Action: "add",
|
|
HostId: h.PublicId,
|
|
}
|
|
want = append(want, chg)
|
|
}
|
|
|
|
assert, require := assert.New(t), require.New(t)
|
|
repo, err := NewRepository(ctx, rw, rw, kms)
|
|
require.NoError(err)
|
|
require.NotNil(repo)
|
|
|
|
got, err := repo.changes(ctx, set.PublicId, targetHostIds)
|
|
assert.NoError(err)
|
|
require.NotNil(got)
|
|
opts := []cmp.Option{
|
|
cmpopts.SortSlices(func(x, y *change) bool { return x.HostId < y.HostId }),
|
|
}
|
|
assert.Len(got, len(want))
|
|
assert.Empty(cmp.Diff(want, got, opts...))
|
|
})
|
|
}
|