github.com/hashicorp/terraform-plugin-sdk@v1.17.2/terraform/terraform_test.go (about)

     1  package terraform
     2  
     3  import (
     4  	"flag"
     5  	"io"
     6  	"io/ioutil"
     7  	"log"
     8  	"os"
     9  	"path/filepath"
    10  	"strings"
    11  	"sync"
    12  	"testing"
    13  
    14  	"github.com/davecgh/go-spew/spew"
    15  	"github.com/zclconf/go-cty/cty"
    16  	"github.com/zclconf/go-cty/cty/convert"
    17  
    18  	"github.com/hashicorp/terraform-plugin-sdk/helper/logging"
    19  	"github.com/hashicorp/terraform-plugin-sdk/internal/addrs"
    20  	"github.com/hashicorp/terraform-plugin-sdk/internal/configs"
    21  	"github.com/hashicorp/terraform-plugin-sdk/internal/configs/configload"
    22  	"github.com/hashicorp/terraform-plugin-sdk/internal/helper/experiment"
    23  	"github.com/hashicorp/terraform-plugin-sdk/internal/initwd"
    24  	"github.com/hashicorp/terraform-plugin-sdk/internal/plans"
    25  	"github.com/hashicorp/terraform-plugin-sdk/internal/providers"
    26  	"github.com/hashicorp/terraform-plugin-sdk/internal/provisioners"
    27  	"github.com/hashicorp/terraform-plugin-sdk/internal/registry"
    28  	"github.com/hashicorp/terraform-plugin-sdk/internal/states"
    29  )
    30  
    31  // This is the directory where our test fixtures are.
    32  const fixtureDir = "./testdata"
    33  
    34  func TestMain(m *testing.M) {
    35  	// We want to shadow on tests just to make sure the shadow graph works
    36  	// in case we need it and to find any race issues.
    37  	experiment.SetEnabled(experiment.X_shadow, true)
    38  
    39  	experiment.Flag(flag.CommandLine)
    40  	flag.Parse()
    41  
    42  	if testing.Verbose() {
    43  		// if we're verbose, use the logging requested by TF_LOG
    44  		logging.SetOutput()
    45  	} else {
    46  		// otherwise silence all logs
    47  		log.SetOutput(ioutil.Discard)
    48  	}
    49  
    50  	// We have fmt.Stringer implementations on lots of objects that hide
    51  	// details that we very often want to see in tests, so we just disable
    52  	// spew's use of String methods globally on the assumption that spew
    53  	// usage implies an intent to see the raw values and ignore any
    54  	// abstractions.
    55  	spew.Config.DisableMethods = true
    56  
    57  	os.Exit(m.Run())
    58  }
    59  
    60  func testModule(t *testing.T, name string) *configs.Config {
    61  	t.Helper()
    62  	c, _ := testModuleWithSnapshot(t, name)
    63  	return c
    64  }
    65  
    66  func testModuleWithSnapshot(t *testing.T, name string) (*configs.Config, *configload.Snapshot) {
    67  	t.Helper()
    68  
    69  	dir := filepath.Join(fixtureDir, name)
    70  	// FIXME: We're not dealing with the cleanup function here because
    71  	// this testModule function is used all over and so we don't want to
    72  	// change its interface at this late stage.
    73  	loader, _ := configload.NewLoaderForTests(t)
    74  
    75  	// Test modules usually do not refer to remote sources, and for local
    76  	// sources only this ultimately just records all of the module paths
    77  	// in a JSON file so that we can load them below.
    78  	inst := initwd.NewModuleInstaller(loader.ModulesDir(), registry.NewClient(nil, nil))
    79  	_, instDiags := inst.InstallModules(dir, true, initwd.ModuleInstallHooksImpl{})
    80  	if instDiags.HasErrors() {
    81  		t.Fatal(instDiags.Err())
    82  	}
    83  
    84  	// Since module installer has modified the module manifest on disk, we need
    85  	// to refresh the cache of it in the loader.
    86  	if err := loader.RefreshModules(); err != nil {
    87  		t.Fatalf("failed to refresh modules after installation: %s", err)
    88  	}
    89  
    90  	config, snap, diags := loader.LoadConfigWithSnapshot(dir)
    91  	if diags.HasErrors() {
    92  		t.Fatal(diags.Error())
    93  	}
    94  
    95  	return config, snap
    96  }
    97  
    98  // testModuleInline takes a map of path -> config strings and yields a config
    99  // structure with those files loaded from disk
   100  func testModuleInline(t *testing.T, sources map[string]string) *configs.Config {
   101  	t.Helper()
   102  
   103  	cfgPath, err := ioutil.TempDir("", "tf-test")
   104  	if err != nil {
   105  		t.Errorf("Error creating temporary directory for config: %s", err)
   106  	}
   107  	defer os.RemoveAll(cfgPath)
   108  
   109  	for path, configStr := range sources {
   110  		dir := filepath.Dir(path)
   111  		if dir != "." {
   112  			err := os.MkdirAll(filepath.Join(cfgPath, dir), os.FileMode(0777))
   113  			if err != nil {
   114  				t.Fatalf("Error creating subdir: %s", err)
   115  			}
   116  		}
   117  		// Write the configuration
   118  		cfgF, err := os.Create(filepath.Join(cfgPath, path))
   119  		if err != nil {
   120  			t.Fatalf("Error creating temporary file for config: %s", err)
   121  		}
   122  
   123  		_, err = io.Copy(cfgF, strings.NewReader(configStr))
   124  		cfgF.Close()
   125  		if err != nil {
   126  			t.Fatalf("Error creating temporary file for config: %s", err)
   127  		}
   128  	}
   129  
   130  	loader, cleanup := configload.NewLoaderForTests(t)
   131  	defer cleanup()
   132  
   133  	// Test modules usually do not refer to remote sources, and for local
   134  	// sources only this ultimately just records all of the module paths
   135  	// in a JSON file so that we can load them below.
   136  	inst := initwd.NewModuleInstaller(loader.ModulesDir(), registry.NewClient(nil, nil))
   137  	_, instDiags := inst.InstallModules(cfgPath, true, initwd.ModuleInstallHooksImpl{})
   138  	if instDiags.HasErrors() {
   139  		t.Fatal(instDiags.Err())
   140  	}
   141  
   142  	// Since module installer has modified the module manifest on disk, we need
   143  	// to refresh the cache of it in the loader.
   144  	if err := loader.RefreshModules(); err != nil {
   145  		t.Fatalf("failed to refresh modules after installation: %s", err)
   146  	}
   147  
   148  	config, diags := loader.LoadConfig(cfgPath)
   149  	if diags.HasErrors() {
   150  		t.Fatal(diags.Error())
   151  	}
   152  
   153  	return config
   154  }
   155  
   156  func testProviderFuncFixed(rp providers.Interface) providers.Factory {
   157  	return func() (providers.Interface, error) {
   158  		return rp, nil
   159  	}
   160  }
   161  
   162  func testProvisionerFuncFixed(rp provisioners.Interface) ProvisionerFactory {
   163  	return func() (provisioners.Interface, error) {
   164  		return rp, nil
   165  	}
   166  }
   167  
   168  func mustResourceInstanceAddr(s string) addrs.AbsResourceInstance {
   169  	addr, diags := addrs.ParseAbsResourceInstanceStr(s)
   170  	if diags.HasErrors() {
   171  		panic(diags.Err())
   172  	}
   173  	return addr
   174  }
   175  
   176  func instanceObjectIdForTests(obj *states.ResourceInstanceObject) string {
   177  	v := obj.Value
   178  	if v.IsNull() || !v.IsKnown() {
   179  		return ""
   180  	}
   181  	idVal := v.GetAttr("id")
   182  	if idVal.IsNull() || !idVal.IsKnown() {
   183  		return ""
   184  	}
   185  	idVal, err := convert.Convert(idVal, cty.String)
   186  	if err != nil {
   187  		return "<invalid>" // placeholder value
   188  	}
   189  	return idVal.AsString()
   190  }
   191  
   192  // HookRecordApplyOrder is a test hook that records the order of applies
   193  // by recording the PreApply event.
   194  type HookRecordApplyOrder struct {
   195  	NilHook
   196  
   197  	Active bool
   198  
   199  	IDs    []string
   200  	States []cty.Value
   201  	Diffs  []*plans.Change
   202  
   203  	l sync.Mutex
   204  }
   205  
   206  func (h *HookRecordApplyOrder) PreApply(addr addrs.AbsResourceInstance, gen states.Generation, action plans.Action, priorState, plannedNewState cty.Value) (HookAction, error) {
   207  	if plannedNewState.RawEquals(priorState) {
   208  		return HookActionContinue, nil
   209  	}
   210  
   211  	if h.Active {
   212  		h.l.Lock()
   213  		defer h.l.Unlock()
   214  
   215  		h.IDs = append(h.IDs, addr.String())
   216  		h.Diffs = append(h.Diffs, &plans.Change{
   217  			Action: action,
   218  			Before: priorState,
   219  			After:  plannedNewState,
   220  		})
   221  		h.States = append(h.States, priorState)
   222  	}
   223  
   224  	return HookActionContinue, nil
   225  }
   226  
   227  // Below are all the constant strings that are the expected output for
   228  // various tests.
   229  
   230  const testTerraformInputProviderOnlyStr = `
   231  aws_instance.foo:
   232    ID = foo
   233    provider = provider.aws
   234    foo = us-west-2
   235    type = aws_instance
   236  `
   237  
   238  const testTerraformInputVarOnlyStr = `
   239  aws_instance.foo:
   240    ID = foo
   241    provider = provider.aws
   242    foo = us-east-1
   243    type = aws_instance
   244  `
   245  
   246  const testTerraformInputVarOnlyUnsetStr = `
   247  aws_instance.foo:
   248    ID = foo
   249    provider = provider.aws
   250    bar = baz
   251    foo = foovalue
   252    type = aws_instance
   253  `
   254  
   255  const testTerraformInputVarsStr = `
   256  aws_instance.bar:
   257    ID = foo
   258    provider = provider.aws
   259    bar = override
   260    foo = us-east-1
   261    type = aws_instance
   262  aws_instance.foo:
   263    ID = foo
   264    provider = provider.aws
   265    bar = baz
   266    num = 2
   267    type = aws_instance
   268  `
   269  
   270  const testTerraformApplyStr = `
   271  aws_instance.bar:
   272    ID = foo
   273    provider = provider.aws
   274    foo = bar
   275    type = aws_instance
   276  aws_instance.foo:
   277    ID = foo
   278    provider = provider.aws
   279    num = 2
   280    type = aws_instance
   281  `
   282  
   283  const testTerraformApplyDataBasicStr = `
   284  data.null_data_source.testing:
   285    ID = yo
   286    provider = provider.null
   287  `
   288  
   289  const testTerraformApplyRefCountStr = `
   290  aws_instance.bar:
   291    ID = foo
   292    provider = provider.aws
   293    foo = 3
   294    type = aws_instance
   295  
   296    Dependencies:
   297      aws_instance.foo
   298  aws_instance.foo.0:
   299    ID = foo
   300    provider = provider.aws
   301  aws_instance.foo.1:
   302    ID = foo
   303    provider = provider.aws
   304  aws_instance.foo.2:
   305    ID = foo
   306    provider = provider.aws
   307  `
   308  
   309  const testTerraformApplyProviderAliasStr = `
   310  aws_instance.bar:
   311    ID = foo
   312    provider = provider.aws.bar
   313    foo = bar
   314    type = aws_instance
   315  aws_instance.foo:
   316    ID = foo
   317    provider = provider.aws
   318    num = 2
   319    type = aws_instance
   320  `
   321  
   322  const testTerraformApplyProviderAliasConfigStr = `
   323  another_instance.bar:
   324    ID = foo
   325    provider = provider.another.two
   326  another_instance.foo:
   327    ID = foo
   328    provider = provider.another
   329  `
   330  
   331  const testTerraformApplyEmptyModuleStr = `
   332  <no state>
   333  Outputs:
   334  
   335  end = XXXX
   336  
   337  module.child:
   338  <no state>
   339  Outputs:
   340  
   341  aws_access_key = YYYYY
   342  aws_route53_zone_id = XXXX
   343  aws_secret_key = ZZZZ
   344  `
   345  
   346  const testTerraformApplyDependsCreateBeforeStr = `
   347  aws_instance.lb:
   348    ID = baz
   349    provider = provider.aws
   350    instance = foo
   351    type = aws_instance
   352  
   353    Dependencies:
   354      aws_instance.web
   355  aws_instance.web:
   356    ID = foo
   357    provider = provider.aws
   358    require_new = ami-new
   359    type = aws_instance
   360  `
   361  
   362  const testTerraformApplyCreateBeforeStr = `
   363  aws_instance.bar:
   364    ID = foo
   365    provider = provider.aws
   366    require_new = xyz
   367    type = aws_instance
   368  `
   369  
   370  const testTerraformApplyCreateBeforeUpdateStr = `
   371  aws_instance.bar:
   372    ID = bar
   373    provider = provider.aws
   374    foo = baz
   375    type = aws_instance
   376  `
   377  
   378  const testTerraformApplyCancelStr = `
   379  aws_instance.foo:
   380    ID = foo
   381    provider = provider.aws
   382    value = 2
   383  `
   384  
   385  const testTerraformApplyComputeStr = `
   386  aws_instance.bar:
   387    ID = foo
   388    provider = provider.aws
   389    foo = computed_value
   390    type = aws_instance
   391  
   392    Dependencies:
   393      aws_instance.foo
   394  aws_instance.foo:
   395    ID = foo
   396    provider = provider.aws
   397    compute = value
   398    compute_value = 1
   399    num = 2
   400    type = aws_instance
   401    value = computed_value
   402  `
   403  
   404  const testTerraformApplyCountDecStr = `
   405  aws_instance.bar:
   406    ID = foo
   407    provider = provider.aws
   408    foo = bar
   409    type = aws_instance
   410  aws_instance.foo.0:
   411    ID = bar
   412    provider = provider.aws
   413    foo = foo
   414    type = aws_instance
   415  aws_instance.foo.1:
   416    ID = bar
   417    provider = provider.aws
   418    foo = foo
   419    type = aws_instance
   420  `
   421  
   422  const testTerraformApplyCountDecToOneStr = `
   423  aws_instance.foo:
   424    ID = bar
   425    provider = provider.aws
   426    foo = foo
   427    type = aws_instance
   428  `
   429  
   430  const testTerraformApplyCountDecToOneCorruptedStr = `
   431  aws_instance.foo:
   432    ID = bar
   433    provider = provider.aws
   434    foo = foo
   435    type = aws_instance
   436  `
   437  
   438  const testTerraformApplyCountDecToOneCorruptedPlanStr = `
   439  DIFF:
   440  
   441  DESTROY: aws_instance.foo[0]
   442    id:   "baz" => ""
   443    type: "aws_instance" => ""
   444  
   445  
   446  
   447  STATE:
   448  
   449  aws_instance.foo:
   450    ID = bar
   451    provider = provider.aws
   452    foo = foo
   453    type = aws_instance
   454  aws_instance.foo.0:
   455    ID = baz
   456    provider = provider.aws
   457    type = aws_instance
   458  `
   459  
   460  const testTerraformApplyCountVariableStr = `
   461  aws_instance.foo.0:
   462    ID = foo
   463    provider = provider.aws
   464    foo = foo
   465    type = aws_instance
   466  aws_instance.foo.1:
   467    ID = foo
   468    provider = provider.aws
   469    foo = foo
   470    type = aws_instance
   471  `
   472  
   473  const testTerraformApplyCountVariableRefStr = `
   474  aws_instance.bar:
   475    ID = foo
   476    provider = provider.aws
   477    foo = 2
   478    type = aws_instance
   479  
   480    Dependencies:
   481      aws_instance.foo
   482  aws_instance.foo.0:
   483    ID = foo
   484    provider = provider.aws
   485  aws_instance.foo.1:
   486    ID = foo
   487    provider = provider.aws
   488  `
   489  const testTerraformApplyForEachVariableStr = `
   490  aws_instance.foo["b15c6d616d6143248c575900dff57325eb1de498"]:
   491    ID = foo
   492    provider = provider.aws
   493    foo = foo
   494    type = aws_instance
   495  aws_instance.foo["c3de47d34b0a9f13918dd705c141d579dd6555fd"]:
   496    ID = foo
   497    provider = provider.aws
   498    foo = foo
   499    type = aws_instance
   500  aws_instance.foo["e30a7edcc42a846684f2a4eea5f3cd261d33c46d"]:
   501    ID = foo
   502    provider = provider.aws
   503    foo = foo
   504    type = aws_instance
   505  aws_instance.one["a"]:
   506    ID = foo
   507    provider = provider.aws
   508  aws_instance.one["b"]:
   509    ID = foo
   510    provider = provider.aws
   511  aws_instance.two["a"]:
   512    ID = foo
   513    provider = provider.aws
   514  
   515    Dependencies:
   516      aws_instance.one
   517  aws_instance.two["b"]:
   518    ID = foo
   519    provider = provider.aws
   520  
   521    Dependencies:
   522      aws_instance.one`
   523  const testTerraformApplyMinimalStr = `
   524  aws_instance.bar:
   525    ID = foo
   526    provider = provider.aws
   527  aws_instance.foo:
   528    ID = foo
   529    provider = provider.aws
   530  `
   531  
   532  const testTerraformApplyModuleStr = `
   533  aws_instance.bar:
   534    ID = foo
   535    provider = provider.aws
   536    foo = bar
   537    type = aws_instance
   538  aws_instance.foo:
   539    ID = foo
   540    provider = provider.aws
   541    num = 2
   542    type = aws_instance
   543  
   544  module.child:
   545    aws_instance.baz:
   546      ID = foo
   547      provider = provider.aws
   548      foo = bar
   549      type = aws_instance
   550  `
   551  
   552  const testTerraformApplyModuleBoolStr = `
   553  aws_instance.bar:
   554    ID = foo
   555    provider = provider.aws
   556    foo = true
   557    type = aws_instance
   558  
   559    Dependencies:
   560      module.child
   561  
   562  module.child:
   563    <no state>
   564    Outputs:
   565  
   566    leader = true
   567  `
   568  
   569  const testTerraformApplyModuleDestroyOrderStr = `
   570  <no state>
   571  `
   572  
   573  const testTerraformApplyMultiProviderStr = `
   574  aws_instance.bar:
   575    ID = foo
   576    provider = provider.aws
   577    foo = bar
   578    type = aws_instance
   579  do_instance.foo:
   580    ID = foo
   581    provider = provider.do
   582    num = 2
   583    type = do_instance
   584  `
   585  
   586  const testTerraformApplyModuleOnlyProviderStr = `
   587  <no state>
   588  module.child:
   589    aws_instance.foo:
   590      ID = foo
   591      provider = provider.aws
   592    test_instance.foo:
   593      ID = foo
   594      provider = provider.test
   595  `
   596  
   597  const testTerraformApplyModuleProviderAliasStr = `
   598  <no state>
   599  module.child:
   600    aws_instance.foo:
   601      ID = foo
   602      provider = module.child.provider.aws.eu
   603  `
   604  
   605  const testTerraformApplyModuleVarRefExistingStr = `
   606  aws_instance.foo:
   607    ID = foo
   608    provider = provider.aws
   609    foo = bar
   610  
   611  module.child:
   612    aws_instance.foo:
   613      ID = foo
   614      provider = provider.aws
   615      type = aws_instance
   616      value = bar
   617  `
   618  
   619  const testTerraformApplyOutputOrphanStr = `
   620  <no state>
   621  Outputs:
   622  
   623  foo = bar
   624  `
   625  
   626  const testTerraformApplyOutputOrphanModuleStr = `
   627  <no state>
   628  module.child:
   629    <no state>
   630    Outputs:
   631  
   632    foo = bar
   633  `
   634  
   635  const testTerraformApplyProvisionerStr = `
   636  aws_instance.bar:
   637    ID = foo
   638    provider = provider.aws
   639  
   640    Dependencies:
   641      aws_instance.foo
   642  aws_instance.foo:
   643    ID = foo
   644    provider = provider.aws
   645    compute = value
   646    compute_value = 1
   647    num = 2
   648    type = aws_instance
   649    value = computed_value
   650  `
   651  
   652  const testTerraformApplyProvisionerModuleStr = `
   653  <no state>
   654  module.child:
   655    aws_instance.bar:
   656      ID = foo
   657      provider = provider.aws
   658  `
   659  
   660  const testTerraformApplyProvisionerFailStr = `
   661  aws_instance.bar: (tainted)
   662    ID = foo
   663    provider = provider.aws
   664  aws_instance.foo:
   665    ID = foo
   666    provider = provider.aws
   667    num = 2
   668    type = aws_instance
   669  `
   670  
   671  const testTerraformApplyProvisionerFailCreateStr = `
   672  aws_instance.bar: (tainted)
   673    ID = foo
   674    provider = provider.aws
   675  `
   676  
   677  const testTerraformApplyProvisionerFailCreateNoIdStr = `
   678  <no state>
   679  `
   680  
   681  const testTerraformApplyProvisionerFailCreateBeforeDestroyStr = `
   682  aws_instance.bar: (tainted) (1 deposed)
   683    ID = foo
   684    provider = provider.aws
   685    require_new = xyz
   686    type = aws_instance
   687    Deposed ID 1 = bar
   688  `
   689  
   690  const testTerraformApplyProvisionerResourceRefStr = `
   691  aws_instance.bar:
   692    ID = foo
   693    provider = provider.aws
   694    num = 2
   695    type = aws_instance
   696  `
   697  
   698  const testTerraformApplyProvisionerSelfRefStr = `
   699  aws_instance.foo:
   700    ID = foo
   701    provider = provider.aws
   702    foo = bar
   703    type = aws_instance
   704  `
   705  
   706  const testTerraformApplyProvisionerMultiSelfRefStr = `
   707  aws_instance.foo.0:
   708    ID = foo
   709    provider = provider.aws
   710    foo = number 0
   711    type = aws_instance
   712  aws_instance.foo.1:
   713    ID = foo
   714    provider = provider.aws
   715    foo = number 1
   716    type = aws_instance
   717  aws_instance.foo.2:
   718    ID = foo
   719    provider = provider.aws
   720    foo = number 2
   721    type = aws_instance
   722  `
   723  
   724  const testTerraformApplyProvisionerMultiSelfRefSingleStr = `
   725  aws_instance.foo.0:
   726    ID = foo
   727    provider = provider.aws
   728    foo = number 0
   729    type = aws_instance
   730  aws_instance.foo.1:
   731    ID = foo
   732    provider = provider.aws
   733    foo = number 1
   734    type = aws_instance
   735  
   736    Dependencies:
   737      aws_instance.foo[0]
   738  aws_instance.foo.2:
   739    ID = foo
   740    provider = provider.aws
   741    foo = number 2
   742    type = aws_instance
   743  
   744    Dependencies:
   745      aws_instance.foo[0]
   746  `
   747  
   748  const testTerraformApplyProvisionerDiffStr = `
   749  aws_instance.bar:
   750    ID = foo
   751    provider = provider.aws
   752    foo = bar
   753    type = aws_instance
   754  `
   755  
   756  const testTerraformApplyDestroyStr = `
   757  <no state>
   758  `
   759  
   760  const testTerraformApplyErrorStr = `
   761  aws_instance.bar: (tainted)
   762    ID = bar
   763    provider = provider.aws
   764  
   765    Dependencies:
   766      aws_instance.foo
   767  aws_instance.foo:
   768    ID = foo
   769    provider = provider.aws
   770    value = 2
   771  `
   772  
   773  const testTerraformApplyErrorCreateBeforeDestroyStr = `
   774  aws_instance.bar:
   775    ID = bar
   776    provider = provider.aws
   777    require_new = abc
   778  `
   779  
   780  const testTerraformApplyErrorDestroyCreateBeforeDestroyStr = `
   781  aws_instance.bar: (1 deposed)
   782    ID = foo
   783    provider = provider.aws
   784    require_new = xyz
   785    type = aws_instance
   786    Deposed ID 1 = bar
   787  `
   788  
   789  const testTerraformApplyErrorPartialStr = `
   790  aws_instance.bar:
   791    ID = bar
   792    provider = provider.aws
   793  
   794    Dependencies:
   795      aws_instance.foo
   796  aws_instance.foo:
   797    ID = foo
   798    provider = provider.aws
   799    value = 2
   800  `
   801  
   802  const testTerraformApplyResourceDependsOnModuleStr = `
   803  aws_instance.a:
   804    ID = foo
   805    provider = provider.aws
   806    ami = parent
   807    type = aws_instance
   808  
   809    Dependencies:
   810      module.child
   811  
   812  module.child:
   813    aws_instance.child:
   814      ID = foo
   815      provider = provider.aws
   816      ami = child
   817      type = aws_instance
   818  `
   819  
   820  const testTerraformApplyResourceDependsOnModuleDeepStr = `
   821  aws_instance.a:
   822    ID = foo
   823    provider = provider.aws
   824    ami = parent
   825    type = aws_instance
   826  
   827    Dependencies:
   828      module.child
   829  
   830  module.child.grandchild:
   831    aws_instance.c:
   832      ID = foo
   833      provider = provider.aws
   834      ami = grandchild
   835      type = aws_instance
   836  `
   837  
   838  const testTerraformApplyResourceDependsOnModuleInModuleStr = `
   839  <no state>
   840  module.child:
   841    aws_instance.b:
   842      ID = foo
   843      provider = provider.aws
   844      ami = child
   845      type = aws_instance
   846  
   847      Dependencies:
   848        module.grandchild
   849  module.child.grandchild:
   850    aws_instance.c:
   851      ID = foo
   852      provider = provider.aws
   853      ami = grandchild
   854      type = aws_instance
   855  `
   856  
   857  const testTerraformApplyTaintStr = `
   858  aws_instance.bar:
   859    ID = foo
   860    provider = provider.aws
   861    num = 2
   862    type = aws_instance
   863  `
   864  
   865  const testTerraformApplyTaintDepStr = `
   866  aws_instance.bar:
   867    ID = bar
   868    provider = provider.aws
   869    foo = foo
   870    num = 2
   871    type = aws_instance
   872  
   873    Dependencies:
   874      aws_instance.foo
   875  aws_instance.foo:
   876    ID = foo
   877    provider = provider.aws
   878    num = 2
   879    type = aws_instance
   880  `
   881  
   882  const testTerraformApplyTaintDepRequireNewStr = `
   883  aws_instance.bar:
   884    ID = foo
   885    provider = provider.aws
   886    foo = foo
   887    require_new = yes
   888    type = aws_instance
   889  
   890    Dependencies:
   891      aws_instance.foo
   892  aws_instance.foo:
   893    ID = foo
   894    provider = provider.aws
   895    num = 2
   896    type = aws_instance
   897  `
   898  
   899  const testTerraformApplyOutputStr = `
   900  aws_instance.bar:
   901    ID = foo
   902    provider = provider.aws
   903    foo = bar
   904    type = aws_instance
   905  aws_instance.foo:
   906    ID = foo
   907    provider = provider.aws
   908    num = 2
   909    type = aws_instance
   910  
   911  Outputs:
   912  
   913  foo_num = 2
   914  `
   915  
   916  const testTerraformApplyOutputAddStr = `
   917  aws_instance.test.0:
   918    ID = foo
   919    provider = provider.aws
   920    foo = foo0
   921    type = aws_instance
   922  aws_instance.test.1:
   923    ID = foo
   924    provider = provider.aws
   925    foo = foo1
   926    type = aws_instance
   927  
   928  Outputs:
   929  
   930  firstOutput = foo0
   931  secondOutput = foo1
   932  `
   933  
   934  const testTerraformApplyOutputListStr = `
   935  aws_instance.bar.0:
   936    ID = foo
   937    provider = provider.aws
   938    foo = bar
   939    type = aws_instance
   940  aws_instance.bar.1:
   941    ID = foo
   942    provider = provider.aws
   943    foo = bar
   944    type = aws_instance
   945  aws_instance.bar.2:
   946    ID = foo
   947    provider = provider.aws
   948    foo = bar
   949    type = aws_instance
   950  aws_instance.foo:
   951    ID = foo
   952    provider = provider.aws
   953    num = 2
   954    type = aws_instance
   955  
   956  Outputs:
   957  
   958  foo_num = [bar,bar,bar]
   959  `
   960  
   961  const testTerraformApplyOutputMultiStr = `
   962  aws_instance.bar.0:
   963    ID = foo
   964    provider = provider.aws
   965    foo = bar
   966    type = aws_instance
   967  aws_instance.bar.1:
   968    ID = foo
   969    provider = provider.aws
   970    foo = bar
   971    type = aws_instance
   972  aws_instance.bar.2:
   973    ID = foo
   974    provider = provider.aws
   975    foo = bar
   976    type = aws_instance
   977  aws_instance.foo:
   978    ID = foo
   979    provider = provider.aws
   980    num = 2
   981    type = aws_instance
   982  
   983  Outputs:
   984  
   985  foo_num = bar,bar,bar
   986  `
   987  
   988  const testTerraformApplyOutputMultiIndexStr = `
   989  aws_instance.bar.0:
   990    ID = foo
   991    provider = provider.aws
   992    foo = bar
   993    type = aws_instance
   994  aws_instance.bar.1:
   995    ID = foo
   996    provider = provider.aws
   997    foo = bar
   998    type = aws_instance
   999  aws_instance.bar.2:
  1000    ID = foo
  1001    provider = provider.aws
  1002    foo = bar
  1003    type = aws_instance
  1004  aws_instance.foo:
  1005    ID = foo
  1006    provider = provider.aws
  1007    num = 2
  1008    type = aws_instance
  1009  
  1010  Outputs:
  1011  
  1012  foo_num = bar
  1013  `
  1014  
  1015  const testTerraformApplyUnknownAttrStr = `
  1016  aws_instance.foo: (tainted)
  1017    ID = foo
  1018    provider = provider.aws
  1019    compute = unknown
  1020    num = 2
  1021    type = aws_instance
  1022  `
  1023  
  1024  const testTerraformApplyVarsStr = `
  1025  aws_instance.bar:
  1026    ID = foo
  1027    provider = provider.aws
  1028    bar = override
  1029    baz = override
  1030    foo = us-east-1
  1031  aws_instance.foo:
  1032    ID = foo
  1033    provider = provider.aws
  1034    bar = baz
  1035    list.# = 2
  1036    list.0 = Hello
  1037    list.1 = World
  1038    map.Baz = Foo
  1039    map.Foo = Bar
  1040    map.Hello = World
  1041    num = 2
  1042  `
  1043  
  1044  const testTerraformApplyVarsEnvStr = `
  1045  aws_instance.bar:
  1046    ID = foo
  1047    provider = provider.aws
  1048    list.# = 2
  1049    list.0 = Hello
  1050    list.1 = World
  1051    map.Baz = Foo
  1052    map.Foo = Bar
  1053    map.Hello = World
  1054    string = baz
  1055    type = aws_instance
  1056  `
  1057  
  1058  const testTerraformInputHCL = `
  1059  hcl_instance.hcltest:
  1060    ID = foo
  1061    provider = provider.hcl
  1062    bar.w = z
  1063    bar.x = y
  1064    foo.# = 2
  1065    foo.0 = a
  1066    foo.1 = b
  1067    type = hcl_instance
  1068  `
  1069  
  1070  const testTerraformRefreshDataRefDataStr = `
  1071  data.null_data_source.bar:
  1072    ID = foo
  1073    provider = provider.null
  1074    bar = yes
  1075  
  1076    Dependencies:
  1077      data.null_data_source.foo
  1078  data.null_data_source.foo:
  1079    ID = foo
  1080    provider = provider.null
  1081    foo = yes
  1082  `