Codebase list golang-github-hashicorp-terraform-plugin-test-upstream / 47eadad
remove individual config dirs The test framework no longer creates a wd.configDir whenever new test config is set. This change simplifies the test directory structure and allows state to persist from one test step to the next, a fundamental assumption of the test framework. Katy Moe 3 years ago
2 changed file(s) with 37 addition(s) and 47 deletion(s). Raw diff Collapse all Expand all
88 "strings"
99
1010 getter "github.com/hashicorp/go-getter"
11 "github.com/hashicorp/terraform-exec/tfexec"
1112 )
1213
1314 const subprocessCurrentSigil = "4acd63807899403ca4859f5bb948d2c6"
186187 return nil, err
187188 }
188189
190 // symlink the provider source files into the config directory
191 // e.g. testdata
192 err = symlinkDirectoriesOnly(h.sourceDir, dir)
193 if err != nil {
194 return nil, err
195 }
196
197 tf, err := tfexec.NewTerraform(dir, h.terraformExec)
198 if err != nil {
199 return nil, err
200 }
201
189202 return &WorkingDir{
190203 h: h,
204 tf: tf,
191205 baseDir: dir,
192206 terraformExec: h.terraformExec,
193207 }, nil
1212 tfjson "github.com/hashicorp/terraform-json"
1313 )
1414
15 const (
16 ConfigFileName = "terraform_plugin_test.tf"
17 PlanFileName = "tfplan"
18 )
19
1520 // WorkingDir represents a distinct working directory that can be used for
1621 // running tests. Each test should construct its own WorkingDir by calling
1722 // NewWorkingDir or RequireNewWorkingDir on its package's singleton
2530 // baseArgs is arguments that should be appended to all commands
2631 baseArgs []string
2732
28 // configDir contains the singular config file generated for each test
29 configDir string
30
3133 // tf is the instance of tfexec.Terraform used for running Terraform commands
3234 tf *tfexec.Terraform
3335
7476 return wd.h
7577 }
7678
77 func (wd *WorkingDir) relativeConfigDir() (string, error) {
78 relPath, err := filepath.Rel(wd.baseDir, wd.configDir)
79 if err != nil {
80 return "", fmt.Errorf("Error determining relative path of configuration directory: %w", err)
81 }
82 return relPath, nil
83 }
84
8579 // SetConfig sets a new configuration for the working directory.
8680 //
8781 // This must be called at least once before any call to Init, Plan, Apply, or
8882 // Destroy to establish the configuration. Any previously-set configuration is
8983 // discarded and any saved plan is cleared.
9084 func (wd *WorkingDir) SetConfig(cfg string) error {
91 // Each call to SetConfig creates a new directory under our baseDir.
92 // We create them within so that our final cleanup step will delete them
93 // automatically without any additional tracking.
94 configDir, err := ioutil.TempDir(wd.baseDir, "config")
85 configFilename := filepath.Join(wd.baseDir, ConfigFileName)
86 err := ioutil.WriteFile(configFilename, []byte(cfg), 0700)
9587 if err != nil {
9688 return err
9789 }
98 configFilename := filepath.Join(configDir, "terraform_plugin_test.tf")
99 err = ioutil.WriteFile(configFilename, []byte(cfg), 0700)
100 if err != nil {
101 return err
102 }
103
104 // symlink the provider source files into the config directory
105 // e.g. testdata
106 err = symlinkDirectoriesOnly(wd.h.sourceDir, configDir)
107 if err != nil {
108 return err
109 }
110
111 tf, err := tfexec.NewTerraform(configDir, wd.terraformExec)
112 if err != nil {
113 return err
114 }
11590
11691 var mismatch *tfexec.ErrVersionMismatch
117 err = tf.SetDisablePluginTLS(true)
92 err = wd.tf.SetDisablePluginTLS(true)
11893 if err != nil && !errors.As(err, &mismatch) {
11994 return err
12095 }
121 err = tf.SetSkipProviderVerify(true)
96 err = wd.tf.SetSkipProviderVerify(true)
12297 if err != nil && !errors.As(err, &mismatch) {
12398 return err
12499 }
125100
126101 if p := os.Getenv("TF_ACC_LOG_PATH"); p != "" {
127 tf.SetLogPath(p)
128 }
129
130 wd.configDir = configDir
131 wd.tf = tf
102 wd.tf.SetLogPath(p)
103 }
132104
133105 // Changing configuration invalidates any saved plan.
134106 err = wd.ClearPlan()
153125 // Any remote objects tracked by the state are not destroyed first, so this
154126 // will leave them dangling in the remote system.
155127 func (wd *WorkingDir) ClearState() error {
156 err := os.Remove(filepath.Join(wd.configDir, "terraform.tfstate"))
128 err := os.Remove(filepath.Join(wd.baseDir, "terraform.tfstate"))
157129 if os.IsNotExist(err) {
158130 return nil
159131 }
192164 // Init runs "terraform init" for the given working directory, forcing Terraform
193165 // to use the current version of the plugin under test.
194166 func (wd *WorkingDir) Init() error {
195 if wd.configDir == "" {
167 if _, err := os.Stat(wd.configFilename()); err != nil {
196168 return fmt.Errorf("must call SetConfig before Init")
197169 }
198170
199171 return wd.tf.Init(context.Background(), tfexec.Reattach(wd.reattachInfo))
172 }
173
174 func (wd *WorkingDir) configFilename() string {
175 return filepath.Join(wd.baseDir, ConfigFileName)
200176 }
201177
202178 // RequireInit is a variant of Init that will fail the test via the given
210186 }
211187
212188 func (wd *WorkingDir) planFilename() string {
213 return filepath.Join(wd.configDir, "tfplan")
189 return filepath.Join(wd.baseDir, PlanFileName)
214190 }
215191
216192 // CreatePlan runs "terraform plan" to create a saved plan file, which if successful
217193 // will then be used for the next call to Apply.
218194 func (wd *WorkingDir) CreatePlan() error {
219 _, err := wd.tf.Plan(context.Background(), tfexec.Reattach(wd.reattachInfo), tfexec.Refresh(false), tfexec.Out("tfplan"))
195 _, err := wd.tf.Plan(context.Background(), tfexec.Reattach(wd.reattachInfo), tfexec.Refresh(false), tfexec.Out(PlanFileName))
220196 return err
221197 }
222198
233209 // CreateDestroyPlan runs "terraform plan -destroy" to create a saved plan
234210 // file, which if successful will then be used for the next call to Apply.
235211 func (wd *WorkingDir) CreateDestroyPlan() error {
236 _, err := wd.tf.Plan(context.Background(), tfexec.Reattach(wd.reattachInfo), tfexec.Refresh(false), tfexec.Out("tfplan"), tfexec.Destroy(true))
212 _, err := wd.tf.Plan(context.Background(), tfexec.Reattach(wd.reattachInfo), tfexec.Refresh(false), tfexec.Out(PlanFileName), tfexec.Destroy(true))
237213 return err
238214 }
239215
244220 func (wd *WorkingDir) Apply() error {
245221 args := []tfexec.ApplyOption{tfexec.Reattach(wd.reattachInfo), tfexec.Refresh(false)}
246222 if wd.HasSavedPlan() {
247 args = append(args, tfexec.DirOrPlan("tfplan"))
223 args = append(args, tfexec.DirOrPlan(PlanFileName))
248224 }
249225
250226 return wd.tf.Apply(context.Background(), args...)
368344
369345 // Import runs terraform import
370346 func (wd *WorkingDir) Import(resource, id string) error {
371 return wd.tf.Import(context.Background(), resource, id, tfexec.Config(wd.configDir), tfexec.Reattach(wd.reattachInfo))
347 return wd.tf.Import(context.Background(), resource, id, tfexec.Config(wd.baseDir), tfexec.Reattach(wd.reattachInfo))
372348 }
373349
374350 // RequireImport is a variant of Import that will fail the test via
383359
384360 // Refresh runs terraform refresh
385361 func (wd *WorkingDir) Refresh() error {
386 return wd.tf.Refresh(context.Background(), tfexec.Reattach(wd.reattachInfo), tfexec.State(filepath.Join(wd.configDir, "terraform.tfstate")))
362 return wd.tf.Refresh(context.Background(), tfexec.Reattach(wd.reattachInfo), tfexec.State(filepath.Join(wd.baseDir, "terraform.tfstate")))
387363 }
388364
389365 // RequireRefresh is a variant of Refresh that will fail the test via