1- // Copyright (c) HashiCorp, Inc.
1+ //ng Copyright (c) HashiCorp, Inc.
22// SPDX-License-Identifier: MPL-2.0
33
44package plugintest
55
66import (
7+ "bytes"
78 "context"
9+ "encoding/json"
810 "fmt"
911 "io"
1012 "os"
13+ "os/exec"
1114 "path/filepath"
1215
1316 "github.com/hashicorp/terraform-exec/tfexec"
@@ -21,6 +24,7 @@ import (
2124const (
2225 ConfigFileName = "terraform_plugin_test.tf"
2326 PlanFileName = "tfplan"
27+ QueryFileName = "terraform_plugin_test.tfquery.hcl"
2428)
2529
2630// WorkingDir represents a distinct working directory that can be used for
@@ -37,6 +41,10 @@ type WorkingDir struct {
3741 // was stored; empty until SetConfig is called.
3842 configFilename string
3943
44+ // queryFilename is the full filename where the latest query configuration
45+ // was stored; empty until SetQuery is called.
46+ queryFilename string
47+
4048 // tf is the instance of tfexec.Terraform used for running Terraform commands
4149 tf * tfexec.Terraform
4250
@@ -101,7 +109,7 @@ func (wd *WorkingDir) SetConfig(ctx context.Context, cfg teststep.Config, vars c
101109
102110 for _ , file := range fi {
103111 if file .Mode ().IsRegular () {
104- if filepath .Ext (file .Name ()) == ".tf" || filepath .Ext (file .Name ()) == ".json" {
112+ if filepath .Ext (file .Name ()) == ".tf" || filepath .Ext (file .Name ()) == ".json" || filepath . Ext ( file . Name ()) == ".hcl" {
105113 err = os .Remove (filepath .Join (d .Name (), file .Name ()))
106114
107115 if err != nil && ! os .IsNotExist (err ) {
@@ -151,6 +159,80 @@ func (wd *WorkingDir) SetConfig(ctx context.Context, cfg teststep.Config, vars c
151159 return nil
152160}
153161
162+ // SetQuery sets a new query configuration for the working directory.
163+ //
164+ // This must be called at least once before any call to Init or Query Destroy
165+ // to establish the query configuration. Any previously-set configuration is
166+ // discarded and any saved plan is cleared.
167+ func (wd * WorkingDir ) SetQuery (ctx context.Context , cfg teststep.Config , vars config.Variables ) error {
168+ // Remove old config and variables files first
169+ d , err := os .Open (wd .baseDir )
170+
171+ if err != nil {
172+ return err
173+ }
174+
175+ defer d .Close ()
176+
177+ fi , err := d .Readdir (- 1 )
178+
179+ if err != nil {
180+ return err
181+ }
182+
183+ for _ , file := range fi {
184+ if file .Mode ().IsRegular () {
185+ if filepath .Ext (file .Name ()) == ".warioform" || filepath .Ext (file .Name ()) == ".json" || filepath .Ext (file .Name ()) == ".hcl" {
186+ err = os .Remove (filepath .Join (d .Name (), file .Name ()))
187+
188+ if err != nil && ! os .IsNotExist (err ) {
189+ return err
190+ }
191+ }
192+ }
193+ }
194+
195+ logging .HelperResourceTrace (ctx , "Setting Terraform query configuration" , map [string ]any {logging .KeyTestTerraformConfiguration : cfg })
196+
197+ outFilename := filepath .Join (wd .baseDir , QueryFileName )
198+
199+ // This file has to be written otherwise wd.Init() will return an error.
200+ err = os .WriteFile (outFilename , nil , 0700 )
201+
202+ if err != nil {
203+ return err
204+ }
205+
206+ // wd.configFilename must be set otherwise wd.Init() will return an error.
207+ wd .queryFilename = outFilename
208+ wd .configFilename = outFilename
209+
210+ // Write configuration
211+ if cfg != nil {
212+ err = cfg .WriteQuery (ctx , wd .baseDir )
213+
214+ if err != nil {
215+ return err
216+ }
217+ }
218+
219+ //Write configuration variables
220+ err = vars .Write (wd .baseDir )
221+
222+ if err != nil {
223+ return err
224+ }
225+
226+ // Changing configuration invalidates any saved plan.
227+ err = wd .ClearPlan (ctx )
228+
229+ if err != nil {
230+ return err
231+ }
232+
233+ return nil
234+ }
235+
154236// ClearState deletes any Terraform state present in the working directory.
155237//
156238// Any remote objects tracked by the state are not destroyed first, so this
@@ -444,3 +526,38 @@ func (wd *WorkingDir) Schemas(ctx context.Context) (*tfjson.ProviderSchemas, err
444526
445527 return providerSchemas , err
446528}
529+
530+ func (wd * WorkingDir ) Query (ctx context.Context ) ([]string , error ) {
531+ logging .HelperResourceTrace (ctx , "Calling Terraform CLI providers query command" )
532+
533+ var reattachStr string
534+ if wd .reattachInfo != nil {
535+ reattachJson , err := json .Marshal (wd .reattachInfo )
536+ if err != nil {
537+ return nil , fmt .Errorf ("error marshaling reattach info: %w" , err )
538+ }
539+ reattachStr = string (reattachJson )
540+ }
541+
542+ buffer := & bytes.Buffer {}
543+ errBuffer := & bytes.Buffer {}
544+ cmd := exec .CommandContext (ctx , wd .terraformExec , "query" , "-json" )
545+ cmd .Dir = wd .baseDir
546+ cmd .Stdout = buffer
547+ cmd .Stderr = errBuffer
548+ cmd .Env = os .Environ ()
549+ fmt .Println ("Reattach info: " , reattachStr )
550+ cmd .Env = append (cmd .Env , "TF_REATTACH_PROVIDERS=" + reattachStr )
551+
552+ err := cmd .Run ()
553+ if err != nil {
554+ output := buffer .String () + "\n \n " + errBuffer .String ()
555+ fmt .Println (output )
556+ return nil , fmt .Errorf ("error running terraform query command: %w" , err )
557+ }
558+
559+ logging .HelperResourceTrace (ctx , "Called Terraform CLI providers query command" )
560+
561+ output := buffer .String ()
562+ return []string {output }, nil
563+ }
0 commit comments