diff --git a/modules/terraform/errors.go b/modules/terraform/errors.go index d80a8514b..ae0e9a484 100644 --- a/modules/terraform/errors.go +++ b/modules/terraform/errors.go @@ -87,3 +87,17 @@ type PanicWhileParsingVarFile struct { func (err PanicWhileParsingVarFile) Error() string { return fmt.Sprintf("Recovering panic while parsing '%s'. Got error of type '%v': %v", err.ConfigFile, reflect.TypeOf(err.RecoveredValue), err.RecoveredValue) } + +// UnsupportedDefaultWorkspaceDeletion is returned when user tries to delete the workspace "default" +type UnsupportedDefaultWorkspaceDeletion struct{} + +func (err *UnsupportedDefaultWorkspaceDeletion) Error() string { + return "Deleting the workspace 'default' is not supported" +} + +// WorkspaceDoesNotExist is returned when user tries to delete a workspace which does not exist +type WorkspaceDoesNotExist string + +func (err WorkspaceDoesNotExist) Error() string { + return fmt.Sprintf("The workspace %q does not exist.", string(err)) +} diff --git a/modules/terraform/workspace.go b/modules/terraform/workspace.go index ef38f1ffa..92e95dfb5 100644 --- a/modules/terraform/workspace.go +++ b/modules/terraform/workspace.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/gruntwork-io/terratest/modules/testing" + "github.com/stretchr/testify/require" ) // WorkspaceSelectOrNew runs terraform workspace with the given options and the workspace name @@ -66,10 +67,13 @@ func nameMatchesWorkspace(name string, workspace string) bool { // If the workspace to delete is the current one, then it tries to switch to the "default" workspace. // Deleting the workspace "default" is not supported. func WorkspaceDeleteE(t testing.TestingT, options *Options, name string) (string, error) { - currentWorkspace := RunTerraformCommand(t, options, "workspace", "show") + currentWorkspace, err := RunTerraformCommandE(t, options, "workspace", "show") + if err != nil { + return currentWorkspace, err + } if name == "default" { - return currentWorkspace, fmt.Errorf("Deleting the workspace 'default' is not supported") + return currentWorkspace, &UnsupportedDefaultWorkspaceDeletion{} } out, err := RunTerraformCommandE(t, options, "workspace", "list") @@ -77,12 +81,15 @@ func WorkspaceDeleteE(t testing.TestingT, options *Options, name string) (string return currentWorkspace, err } if !isExistingWorkspace(out, name) { - return currentWorkspace, fmt.Errorf("The workspace %q does not exist.", name) + return currentWorkspace, WorkspaceDoesNotExist(name) } // Switch workspace before deleting if it is the current if currentWorkspace == name { - currentWorkspace = WorkspaceSelectOrNew(t, options, "default") + currentWorkspace, err = WorkspaceSelectOrNewE(t, options, "default") + if err != nil { + return currentWorkspace, err + } } // delete workspace diff --git a/modules/terraform/workspace_test.go b/modules/terraform/workspace_test.go index cbca18d4b..3c913c76b 100644 --- a/modules/terraform/workspace_test.go +++ b/modules/terraform/workspace_test.go @@ -5,6 +5,7 @@ import ( "github.com/gruntwork-io/terratest/modules/files" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestWorkspaceNew(t *testing.T) { @@ -131,7 +132,6 @@ func TestNameMatchesWorkspace(t *testing.T) { } } -// Please note that this test depends on other functions that should be mocked to be a unit test. func TestWorkspaceDeleteE(t *testing.T) { t.Parallel() @@ -143,11 +143,11 @@ func TestWorkspaceDeleteE(t *testing.T) { // testCase describes a named test case with a state, args and expcted results type testCase struct { - name string - initialState state - toDeleteWorkspace string - expectedCurrent string - expectedErrorMessage string + name string + initialState state + toDeleteWorkspace string + expectedCurrent string + expectedError error } testCases := []testCase{ @@ -157,9 +157,9 @@ func TestWorkspaceDeleteE(t *testing.T) { workspaces: []string{"staging", "production"}, current: "staging", }, - toDeleteWorkspace: "production", - expectedCurrent: "staging", - expectedErrorMessage: "", + toDeleteWorkspace: "production", + expectedCurrent: "staging", + expectedError: nil, }, { name: "delete current workspace and switch to a specified", @@ -167,9 +167,9 @@ func TestWorkspaceDeleteE(t *testing.T) { workspaces: []string{"staging", "production"}, current: "production", }, - toDeleteWorkspace: "production", - expectedCurrent: "default", - expectedErrorMessage: "", + toDeleteWorkspace: "production", + expectedCurrent: "default", + expectedError: nil, }, { name: "delete a non existing workspace should trigger an error", @@ -177,9 +177,9 @@ func TestWorkspaceDeleteE(t *testing.T) { workspaces: []string{"staging", "production"}, current: "staging", }, - toDeleteWorkspace: "hellothere", - expectedCurrent: "staging", - expectedErrorMessage: "The workspace \"hellothere\" does not exist.", + toDeleteWorkspace: "hellothere", + expectedCurrent: "staging", + expectedError: WorkspaceDoesNotExist("hellothere"), }, { name: "delete the default workspace triggers an error", @@ -187,120 +187,43 @@ func TestWorkspaceDeleteE(t *testing.T) { workspaces: []string{"staging", "production"}, current: "staging", }, - toDeleteWorkspace: "default", - expectedCurrent: "staging", - expectedErrorMessage: "Deleting the workspace 'default' is not supported", + toDeleteWorkspace: "default", + expectedCurrent: "staging", + expectedError: &UnsupportedDefaultWorkspaceDeletion{}, }, } for _, tt := range testCases { - testFolder, err := files.CopyTerraformFolderToTemp("../../test/fixtures/terraform-workspace", tt.name) - if err != nil { - t.Fatal(err) - } - - options := &Options{ - TerraformDir: testFolder, - } - - // Set up pre-existing environment based on test case description - for _, existingWorkspace := range tt.initialState.workspaces { - _, err = RunTerraformCommandE(t, options, "workspace", "new", existingWorkspace) - if err != nil { - t.Fatal(err) - } - } - // Switch to the specified workspace - _, err = RunTerraformCommandE(t, options, "workspace", "select", tt.initialState.current) - if err != nil { - t.Fatal(err) - } - - // Testing time, wooohoooo - gotResult, gotErr := WorkspaceDeleteE(t, options, tt.toDeleteWorkspace) - - // Check for errors - if tt.expectedErrorMessage != "" { - assert.Error(t, gotErr) - assert.Equal(t, tt.expectedErrorMessage, gotErr.Error()) - } else { - assert.Nil(t, gotErr) - // Check for results - assert.Equal(t, tt.expectedCurrent, gotResult) - assert.False(t, isExistingWorkspace(RunTerraformCommand(t, options, "workspace", "list"), tt.toDeleteWorkspace)) - } - - } -} + t.Run(tt.name, func(t *testing.T) { + testFolder, err := files.CopyTerraformFolderToTemp("../../test/fixtures/terraform-workspace", tt.name) + require.NoError(t, err) -// Please note that this test depends on other functions that should be mocked to be a unit test. -func TestWorkspaceDelete(t *testing.T) { - t.Parallel() - - // state describes an expected status when a given testCase begins - type state struct { - workspaces []string - current string - } - - // testCase describes a named test case with a state, args and expcted results - type testCase struct { - name string - initialState state - toDeleteWorkspace string - expectedCurrent string - } - - testCases := []testCase{ - { - name: "delete another existing workspace and stay on current", - initialState: state{ - workspaces: []string{"staging", "production"}, - current: "staging", - }, - toDeleteWorkspace: "production", - expectedCurrent: "staging", - }, - { - name: "delete current workspace and switch to a specified", - initialState: state{ - workspaces: []string{"staging", "production"}, - current: "production", - }, - toDeleteWorkspace: "production", - expectedCurrent: "default", - }, - } + options := &Options{ + TerraformDir: testFolder, + } - for _, tt := range testCases { - testFolder, err := files.CopyTerraformFolderToTemp("../../test/fixtures/terraform-workspace", tt.name) - if err != nil { - t.Fatal(err) - } - - options := &Options{ - TerraformDir: testFolder, - } - - // Set up pre-existing environment based on test case description - for _, existingWorkspace := range tt.initialState.workspaces { - _, err = RunTerraformCommandE(t, options, "workspace", "new", existingWorkspace) - if err != nil { - t.Fatal(err) + // Set up pre-existing environment based on test case description + for _, existingWorkspace := range tt.initialState.workspaces { + _, err = RunTerraformCommandE(t, options, "workspace", "new", existingWorkspace) + require.NoError(t, err) + } + // Switch to the specified workspace + _, err = RunTerraformCommandE(t, options, "workspace", "select", tt.initialState.current) + require.NoError(t, err) + + // Testing time, wooohoooo + gotResult, gotErr := WorkspaceDeleteE(t, options, tt.toDeleteWorkspace) + + // Check for errors + if tt.expectedError != nil { + assert.EqualError(t, gotErr, tt.expectedError.Error()) + } else { + assert.Nil(t, gotErr) + // Check for results + assert.Equal(t, tt.expectedCurrent, gotResult) + assert.False(t, isExistingWorkspace(RunTerraformCommand(t, options, "workspace", "list"), tt.toDeleteWorkspace)) } - } - // Switch to the specified workspace - _, err = RunTerraformCommandE(t, options, "workspace", "select", tt.initialState.current) - if err != nil { - t.Fatal(err) - } - - // Testing time, wooohoooo - gotResult := WorkspaceDelete(t, options, tt.toDeleteWorkspace) - - // Check for results - assert.Equal(t, tt.expectedCurrent, gotResult) - assert.False(t, isExistingWorkspace(RunTerraformCommand(t, options, "workspace", "list"), tt.toDeleteWorkspace)) + }) } }