Skip to content

Commit e46c64f

Browse files
bendbennettbflad
andauthored
Add Option to use Terraform Configuration in TestStep (#153)
* Adding ConfigDirectory to TestStep (#150) * Add teststep.Config interface so that logic that examines the contents of TestStep.Config or TestStep.Directory can be encapsulated in teststep.config struct (#150) * Update TestStep.Validate() to use teststep.Config interface implementation (#150) * Switching to using a teststep.ConfigurationRequest struct for use in instantiating implementations of teststep.Config (#150) * Refactoring to use type implementing teststep.Config interface (#150) * Refactoring testStepNewImportState() to use type implementing teststep.Config interface for applied configuration (#150) * Switching to using type implementing teststep.Config interface (#150) * Moved TestStep.configHasProviderBlock(), TestStep.configHasTerraformBlock and TestStep.mergedConfig() to configuration.HasProviderBlock(), configuration.hasTerraformBlock and configuration.MergedConfig(), respectively (#150) * Fix validation error message to include ConfigDirectory (#150) * Added testCaseProviderConfig and testStepProviderConfig as fields on configuration struct to simplify processing during GetRaw() and the equivalent function(s) for processing Directory and File (#150) * Add initial implementation of copying files from ConfigDirectory into wd.baseDir (#150) * Switch to using WriteDirectory() method on configuration to make management of writing test case provider config or test step provider config simpler when handling copying of files from configuration.directory (#150) * Adding tests to verify that the ExternalProviders specified in a TestCase or TestStep are being used when TestStep.ConfigDirectory is specified (#150) * Extending implementation of HasProviderBlock() to include detection of provider blocks in configuration files within the configuration directory (#150) * Moving writing of raw config or copy of config directory files internally to configuration struct. (#150) * Removing writing of configuration files for external providers (contained within testCaseProviderConfig and testStepProvider config fields) when processing config directory as the expectation is that external providers will be specified directly in the terraform configuration files within the config directory (#150) * Adding HasConfigurationFiles() func to Config interface to be able to validate that when ConfigDirectory is defined that ExternalProviders cannot be specified for either TestCase or TestStep (#150) * Reinstating TestStep.mergedConfig() method as terraform and provider blocks are only written when using TestStep.Config. The expectation is that when using TestStep.ConfigDirectoy, the terraform files within the configuration directory will specify the terraform and/or provider blocks as necessary (#150) * Adding a couple of tests to verify behaviour when using multiple terraform configuration files in TestStep.ConfigDirectory (#150) * Switching to using TestStepConfigFunc type for TestStep.ConfigDirectory (#150) * Adding acceptance test coverage for StaticDirectory(), TestNameDirectory() and TestStepDirectory() (#150) * Adding Exec() method to TestStepConfigFunc type and removing ExecuteTestStepConfigFunc (#150) * Adding ConfigVariables to allow defining of Terraform variables within a TestStep (#150) * Adding docs for config directory and variables (#150) * Adding tests for TestStepConfigFunc.Exec() method (#150) * Adding tests for config<Type>Variable and Variables.Write() func (#150) * Adding copyright headers (#150) * Unmarshalling before comparing (#150) * Apply suggestions from code review Co-authored-by: Brian Flad <[email protected]> * Adding TestName to TestStepConfigRequest and updating TestStepDirectory() func to use TestName (#150) * Switching to supplying t.Name() to TestStepConfigRequest (#150) * Moving all test fixtures for ConfigDirectory to resource/testdata * Marshalling Variables directly (#150) * Adding comment to explain the usage of Unwrap() (#150) * Adding FloatVariable and IntegerVariable and removing NumberVariable (#150) * Changing ConfigurationRequest fields Directory and Raw to *string to make it clear that they are optional (#150) * Adding Validate() func to ConfigurationRequest along with test coverage (#150) * Adding configurationDirectory and configurationString types (#150) * Configuration() now returns the Config interface to accommodate the different types that could be returned (e.g., configurationDirectory, configurationString) * Renaming raw.go to string.go to match type defined therein (#150) * Adding support for TestStep.ConfigFile field (#150) * Updating docs for config pkg (#150) * Adding documentation into teststep/config.go and tests for exported methods/funcs in teststep/config.go (#150) * Includes refactoring of Configuration func to remove error returned as this was always nil and the returned Config interface needs to be checked for nil in any case. * Adding checks for absolute filepath in configurationDirectory and configurationFile HasProviderBlock, HasTerraformBlock and Write methods (#150) * Adding test coverage for configurationDirectory and configurationFile HasProviderBlock method * Adding tests configurationDirectory, configurationFile and configurationString HasTerraformBlock methods (#150) * Adding test coverage for error conditions and configurationDirectory, configurationFile and configurationString Write methods (#150) * Adding empty dir for tests to git (#150) * Adding a page on usage of Terraform configuration to the website docs (#150) * Adding changelog entries (#150) * Adding test to demonstrate that the TestStep number is being used dynamically to determine the directory containing the Terraform configuration (#150) * Removing unneeded elsif conditional (#150) * Updating docs (#150) * Removing any configuration or variables files from previous test steps prior to copy configuration and variables for current test step (#150) * Updating docs (#150) * Apply suggestions from code review Co-authored-by: Brian Flad <[email protected]> * Update .changes/unreleased/FEATURES-20230728-152822.yaml Co-authored-by: Brian Flad <[email protected]> * Removing unneeded changelog entries (#150) * Reusing stepNumber variable (#150) --------- Co-authored-by: Brian Flad <[email protected]>
1 parent 5eb089d commit e46c64f

File tree

144 files changed

+6262
-209
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

144 files changed

+6262
-209
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
kind: FEATURES
2+
body: 'config: Introduced new `config` package which contains interfaces and helper
3+
functions for working with native Terraform configuration and variables'
4+
time: 2023-07-28T14:38:14.006499+01:00
5+
custom:
6+
Issue: "153"
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
kind: FEATURES
2+
body: 'helper/resource: Added `TestStep.ConfigDirectory` to allow specifying a directory
3+
containing Terraform configuration for use during acceptance tests'
4+
time: 2023-07-28T15:27:37.944964+01:00
5+
custom:
6+
Issue: "153"
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
kind: FEATURES
2+
body: 'helper/resource: Added `TestStep.ConfigFile` to allow specifying a file containing
3+
Terraform configuration for use during acceptance tests'
4+
time: 2023-07-28T15:28:22.204411+01:00
5+
custom:
6+
Issue: "153"
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
kind: FEATURES
2+
body: 'helper/resource: Added `TestStep.ConfigVariables` to allow specifying Terraform variables
3+
for use with Terraform configuration during acceptance tests'
4+
time: 2023-07-28T15:29:17.02183+01:00
5+
custom:
6+
Issue: "153"

config/config.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package config
5+
6+
// TestStepConfigFunc is the callback type used with acceptance tests to
7+
// specify a string which either identifies a directory containing
8+
// Terraform configuration files, or a file that contains Terraform
9+
// configuration.
10+
type TestStepConfigFunc func(TestStepConfigRequest) string
11+
12+
// TestStepConfigRequest defines the request supplied to types
13+
// implementing TestStepConfigFunc. StepNumber is one-based
14+
// and is used in the predefined helper functions:
15+
//
16+
// - [config.TestStepDirectory]
17+
// - [config.TestStepFile].
18+
//
19+
// TestName is used in the predefined helper functions:
20+
//
21+
// - [config.TestNameDirectory]
22+
// - [config.TestStepDirectory]
23+
// - [config.TestNameFile]
24+
// - [config.TestStepFile]
25+
type TestStepConfigRequest struct {
26+
StepNumber int
27+
TestName string
28+
}
29+
30+
// Exec executes TestStepConfigFunc if it is not nil, otherwise an
31+
// empty string is returned.
32+
func (f TestStepConfigFunc) Exec(req TestStepConfigRequest) string {
33+
if f != nil {
34+
return f(req)
35+
}
36+
37+
return ""
38+
}

config/directory.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package config
5+
6+
import (
7+
"path/filepath"
8+
"strconv"
9+
)
10+
11+
// StaticDirectory returns the supplied directory.
12+
func StaticDirectory(directory string) func(TestStepConfigRequest) string {
13+
return func(_ TestStepConfigRequest) string {
14+
return directory
15+
}
16+
}
17+
18+
// TestNameDirectory returns the name of the test prefixed with
19+
// "testdata".
20+
//
21+
// For example, given test code:
22+
//
23+
// func TestExampleCloudThing_basic(t *testing.T) {
24+
// resource.Test(t, resource.TestCase{
25+
// Steps: []resource.TestStep{
26+
// {
27+
// ConfigDirectory: config.TestNameDirectory(),
28+
// },
29+
// },
30+
// })
31+
// }
32+
//
33+
// The testing configurations will be expected in the
34+
// testdata/TestExampleCloudThing_basic/ directory.
35+
func TestNameDirectory() func(TestStepConfigRequest) string {
36+
return func(req TestStepConfigRequest) string {
37+
return filepath.Join("testdata", req.TestName)
38+
}
39+
}
40+
41+
// TestStepDirectory returns the name of the test suffixed with the
42+
// test step number and prefixed with "testdata".
43+
//
44+
// For example, given test code:
45+
//
46+
// func TestExampleCloudThing_basic(t *testing.T) {
47+
// resource.Test(t, resource.TestCase{
48+
// Steps: []resource.TestStep{
49+
// {
50+
// ConfigDirectory: config.TestStepDirectory(),
51+
// },
52+
// },
53+
// })
54+
// }
55+
//
56+
// The testing configurations will be expected in the
57+
// testdata/TestExampleCloudThing_basic/1 directory as
58+
// TestStepConfigRequest.StepNumber is one-based.
59+
func TestStepDirectory() func(TestStepConfigRequest) string {
60+
return func(req TestStepConfigRequest) string {
61+
return filepath.Join("testdata", req.TestName, strconv.Itoa(req.StepNumber))
62+
}
63+
}

config/directory_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package config_test
5+
6+
import (
7+
"testing"
8+
9+
"github.com/hashicorp/terraform-plugin-testing/config"
10+
)
11+
12+
func TestTestStepConfigFunc_Exec_Directory(t *testing.T) {
13+
t.Parallel()
14+
15+
testCases := map[string]struct {
16+
testStepConfigFunc config.TestStepConfigFunc
17+
testStepConfigRequest config.TestStepConfigRequest
18+
expected string
19+
}{
20+
"static_directory": {
21+
testStepConfigFunc: config.StaticDirectory("name_of_directory"),
22+
expected: "name_of_directory",
23+
},
24+
"test_name_directory": {
25+
testStepConfigFunc: config.TestNameDirectory(),
26+
testStepConfigRequest: config.TestStepConfigRequest{
27+
TestName: "TestTestStepConfigFunc_Exec",
28+
},
29+
expected: "testdata/TestTestStepConfigFunc_Exec",
30+
},
31+
"test_step_directory": {
32+
testStepConfigFunc: config.TestStepDirectory(),
33+
testStepConfigRequest: config.TestStepConfigRequest{
34+
StepNumber: 1,
35+
TestName: "TestTestStepConfigFunc_Exec",
36+
},
37+
expected: "testdata/TestTestStepConfigFunc_Exec/1",
38+
},
39+
}
40+
41+
for name, testCase := range testCases {
42+
name, testCase := name, testCase
43+
44+
t.Run(name, func(t *testing.T) {
45+
t.Parallel()
46+
47+
got := testCase.testStepConfigFunc.Exec(testCase.testStepConfigRequest)
48+
49+
if testCase.expected != got {
50+
t.Errorf("expected %s, got %s", testCase.expected, got)
51+
}
52+
})
53+
}
54+
}

config/doc.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
// Package config implements functionality for supporting native
5+
// Terraform configuration and variables for testing purposes.
6+
package config

config/file.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package config
5+
6+
import (
7+
"path/filepath"
8+
"strconv"
9+
)
10+
11+
// StaticFile returns the supplied file.
12+
func StaticFile(file string) func(TestStepConfigRequest) string {
13+
return func(_ TestStepConfigRequest) string {
14+
return file
15+
}
16+
}
17+
18+
// TestNameFile returns the name of the test suffixed with the supplied
19+
// file and prefixed with "testdata".
20+
//
21+
// For example, given test code:
22+
//
23+
// func TestExampleCloudThing_basic(t *testing.T) {
24+
// resource.Test(t, resource.TestCase{
25+
// Steps: []resource.TestStep{
26+
// {
27+
// ConfigFile: config.TestNameFile("test.tf"),
28+
// },
29+
// },
30+
// })
31+
// }
32+
//
33+
// The testing configuration will be expected in the
34+
// testdata/TestExampleCloudThing_basic/test.tf file.
35+
func TestNameFile(file string) func(TestStepConfigRequest) string {
36+
return func(req TestStepConfigRequest) string {
37+
return filepath.Join("testdata", req.TestName, file)
38+
}
39+
}
40+
41+
// TestStepFile returns the name of the test suffixed with the test
42+
// step number and the supplied file, and prefixed with "testdata".
43+
//
44+
// For example, given test code:
45+
//
46+
// func TestExampleCloudThing_basic(t *testing.T) {
47+
// resource.Test(t, resource.TestCase{
48+
// Steps: []resource.TestStep{
49+
// {
50+
// ConfigFile: config.TestStepFile("test.tf"),
51+
// },
52+
// },
53+
// })
54+
// }
55+
//
56+
// The testing configuration will be expected in the
57+
// testdata/TestExampleCloudThing_basic/1/test.tf file
58+
// as TestStepConfigRequest.StepNumber is one-based.
59+
func TestStepFile(file string) func(TestStepConfigRequest) string {
60+
return func(req TestStepConfigRequest) string {
61+
return filepath.Join("testdata", req.TestName, strconv.Itoa(req.StepNumber), file)
62+
}
63+
}

config/file_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Copyright (c) HashiCorp, Inc.
2+
// SPDX-License-Identifier: MPL-2.0
3+
4+
package config_test
5+
6+
import (
7+
"testing"
8+
9+
"github.com/hashicorp/terraform-plugin-testing/config"
10+
)
11+
12+
func TestTestStepConfigFunc_Exec_File(t *testing.T) {
13+
t.Parallel()
14+
15+
testCases := map[string]struct {
16+
testStepConfigFunc config.TestStepConfigFunc
17+
testStepConfigRequest config.TestStepConfigRequest
18+
expected string
19+
}{
20+
"static_file": {
21+
testStepConfigFunc: config.StaticFile("name_of_file"),
22+
expected: "name_of_file",
23+
},
24+
"test_name_file": {
25+
testStepConfigFunc: config.TestNameFile("test.tf"),
26+
testStepConfigRequest: config.TestStepConfigRequest{
27+
TestName: "TestTestStepConfigFunc_Exec",
28+
},
29+
expected: "testdata/TestTestStepConfigFunc_Exec/test.tf",
30+
},
31+
"test_step_file": {
32+
testStepConfigFunc: config.TestStepFile("test.tf"),
33+
testStepConfigRequest: config.TestStepConfigRequest{
34+
StepNumber: 1,
35+
TestName: "TestTestStepConfigFunc_Exec",
36+
},
37+
expected: "testdata/TestTestStepConfigFunc_Exec/1/test.tf",
38+
},
39+
}
40+
41+
for name, testCase := range testCases {
42+
name, testCase := name, testCase
43+
44+
t.Run(name, func(t *testing.T) {
45+
t.Parallel()
46+
47+
got := testCase.testStepConfigFunc.Exec(testCase.testStepConfigRequest)
48+
49+
if testCase.expected != got {
50+
t.Errorf("expected %s, got %s", testCase.expected, got)
51+
}
52+
})
53+
}
54+
}

0 commit comments

Comments
 (0)