Refactor link monitor test into a table test

pull/20401/head
Nick Cellino 10 months ago
parent 3e21faeaa9
commit daa1962623

@ -26,13 +26,10 @@ import (
"github.com/hashicorp/consul/sdk/testutil"
)
func TestMonitorHCPLink_Ok(t *testing.T) {
func TestMonitorHCPLink(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
linkWatchCh := make(chan *pbresource.WatchEvent)
mgr := NewMockManager(t)
mockHCPClient := hcpclient.NewMockClient(t)
mockHcpClientFn := func(_ config.CloudConfig) (hcpclient.Client, error) {
return mockHCPClient, nil
@ -43,213 +40,110 @@ func TestMonitorHCPLink_Ok(t *testing.T) {
}
dataDir := testutil.TempDir(t, "test-link-controller")
os.Mkdir(filepath.Join(dataDir, constants.SubDir), os.ModeDir)
err := os.Mkdir(filepath.Join(dataDir, constants.SubDir), os.ModeDir)
require.NoError(t, err)
existingCfg := config.CloudConfig{
AuthURL: "test.com",
}
var wg sync.WaitGroup
type testCase struct {
mutateLink func(*pbhcp.Link)
mutateUpsertEvent func(*pbresource.WatchEvent_Upsert)
applyMocksAndAssertions func(*testing.T, *MockManager, *pbhcp.Link)
}
wg.Add(1)
go func() {
defer wg.Done()
MonitorHCPLink(
ctx, hclog.New(&hclog.LoggerOptions{Output: io.Discard}), mgr, linkWatchCh, mockHcpClientFn,
loadMgmtTokenFn, existingCfg, dataDir,
)
}()
testCases := map[string]testCase{
// HCP manager should be started when link is created and stopped when link is deleted
"Ok": {
applyMocksAndAssertions: func(t *testing.T, mgr *MockManager, link *pbhcp.Link) {
mgr.EXPECT().Start(mock.Anything).Return(nil).Once()
// Set up a link
link := pbhcp.Link{
ResourceId: "abc",
ClientId: "def",
ClientSecret: "ghi",
AccessLevel: pbhcp.AccessLevel_ACCESS_LEVEL_GLOBAL_READ_WRITE,
}
expectedCfg := config.CloudConfig{
ResourceID: link.ResourceId,
ClientID: link.ClientId,
ClientSecret: link.ClientSecret,
AuthURL: "test.com",
ManagementToken: "test-mgmt-token",
}
linkResource, err := anypb.New(&link)
require.NoError(t, err)
expectedCfg := config.CloudConfig{
ResourceID: link.ResourceId,
ClientID: link.ClientId,
ClientSecret: link.ClientSecret,
AuthURL: "test.com",
ManagementToken: "test-mgmt-token",
}
mgr.EXPECT().UpdateConfig(mockHCPClient, expectedCfg)
// Create link, expect HCP manager to be updated and started
mgr.EXPECT().Start(mock.Anything).Return(nil).Once()
mgr.EXPECT().UpdateConfig(mockHCPClient, expectedCfg)
linkWatchCh <- &pbresource.WatchEvent{
Event: &pbresource.WatchEvent_Upsert_{
Upsert: &pbresource.WatchEvent_Upsert{
Resource: &pbresource.Resource{
Id: &pbresource.ID{
Name: "global",
Type: pbhcp.LinkType,
},
Status: map[string]*pbresource.Status{
hcpctl.StatusKey: {
Conditions: []*pbresource.Condition{hcpctl.ConditionValidatedSuccess},
},
},
Data: linkResource,
},
mgr.EXPECT().Stop().Return(nil).Once()
},
},
}
// Delete link, expect HCP manager to be stopped
mgr.EXPECT().Stop().Return(nil).Once()
linkWatchCh <- &pbresource.WatchEvent{
Event: &pbresource.WatchEvent_Delete_{
Delete: &pbresource.WatchEvent_Delete{},
// HCP manager should not be updated with management token
"ReadOnly": {
mutateLink: func(link *pbhcp.Link) {
link.AccessLevel = pbhcp.AccessLevel_ACCESS_LEVEL_GLOBAL_READ_ONLY
},
applyMocksAndAssertions: func(t *testing.T, mgr *MockManager, link *pbhcp.Link) {
mgr.EXPECT().Start(mock.Anything).Return(nil).Once()
expectedCfg := config.CloudConfig{
ResourceID: link.ResourceId,
ClientID: link.ClientId,
ClientSecret: link.ClientSecret,
AuthURL: "test.com",
ManagementToken: "",
}
mgr.EXPECT().UpdateConfig(mockHCPClient, expectedCfg)
mgr.EXPECT().Stop().Return(nil).Once()
},
},
}
// Wait for MonitorHCPLink to return before assertions run
close(linkWatchCh)
wg.Wait()
// Ensure hcp-config directory is removed
file := filepath.Join(dataDir, constants.SubDir)
if _, err := os.Stat(file); err == nil || !os.IsNotExist(err) {
require.Fail(t, "should have removed hcp-config directory")
}
}
func TestMonitorHCPLink_ValidationError(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
linkWatchCh := make(chan *pbresource.WatchEvent)
mgr := NewMockManager(t)
mockHCPClient := hcpclient.NewMockClient(t)
mockHcpClientFn := func(_ config.CloudConfig) (hcpclient.Client, error) {
return mockHCPClient, nil
}
loadMgmtTokenFn := func(ctx context.Context, logger hclog.Logger, hcpClient hcpclient.Client, dataDir string) (string, error) {
return "test-mgmt-token", nil
}
dataDir := testutil.TempDir(t, "test-link-controller")
os.Mkdir(filepath.Join(dataDir, constants.SubDir), os.ModeDir)
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
MonitorHCPLink(
ctx, hclog.New(&hclog.LoggerOptions{Output: io.Discard}), mgr, linkWatchCh, mockHcpClientFn,
loadMgmtTokenFn, config.CloudConfig{}, dataDir,
)
}()
// Set up a link
link := pbhcp.Link{
ResourceId: "abc",
ClientId: "def",
ClientSecret: "ghi",
AccessLevel: pbhcp.AccessLevel_ACCESS_LEVEL_GLOBAL_READ_WRITE,
}
linkResource, err := anypb.New(&link)
require.NoError(t, err)
// Create link, expect HCP manager to be updated and started
linkWatchCh <- &pbresource.WatchEvent{
Event: &pbresource.WatchEvent_Upsert_{
Upsert: &pbresource.WatchEvent_Upsert{
Resource: &pbresource.Resource{
Id: &pbresource.ID{
Name: "global",
Type: pbhcp.LinkType,
},
Status: map[string]*pbresource.Status{
hcpctl.StatusKey: {
Conditions: []*pbresource.Condition{hcpctl.ConditionValidatedFailed},
},
// HCP manager should not be started or updated if link is not validated
"ValidationError": {
mutateUpsertEvent: func(upsert *pbresource.WatchEvent_Upsert) {
upsert.Resource.Status = map[string]*pbresource.Status{
hcpctl.StatusKey: {
Conditions: []*pbresource.Condition{hcpctl.ConditionValidatedFailed},
},
Data: linkResource,
},
}
},
applyMocksAndAssertions: func(t *testing.T, mgr *MockManager, link *pbhcp.Link) {
mgr.AssertNotCalled(t, "Start", mock.Anything)
mgr.AssertNotCalled(t, "UpdateConfig", mock.Anything, mock.Anything)
mgr.EXPECT().Stop().Return(nil).Once()
},
},
}
// Delete link, expect HCP manager to be stopped
mgr.EXPECT().Stop().Return(nil).Once()
linkWatchCh <- &pbresource.WatchEvent{
Event: &pbresource.WatchEvent_Delete_{
Delete: &pbresource.WatchEvent_Delete{},
},
}
// Wait for MonitorHCPLink to return before assertions run
close(linkWatchCh)
wg.Wait()
// Ensure hcp-config directory is removed
file := filepath.Join(dataDir, constants.SubDir)
if _, err := os.Stat(file); err == nil || !os.IsNotExist(err) {
require.Fail(t, "should have removed hcp-config directory")
}
}
func TestMonitorHCPLink_Ok_ReadOnly(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
for name, test := range testCases {
t.Run(name, func(t2 *testing.T) {
mgr := NewMockManager(t2)
linkWatchCh := make(chan *pbresource.WatchEvent)
mgr := NewMockManager(t)
// Set up a link
link := pbhcp.Link{
ResourceId: "abc",
ClientId: "def",
ClientSecret: "ghi",
AccessLevel: pbhcp.AccessLevel_ACCESS_LEVEL_GLOBAL_READ_WRITE,
}
mockHCPClient := hcpclient.NewMockClient(t)
mockHcpClientFn := func(_ config.CloudConfig) (hcpclient.Client, error) {
return mockHCPClient, nil
}
if test.mutateLink != nil {
test.mutateLink(&link)
}
loadMgmtTokenFn := func(ctx context.Context, logger hclog.Logger, hcpClient hcpclient.Client, dataDir string) (string, error) {
return "test-mgmt-token", nil
}
existingManagerCfg := config.CloudConfig{
AuthURL: "test.com",
}
linkResource, err := anypb.New(&link)
require.NoError(t2, err)
var wg sync.WaitGroup
if test.applyMocksAndAssertions != nil {
test.applyMocksAndAssertions(t2, mgr, &link)
}
wg.Add(1)
go func() {
defer wg.Done()
MonitorHCPLink(
ctx, hclog.New(&hclog.LoggerOptions{Output: io.Discard}), mgr, linkWatchCh, mockHcpClientFn,
loadMgmtTokenFn, existingManagerCfg, "",
)
}()
linkWatchCh := make(chan *pbresource.WatchEvent)
// Set up a link with READ_ONLY AccessLevel
// In this case, we don't expect the HCP manager to be updated with any management token
link := pbhcp.Link{
ResourceId: "abc",
ClientId: "def",
ClientSecret: "ghi",
AccessLevel: pbhcp.AccessLevel_ACCESS_LEVEL_GLOBAL_READ_ONLY,
}
expectedCfg := config.CloudConfig{
ResourceID: link.ResourceId,
ClientID: link.ClientId,
ClientSecret: link.ClientSecret,
AuthURL: "test.com",
ManagementToken: "",
}
linkResource, err := anypb.New(&link)
require.NoError(t, err)
// Start MonitorHCPLink
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
MonitorHCPLink(
ctx, hclog.New(&hclog.LoggerOptions{Output: io.Discard}), mgr, linkWatchCh, mockHcpClientFn,
loadMgmtTokenFn, existingCfg, dataDir,
)
}()
// Create link, expect HCP manager to be updated and started
mgr.EXPECT().Start(mock.Anything).Return(nil).Once()
mgr.EXPECT().UpdateConfig(mockHCPClient, expectedCfg)
linkWatchCh <- &pbresource.WatchEvent{
Event: &pbresource.WatchEvent_Upsert_{
Upsert: &pbresource.WatchEvent_Upsert{
upsertEvent := &pbresource.WatchEvent_Upsert{
Resource: &pbresource.Resource{
Id: &pbresource.ID{
Name: "global",
@ -262,11 +156,33 @@ func TestMonitorHCPLink_Ok_ReadOnly(t *testing.T) {
},
Data: linkResource,
},
},
},
}
}
if test.mutateUpsertEvent != nil {
test.mutateUpsertEvent(upsertEvent)
}
linkWatchCh <- &pbresource.WatchEvent{
Event: &pbresource.WatchEvent_Upsert_{
Upsert: upsertEvent,
},
}
// Delete link, expect HCP manager to be stopped
linkWatchCh <- &pbresource.WatchEvent{
Event: &pbresource.WatchEvent_Delete_{
Delete: &pbresource.WatchEvent_Delete{},
},
}
// Wait for MonitorHCPLink to return before assertions run
close(linkWatchCh)
wg.Wait()
// Wait for MonitorHCPLink to return before assertions run
close(linkWatchCh)
wg.Wait()
// Ensure hcp-config directory is removed
file := filepath.Join(dataDir, constants.SubDir)
if _, err := os.Stat(file); err == nil || !os.IsNotExist(err) {
require.Fail(t2, "should have removed hcp-config directory")
}
})
}
}

Loading…
Cancel
Save