github.com/muratcelep/terraform@v1.1.0-beta2-not-internal-4/not-internal/terraform/terraform_test.go (about)

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