diff --git a/CHANGELOG.md b/CHANGELOG.md index 89fdfe0839d..19835d10c59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +ENHANCEMENTS + +* `helper/resource.TestStep` now has a `ConfigIsJSON` bool flag that allows tests to use configuration in the JSON syntax. ([#721](https://github.com/hashicorp/terraform-plugin-sdk/issues/721)) + # 2.4.4 (February 24, 2021) NOTES diff --git a/helper/resource/testing.go b/helper/resource/testing.go index fc9644b371b..4aa68aa01b3 100644 --- a/helper/resource/testing.go +++ b/helper/resource/testing.go @@ -398,7 +398,11 @@ type TestStep struct { // Config a string of the configuration to give to Terraform. If this // is set, then the TestCase will execute this step with the same logic // as a `terraform apply`. - Config string + // + // ConfigIsJSON, if true, will assume that the configuration in Config, + // if any, uses the JSON syntax rather than the native syntax. + Config string + ConfigIsJSON bool // Check is called after the Config is applied. Use this step to // make your own API calls to check the status of things, and to diff --git a/helper/resource/testing_new.go b/helper/resource/testing_new.go index c9d90dd2159..683aa880831 100644 --- a/helper/resource/testing_new.go +++ b/helper/resource/testing_new.go @@ -72,6 +72,7 @@ func runNewTest(t testing.T, c TestCase, helper *plugintest.Helper) { t.Fatal(err) } + wd.SetConfigIsJSON(false) err = wd.SetConfig(providerCfg) if err != nil { t.Fatalf("Error setting test config: %s", err) @@ -196,11 +197,13 @@ func testIDRefresh(c TestCase, t testing.T, wd *plugintest.WorkingDir, step Test if err != nil { return err } + wd.SetConfigIsJSON(false) err = wd.SetConfig(cfg) if err != nil { t.Fatalf("Error setting import test config: %s", err) } defer func() { + wd.SetConfigIsJSON(step.ConfigIsJSON) err = wd.SetConfig(step.Config) if err != nil { t.Fatalf("Error resetting test config: %s", err) diff --git a/helper/resource/testing_new_config.go b/helper/resource/testing_new_config.go index 0e218f60217..ef1faa51147 100644 --- a/helper/resource/testing_new_config.go +++ b/helper/resource/testing_new_config.go @@ -35,6 +35,7 @@ func testStepNewConfig(t testing.T, c TestCase, wd *plugintest.WorkingDir, step } } + wd.SetConfigIsJSON(step.ConfigIsJSON) err := wd.SetConfig(step.Config) if err != nil { return fmt.Errorf("Error setting config: %w", err) diff --git a/helper/resource/testing_new_import_state.go b/helper/resource/testing_new_import_state.go index 52487ad85cb..8df732811c4 100644 --- a/helper/resource/testing_new_import_state.go +++ b/helper/resource/testing_new_import_state.go @@ -64,6 +64,7 @@ func testStepNewImportState(t testing.T, c TestCase, helper *plugintest.Helper, } importWd := helper.RequireNewWorkingDir(t) defer importWd.Close() + importWd.SetConfigIsJSON(step.ConfigIsJSON) err = importWd.SetConfig(step.Config) if err != nil { t.Fatalf("Error setting test config: %s", err) diff --git a/internal/plugintest/working_dir.go b/internal/plugintest/working_dir.go index 1faeb5c7a71..50be16a6dad 100644 --- a/internal/plugintest/working_dir.go +++ b/internal/plugintest/working_dir.go @@ -14,8 +14,9 @@ import ( ) const ( - ConfigFileName = "terraform_plugin_test.tf" - PlanFileName = "tfplan" + ConfigFileNameNative = "terraform_plugin_test.tf" + ConfigFileNameJSON = ConfigFileNameNative + ".json" + PlanFileName = "tfplan" ) // WorkingDir represents a distinct working directory that can be used for @@ -42,6 +43,11 @@ type WorkingDir struct { reattachInfo tfexec.ReattachInfo env map[string]string + + // configIsJSON is a flag that affects the assumed syntax of the + // configuration passed to SetConfig. If true, SetConfig assumes the + // configuration is in the JSON syntax rather than the native syntax. + configIsJSON bool } // Close deletes the directories and files created to represent the receiving @@ -77,14 +83,26 @@ func (wd *WorkingDir) GetHelper() *Helper { return wd.h } +// SetConfigIsJSON sets the configIsJSON flag, which affects all subsequent +// calls to SetConfig. +func (wd *WorkingDir) SetConfigIsJSON(configIsJSON bool) { + wd.configIsJSON = configIsJSON +} + // SetConfig sets a new configuration for the working directory. // // This must be called at least once before any call to Init, Plan, Apply, or // Destroy to establish the configuration. Any previously-set configuration is // discarded and any saved plan is cleared. +// +// The assumed syntax of the configuration can be changed by calling +// SetConfigIsJSON prior to calling SetConfig. func (wd *WorkingDir) SetConfig(cfg string) error { - configFilename := filepath.Join(wd.baseDir, ConfigFileName) - err := ioutil.WriteFile(configFilename, []byte(cfg), 0700) + err := os.Remove(wd.configFilename(!wd.configIsJSON)) + if err != nil && !errors.Is(err, os.ErrNotExist) { + return err + } + err = ioutil.WriteFile(wd.configFilename(wd.configIsJSON), []byte(cfg), 0700) if err != nil { return err } @@ -135,15 +153,19 @@ func (wd *WorkingDir) ClearPlan() error { // Init runs "terraform init" for the given working directory, forcing Terraform // to use the current version of the plugin under test. func (wd *WorkingDir) Init() error { - if _, err := os.Stat(wd.configFilename()); err != nil { + if _, err := os.Stat(wd.configFilename(wd.configIsJSON)); err != nil { return fmt.Errorf("must call SetConfig before Init") } return wd.tf.Init(context.Background(), tfexec.Reattach(wd.reattachInfo)) } -func (wd *WorkingDir) configFilename() string { - return filepath.Join(wd.baseDir, ConfigFileName) +func (wd *WorkingDir) configFilename(configIsJson bool) string { + if configIsJson { + return filepath.Join(wd.baseDir, ConfigFileNameJSON) + } else { + return filepath.Join(wd.baseDir, ConfigFileNameNative) + } } func (wd *WorkingDir) planFilename() string {