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.
boundary/internal/host/plugin/repository_host_util_test.go

313 lines
8.6 KiB

package plugin
import (
"context"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/hashicorp/boundary/internal/host"
hoststore "github.com/hashicorp/boundary/internal/host/store"
plgpb "github.com/hashicorp/boundary/sdk/pbs/plugin"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/proto"
)
func TestUtilFunctions(t *testing.T) {
ctx := context.Background()
const externalId = "ext_1234567890"
const pluginId = "plg_1234567890"
catalog, err := NewHostCatalog(ctx, "p_1234567890", pluginId)
require.NoError(t, err)
require.NotNil(t, catalog)
catalog.PublicId = "hc_1234567890"
baseHostId, err := newHostId(ctx, catalog.GetPublicId(), externalId)
require.NoError(t, err)
baseResponseHost := &plgpb.ListHostsResponseHost{
ExternalId: externalId,
Name: "base-name",
Description: "base-description",
IpAddresses: []string{"1.2.3.4", "5.6.7.8"},
DnsNames: []string{"a.b.c", "x.y.z"},
SetIds: []string{"set1", "set2"},
}
baseIpsIfaces := valueToInterfaceMap{}
for _, v := range baseResponseHost.IpAddresses {
ip, err := host.NewIpAddress(ctx, baseHostId, v)
require.NoError(t, err)
baseIpsIfaces[v] = ip
}
baseDnsNamesIfaces := valueToInterfaceMap{}
for _, v := range baseResponseHost.DnsNames {
name, err := host.NewDnsName(ctx, baseHostId, v)
require.NoError(t, err)
baseDnsNamesIfaces[v] = name
}
baseHost := NewHost(ctx, catalog.PublicId, externalId)
baseHost.Name = baseResponseHost.Name
baseHost.Description = baseResponseHost.Description
baseHost.IpAddresses = baseResponseHost.IpAddresses
baseHost.DnsNames = baseResponseHost.DnsNames
baseHost.PluginId = pluginId
baseHost.SetIds = baseResponseHost.SetIds
defaultHostFunc := func(in *Host) *Host {
return in
}
defaultSetsFunc := func() []string {
return baseHost.SetIds
}
tests := []struct {
name string
host func(*Host) *Host
// This function should take in a base host (which will be provided as a
// clone) and transform however needed for the particular test
in func(*plgpb.ListHostsResponseHost) (*plgpb.ListHostsResponseHost, *hostInfo)
sets func() []string
setsToAdd map[string][]string
setsToRemove map[string][]string
}{
{
name: "base",
host: func(in *Host) *Host {
return nil
},
sets: func() []string {
return nil
},
in: func(in *plgpb.ListHostsResponseHost) (*plgpb.ListHostsResponseHost, *hostInfo) {
hi := &hostInfo{
dirtyHost: true,
ipsToAdd: baseIpsIfaces,
dnsNamesToAdd: baseDnsNamesIfaces,
}
return in, hi
},
},
{
name: "no-change",
host: defaultHostFunc,
sets: defaultSetsFunc,
in: func(in *plgpb.ListHostsResponseHost) (*plgpb.ListHostsResponseHost, *hostInfo) {
hi := &hostInfo{}
return in, hi
},
},
{
name: "new-name",
host: defaultHostFunc,
sets: defaultSetsFunc,
in: func(in *plgpb.ListHostsResponseHost) (*plgpb.ListHostsResponseHost, *hostInfo) {
in.Name = "newname"
hi := &hostInfo{
dirtyHost: true,
}
return in, hi
},
},
{
name: "new-description",
host: defaultHostFunc,
sets: defaultSetsFunc,
in: func(in *plgpb.ListHostsResponseHost) (*plgpb.ListHostsResponseHost, *hostInfo) {
in.Description = "newdescription"
hi := &hostInfo{
dirtyHost: true,
}
return in, hi
},
},
{
name: "extra-ip",
host: defaultHostFunc,
sets: defaultSetsFunc,
in: func(in *plgpb.ListHostsResponseHost) (*plgpb.ListHostsResponseHost, *hostInfo) {
const newIp = "11.22.33.44"
in.IpAddresses = append(in.IpAddresses, newIp)
ip, err := host.NewIpAddress(ctx, baseHostId, newIp)
require.NoError(t, err)
hi := &hostInfo{
ipsToAdd: valueToInterfaceMap{newIp: ip},
}
return in, hi
},
},
{
name: "remove-ip",
host: defaultHostFunc,
sets: defaultSetsFunc,
in: func(in *plgpb.ListHostsResponseHost) (*plgpb.ListHostsResponseHost, *hostInfo) {
hi := &hostInfo{
ipsToRemove: valueToInterfaceMap{},
}
for _, ip := range in.IpAddresses[1:] {
hi.ipsToRemove[ip] = baseIpsIfaces[ip]
}
in.IpAddresses = in.IpAddresses[0:1]
return in, hi
},
},
{
name: "extra-dns-name",
host: defaultHostFunc,
sets: defaultSetsFunc,
in: func(in *plgpb.ListHostsResponseHost) (*plgpb.ListHostsResponseHost, *hostInfo) {
const newName = "this.is.a.test"
in.DnsNames = append(in.DnsNames, newName)
name, err := host.NewDnsName(ctx, baseHostId, newName)
require.NoError(t, err)
hi := &hostInfo{
dnsNamesToAdd: valueToInterfaceMap{newName: name},
}
return in, hi
},
},
{
name: "remove-dns-name",
host: defaultHostFunc,
sets: defaultSetsFunc,
in: func(in *plgpb.ListHostsResponseHost) (*plgpb.ListHostsResponseHost, *hostInfo) {
hi := &hostInfo{
dnsNamesToRemove: valueToInterfaceMap{},
}
for _, name := range in.DnsNames[1:] {
hi.dnsNamesToRemove[name] = baseDnsNamesIfaces[name]
}
in.DnsNames = in.DnsNames[0:1]
return in, hi
},
},
{
name: "add-sets",
host: defaultHostFunc,
sets: func() []string {
return append(defaultSetsFunc(), "extra-set", "extra-set-2")
},
in: func(in *plgpb.ListHostsResponseHost) (*plgpb.ListHostsResponseHost, *hostInfo) {
hi := &hostInfo{}
return in, hi
},
setsToAdd: map[string][]string{
"extra-set": {baseHostId},
"extra-set-2": {baseHostId},
},
},
{
name: "remove-sets",
host: defaultHostFunc,
sets: func() []string {
return defaultSetsFunc()[0:1]
},
in: func(in *plgpb.ListHostsResponseHost) (*plgpb.ListHostsResponseHost, *hostInfo) {
hi := &hostInfo{}
return in, hi
},
setsToRemove: map[string][]string{
"set2": {baseHostId},
},
},
{
name: "add-and-remove-sets",
host: defaultHostFunc,
sets: func() []string {
return append(defaultSetsFunc()[0:1], "extra-set")
},
in: func(in *plgpb.ListHostsResponseHost) (*plgpb.ListHostsResponseHost, *hostInfo) {
hi := &hostInfo{}
return in, hi
},
setsToAdd: map[string][]string{
"extra-set": {baseHostId},
},
setsToRemove: map[string][]string{
"set2": {baseHostId},
},
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
require, assert := require.New(t), assert.New(t)
var hi *hostInfo
currHost := tt.host(baseHost.clone())
currentHostMap := map[string]*Host{}
if currHost != nil {
currentHostMap[baseHostId] = currHost
}
h := proto.Clone(baseResponseHost).(*plgpb.ListHostsResponseHost)
h, hi = tt.in(h)
newHostMap, err := createNewHostMap(ctx, catalog, []*plgpb.ListHostsResponseHost{h}, currentHostMap)
require.NoError(err)
require.NotNil(newHostMap)
require.NotNil(newHostMap[baseHostId])
got := newHostMap[baseHostId]
// Check the various host/hostinfo bits
{
assert.Equal(h.ExternalId, got.h.ExternalId)
assert.Equal(h.Name, got.h.Name)
assert.Equal(h.Description, got.h.Description)
assert.ElementsMatch(h.IpAddresses, got.h.IpAddresses)
assert.ElementsMatch(h.DnsNames, got.h.DnsNames)
assert.ElementsMatch(h.SetIds, got.h.SetIds)
assert.Equal(hi.dirtyHost, got.dirtyHost)
assert.Empty(
cmp.Diff(
hi.ipsToAdd,
got.ipsToAdd,
cmpopts.IgnoreUnexported(host.IpAddress{}, hoststore.IpAddress{}),
cmpopts.SortSlices(func(x, y interface{}) bool {
return x.(*host.IpAddress).Address < y.(*host.IpAddress).Address
}),
),
)
assert.Empty(
cmp.Diff(
hi.ipsToRemove,
got.ipsToRemove,
cmpopts.IgnoreUnexported(host.IpAddress{}, hoststore.IpAddress{}),
cmpopts.SortSlices(func(x, y interface{}) bool {
return x.(*host.IpAddress).Address < y.(*host.IpAddress).Address
}),
),
)
assert.Empty(
cmp.Diff(
hi.dnsNamesToAdd,
got.dnsNamesToAdd,
cmpopts.IgnoreUnexported(host.DnsName{}, hoststore.DnsName{}),
cmpopts.SortSlices(func(x, y interface{}) bool {
return x.(*host.DnsName).Name < y.(*host.DnsName).Name
}),
),
)
assert.Empty(
cmp.Diff(
hi.dnsNamesToRemove,
got.dnsNamesToRemove,
cmpopts.IgnoreUnexported(host.DnsName{}, hoststore.DnsName{}),
cmpopts.SortSlices(func(x, y interface{}) bool {
return x.(*host.DnsName).Name < y.(*host.DnsName).Name
}),
),
)
}
// Run through the sets function
{
newHostMap[baseHostId].h.SetIds = tt.sets()
toAdd, toRemove := getSetChanges(currentHostMap, newHostMap)
assert.Equal(tt.setsToAdd, toAdd)
assert.Equal(tt.setsToRemove, toRemove)
}
})
}
}