kubeform.dev/terraform-backend-sdk@v0.0.0-20220310143633-45f07fe731c5/terraform/terraform_test.go (about)

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