Files
threshold/internal/host/plugin/host_catalog_test.go
T
Todd a4ea99047f Remove Prefix Id and Plugin Name fields (#1563)
* Remove Prefix Id and Plugin Name fields.  Creating catalogs now require either the plugin id or the name of the plugin resource (but not both).  Host Catalogs and Host Sets API resources now have a read only plugin field populated with plugin info.  Host Catalogs have a plugin id field as a top level field.
2021-09-24 13:16:13 -07:00

329 lines
8.4 KiB
Go

package plugin
import (
"context"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/hashicorp/boundary/internal/db"
"github.com/hashicorp/boundary/internal/errors"
"github.com/hashicorp/boundary/internal/host/plugin/store"
"github.com/hashicorp/boundary/internal/iam"
"github.com/hashicorp/boundary/internal/plugin/host"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/testing/protocmp"
"google.golang.org/protobuf/types/known/structpb"
)
func TestHostCatalog_Create(t *testing.T) {
ctx := context.Background()
conn, _ := db.TestSetup(t, "postgres")
wrapper := db.TestWrapper(t)
_, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper))
plg := host.TestPlugin(t, conn, "test")
type args struct {
pluginId string
scopeId string
opts []Option
}
tests := []struct {
name string
args args
want *HostCatalog
wantErr bool
wantCreateErr bool
}{
{
name: "blank-scopeId",
args: args{
pluginId: plg.GetPublicId(),
scopeId: "",
},
want: &HostCatalog{
HostCatalog: &store.HostCatalog{
PluginId: plg.GetPublicId(),
Attributes: []byte{},
},
},
wantCreateErr: true,
},
{
name: "blank-pluginId",
args: args{
pluginId: "",
scopeId: prj.GetPublicId(),
},
want: &HostCatalog{
HostCatalog: &store.HostCatalog{
ScopeId: prj.GetPublicId(),
Attributes: []byte{},
},
},
wantCreateErr: true,
},
{
name: "valid-no-options",
args: args{
pluginId: plg.GetPublicId(),
scopeId: prj.GetPublicId(),
},
want: &HostCatalog{
HostCatalog: &store.HostCatalog{
PluginId: plg.GetPublicId(),
ScopeId: prj.GetPublicId(),
Attributes: []byte{},
},
},
},
{
name: "valid-with-name",
args: args{
pluginId: plg.GetPublicId(),
scopeId: prj.GetPublicId(),
opts: []Option{
WithName("test-name"),
},
},
want: &HostCatalog{
HostCatalog: &store.HostCatalog{
PluginId: plg.GetPublicId(),
ScopeId: prj.GetPublicId(),
Name: "test-name",
Attributes: []byte{},
},
},
},
{
name: "valid-with-description",
args: args{
pluginId: plg.GetPublicId(),
scopeId: prj.GetPublicId(),
opts: []Option{
WithDescription("test-description"),
},
},
want: &HostCatalog{
HostCatalog: &store.HostCatalog{
PluginId: plg.GetPublicId(),
ScopeId: prj.GetPublicId(),
Description: "test-description",
Attributes: []byte{},
},
},
},
{
name: "valid-with-attributes",
args: args{
pluginId: plg.GetPublicId(),
scopeId: prj.GetPublicId(),
opts: []Option{
WithAttributes(&structpb.Struct{Fields: map[string]*structpb.Value{"foo": structpb.NewStringValue("bar")}}),
},
},
want: func() *HostCatalog {
hc := &HostCatalog{
HostCatalog: &store.HostCatalog{
PluginId: plg.GetPublicId(),
ScopeId: prj.GetPublicId(),
},
}
var err error
hc.Attributes, err = proto.Marshal(&structpb.Struct{Fields: map[string]*structpb.Value{"foo": structpb.NewStringValue("bar")}})
require.NoError(t, err)
return hc
}(),
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
got, err := NewHostCatalog(ctx, tt.args.scopeId, tt.args.pluginId, tt.args.opts...)
require.NoError(t, err)
require.NotNil(t, got)
assert.Emptyf(t, got.PublicId, "PublicId set")
assert.Equal(t, tt.want, got)
id, err := newHostCatalogId(ctx)
assert.NoError(t, err)
tt.want.PublicId = id
got.PublicId = id
w := db.New(conn)
err = w.Create(ctx, got)
if tt.wantCreateErr {
assert.Error(t, err)
} else {
assert.NoError(t, err)
found := &HostCatalog{
HostCatalog: &store.HostCatalog{
PublicId: id,
},
}
require.NoError(t, w.LookupById(ctx, found))
assert.Empty(t, cmp.Diff(got.HostCatalog, found.HostCatalog, protocmp.Transform()), "%q compared to %q", got.Attributes, found.Attributes)
}
})
}
}
func TestHostCatalog_Create_DuplicateNames(t *testing.T) {
ctx := context.Background()
conn, _ := db.TestSetup(t, "postgres")
w := db.New(conn)
wrapper := db.TestWrapper(t)
_, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper))
_, prj2 := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper))
plg := host.TestPlugin(t, conn, "test1")
plg2 := host.TestPlugin(t, conn, "test2")
got, err := NewHostCatalog(ctx, prj.GetPublicId(), plg.GetPublicId(), WithName("duplicate"))
require.NoError(t, err)
got.PublicId, err = newHostCatalogId(ctx)
require.NoError(t, err)
require.NoError(t, w.Create(ctx, got))
// Can't create another resource with the same name in the same scope
got.PublicId, err = newHostCatalogId(ctx)
require.NoError(t, err)
assert.Error(t, w.Create(ctx, got))
// Can't create another resource with same name in same scope even for different plugin
got, err = NewHostCatalog(ctx, prj.GetPublicId(), plg2.GetPublicId(), WithName("duplicate"))
require.NoError(t, err)
got.PublicId, err = newHostCatalogId(ctx)
require.NoError(t, err)
assert.Error(t, w.Create(ctx, got))
// Can create another resource with same name in different scope even for same plugin
got, err = NewHostCatalog(ctx, prj2.GetPublicId(), plg.GetPublicId(), WithName("duplicate"))
require.NoError(t, err)
got.PublicId, err = newHostCatalogId(ctx)
require.NoError(t, err)
assert.NoError(t, w.Create(ctx, got))
}
func TestHostCatalog_Delete(t *testing.T) {
conn, _ := db.TestSetup(t, "postgres")
wrapper := db.TestWrapper(t)
_, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper))
plg := host.TestPlugin(t, conn, "test")
cat := TestCatalog(t, conn, prj.GetPublicId(), plg.GetPublicId())
ignoredCat := TestCatalog(t, conn, prj.GetPublicId(), plg.GetPublicId())
_ = ignoredCat
tests := []struct {
name string
cat *HostCatalog
rowsDeleted int
}{
{
name: "valid",
cat: &HostCatalog{
HostCatalog: &store.HostCatalog{
PublicId: cat.GetPublicId(),
},
},
rowsDeleted: 1,
},
{
name: "bad-id",
cat: &HostCatalog{
HostCatalog: &store.HostCatalog{
PublicId: "bad-id",
},
},
rowsDeleted: 0,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ctx := context.Background()
w := db.New(conn)
deletedRows, err := w.Delete(ctx, tt.cat)
require.NoError(t, err)
assert.Equal(t, tt.rowsDeleted, deletedRows)
err = w.LookupById(ctx, tt.cat)
require.Error(t, err)
assert.True(t, errors.IsNotFoundError(err))
})
}
}
func TestHostCatalog_Delete_Cascading(t *testing.T) {
conn, _ := db.TestSetup(t, "postgres")
w := db.New(conn)
wrapper := db.TestWrapper(t)
ctx := context.Background()
t.Run("delete-scope", func(t *testing.T) {
_, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper))
plg := host.TestPlugin(t, conn, "deletescope")
cat := TestCatalog(t, conn, prj.GetPublicId(), plg.GetPublicId())
deleted, err := w.Delete(ctx, prj)
require.NoError(t, err)
require.Equal(t, 1, deleted)
err = w.LookupById(ctx, cat)
require.Error(t, err)
assert.True(t, errors.IsNotFoundError(err))
})
t.Run("delete-plugin", func(t *testing.T) {
_, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper))
plg := host.TestPlugin(t, conn, "deleteplugin")
cat := TestCatalog(t, conn, prj.GetPublicId(), plg.GetPublicId())
deleted, err := w.Delete(ctx, plg)
require.NoError(t, err)
require.Equal(t, 1, deleted)
err = w.LookupById(ctx, cat)
require.Error(t, err)
assert.True(t, errors.IsNotFoundError(err))
})
}
func TestHostCatalog_SetTableName(t *testing.T) {
defaultTableName := "host_plugin_catalog"
tests := []struct {
name string
initialName string
setNameTo string
want string
}{
{
name: "new-name",
initialName: "",
setNameTo: "new-name",
want: "new-name",
},
{
name: "reset to default",
initialName: "initial",
setNameTo: "",
want: defaultTableName,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
def, err := NewHostCatalog(context.Background(), "", "")
require.NoError(t, err)
require.Equal(t, defaultTableName, def.TableName())
s := &HostCatalog{
HostCatalog: &store.HostCatalog{},
tableName: tt.initialName,
}
s.SetTableName(tt.setNameTo)
assert.Equal(t, tt.want, s.TableName())
})
}
}