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" "github.com/hashicorp/consul/sdk/testutil"
) )
func TestMonitorHCPLink_Ok(t *testing.T) { func TestMonitorHCPLink(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel) t.Cleanup(cancel)
linkWatchCh := make(chan *pbresource.WatchEvent)
mgr := NewMockManager(t)
mockHCPClient := hcpclient.NewMockClient(t) mockHCPClient := hcpclient.NewMockClient(t)
mockHcpClientFn := func(_ config.CloudConfig) (hcpclient.Client, error) { mockHcpClientFn := func(_ config.CloudConfig) (hcpclient.Client, error) {
return mockHCPClient, nil return mockHCPClient, nil
@ -43,29 +40,24 @@ func TestMonitorHCPLink_Ok(t *testing.T) {
} }
dataDir := testutil.TempDir(t, "test-link-controller") 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{ existingCfg := config.CloudConfig{
AuthURL: "test.com", 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) testCases := map[string]testCase{
go func() { // HCP manager should be started when link is created and stopped when link is deleted
defer wg.Done() "Ok": {
MonitorHCPLink( applyMocksAndAssertions: func(t *testing.T, mgr *MockManager, link *pbhcp.Link) {
ctx, hclog.New(&hclog.LoggerOptions{Output: io.Discard}), mgr, linkWatchCh, mockHcpClientFn, mgr.EXPECT().Start(mock.Anything).Return(nil).Once()
loadMgmtTokenFn, existingCfg, dataDir,
)
}()
// Set up a link
link := pbhcp.Link{
ResourceId: "abc",
ClientId: "def",
ClientSecret: "ghi",
AccessLevel: pbhcp.AccessLevel_ACCESS_LEVEL_GLOBAL_READ_WRITE,
}
expectedCfg := config.CloudConfig{ expectedCfg := config.CloudConfig{
ResourceID: link.ResourceId, ResourceID: link.ResourceId,
ClientID: link.ClientId, ClientID: link.ClientId,
@ -73,94 +65,85 @@ func TestMonitorHCPLink_Ok(t *testing.T) {
AuthURL: "test.com", AuthURL: "test.com",
ManagementToken: "test-mgmt-token", ManagementToken: "test-mgmt-token",
} }
linkResource, err := anypb.New(&link)
require.NoError(t, err)
// Create link, expect HCP manager to be updated and started
mgr.EXPECT().Start(mock.Anything).Return(nil).Once()
mgr.EXPECT().UpdateConfig(mockHCPClient, expectedCfg) mgr.EXPECT().UpdateConfig(mockHCPClient, expectedCfg)
linkWatchCh <- &pbresource.WatchEvent{
Event: &pbresource.WatchEvent_Upsert_{ mgr.EXPECT().Stop().Return(nil).Once()
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},
}, },
// HCP manager should not be updated with management token
"ReadOnly": {
mutateLink: func(link *pbhcp.Link) {
link.AccessLevel = pbhcp.AccessLevel_ACCESS_LEVEL_GLOBAL_READ_ONLY
}, },
Data: linkResource, 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()
}, },
}, },
// 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},
}, },
} }
},
// Delete link, expect HCP manager to be stopped 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() 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 for name, test := range testCases {
close(linkWatchCh) t.Run(name, func(t2 *testing.T) {
wg.Wait() mgr := NewMockManager(t2)
// Ensure hcp-config directory is removed // Set up a link
file := filepath.Join(dataDir, constants.SubDir) link := pbhcp.Link{
if _, err := os.Stat(file); err == nil || !os.IsNotExist(err) { ResourceId: "abc",
require.Fail(t, "should have removed hcp-config directory") ClientId: "def",
ClientSecret: "ghi",
AccessLevel: pbhcp.AccessLevel_ACCESS_LEVEL_GLOBAL_READ_WRITE,
} }
}
func TestMonitorHCPLink_ValidationError(t *testing.T) { if test.mutateLink != nil {
ctx, cancel := context.WithCancel(context.Background()) test.mutateLink(&link)
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) { linkResource, err := anypb.New(&link)
return "test-mgmt-token", nil require.NoError(t2, err)
if test.applyMocksAndAssertions != nil {
test.applyMocksAndAssertions(t2, mgr, &link)
} }
dataDir := testutil.TempDir(t, "test-link-controller") linkWatchCh := make(chan *pbresource.WatchEvent)
os.Mkdir(filepath.Join(dataDir, constants.SubDir), os.ModeDir)
// Start MonitorHCPLink
var wg sync.WaitGroup var wg sync.WaitGroup
wg.Add(1) wg.Add(1)
go func() { go func() {
defer wg.Done() defer wg.Done()
MonitorHCPLink( MonitorHCPLink(
ctx, hclog.New(&hclog.LoggerOptions{Output: io.Discard}), mgr, linkWatchCh, mockHcpClientFn, ctx, hclog.New(&hclog.LoggerOptions{Output: io.Discard}), mgr, linkWatchCh, mockHcpClientFn,
loadMgmtTokenFn, config.CloudConfig{}, dataDir, loadMgmtTokenFn, existingCfg, dataDir,
) )
}() }()
// Set up a link upsertEvent := &pbresource.WatchEvent_Upsert{
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{ Resource: &pbresource.Resource{
Id: &pbresource.ID{ Id: &pbresource.ID{
Name: "global", Name: "global",
@ -168,17 +151,23 @@ func TestMonitorHCPLink_ValidationError(t *testing.T) {
}, },
Status: map[string]*pbresource.Status{ Status: map[string]*pbresource.Status{
hcpctl.StatusKey: { hcpctl.StatusKey: {
Conditions: []*pbresource.Condition{hcpctl.ConditionValidatedFailed}, Conditions: []*pbresource.Condition{hcpctl.ConditionValidatedSuccess},
}, },
}, },
Data: linkResource, 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 // Delete link, expect HCP manager to be stopped
mgr.EXPECT().Stop().Return(nil).Once()
linkWatchCh <- &pbresource.WatchEvent{ linkWatchCh <- &pbresource.WatchEvent{
Event: &pbresource.WatchEvent_Delete_{ Event: &pbresource.WatchEvent_Delete_{
Delete: &pbresource.WatchEvent_Delete{}, Delete: &pbresource.WatchEvent_Delete{},
@ -192,81 +181,8 @@ func TestMonitorHCPLink_ValidationError(t *testing.T) {
// Ensure hcp-config directory is removed // Ensure hcp-config directory is removed
file := filepath.Join(dataDir, constants.SubDir) file := filepath.Join(dataDir, constants.SubDir)
if _, err := os.Stat(file); err == nil || !os.IsNotExist(err) { if _, err := os.Stat(file); err == nil || !os.IsNotExist(err) {
require.Fail(t, "should have removed hcp-config directory") require.Fail(t2, "should have removed hcp-config directory")
}
}
func TestMonitorHCPLink_Ok_ReadOnly(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
}
existingManagerCfg := config.CloudConfig{
AuthURL: "test.com",
}
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, existingManagerCfg, "",
)
}()
// 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)
// 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,
},
},
},
}
// Wait for MonitorHCPLink to return before assertions run
close(linkWatchCh)
wg.Wait()
} }

Loading…
Cancel
Save