github.com/bpineau/terraform@v0.8.0-rc1.0.20161126184705-a8886012d185/terraform/terraform_test.go (about)

     1  package terraform
     2  
     3  import (
     4  	"flag"
     5  	"fmt"
     6  	"io"
     7  	"io/ioutil"
     8  	"log"
     9  	"os"
    10  	"path/filepath"
    11  	"strings"
    12  	"sync"
    13  	"testing"
    14  
    15  	"github.com/hashicorp/go-getter"
    16  	"github.com/hashicorp/terraform/config"
    17  	"github.com/hashicorp/terraform/config/module"
    18  	"github.com/hashicorp/terraform/helper/experiment"
    19  	"github.com/hashicorp/terraform/helper/logging"
    20  )
    21  
    22  // This is the directory where our test fixtures are.
    23  const fixtureDir = "./test-fixtures"
    24  
    25  func TestMain(m *testing.M) {
    26  	experiment.Flag(flag.CommandLine)
    27  	flag.Parse()
    28  
    29  	if testing.Verbose() {
    30  		// if we're verbose, use the logging requested by TF_LOG
    31  		logging.SetOutput()
    32  	} else {
    33  		// otherwise silence all logs
    34  		log.SetOutput(ioutil.Discard)
    35  	}
    36  
    37  	// Make sure shadow operations fail our real tests
    38  	contextFailOnShadowError = true
    39  
    40  	// Always DeepCopy the Diff on every Plan during a test
    41  	contextTestDeepCopyOnPlan = true
    42  
    43  	os.Exit(m.Run())
    44  }
    45  
    46  func tempDir(t *testing.T) string {
    47  	dir, err := ioutil.TempDir("", "tf")
    48  	if err != nil {
    49  		t.Fatalf("err: %s", err)
    50  	}
    51  	if err := os.RemoveAll(dir); err != nil {
    52  		t.Fatalf("err: %s", err)
    53  	}
    54  
    55  	return dir
    56  }
    57  
    58  // tempEnv lets you temporarily set an environment variable. It returns
    59  // a function to defer to reset the old value.
    60  // the old value that should be set via a defer.
    61  func tempEnv(t *testing.T, k string, v string) func() {
    62  	old, oldOk := os.LookupEnv(k)
    63  	os.Setenv(k, v)
    64  	return func() {
    65  		if !oldOk {
    66  			os.Unsetenv(k)
    67  		} else {
    68  			os.Setenv(k, old)
    69  		}
    70  	}
    71  }
    72  
    73  func testConfig(t *testing.T, name string) *config.Config {
    74  	c, err := config.LoadFile(filepath.Join(fixtureDir, name, "main.tf"))
    75  	if err != nil {
    76  		t.Fatalf("err: %s", err)
    77  	}
    78  
    79  	return c
    80  }
    81  
    82  func testModule(t *testing.T, name string) *module.Tree {
    83  	mod, err := module.NewTreeModule("", filepath.Join(fixtureDir, name))
    84  	if err != nil {
    85  		t.Fatalf("err: %s", err)
    86  	}
    87  
    88  	s := &getter.FolderStorage{StorageDir: tempDir(t)}
    89  	if err := mod.Load(s, module.GetModeGet); err != nil {
    90  		t.Fatalf("err: %s", err)
    91  	}
    92  
    93  	return mod
    94  }
    95  
    96  // testModuleInline takes a map of path -> config strings and yields a config
    97  // structure with those files loaded from disk
    98  func testModuleInline(t *testing.T, config map[string]string) *module.Tree {
    99  	cfgPath, err := ioutil.TempDir("", "tf-test")
   100  	if err != nil {
   101  		t.Errorf("Error creating temporary directory for config: %s", err)
   102  	}
   103  	defer os.RemoveAll(cfgPath)
   104  
   105  	for path, configStr := range config {
   106  		dir := filepath.Dir(path)
   107  		if dir != "." {
   108  			err := os.MkdirAll(filepath.Join(cfgPath, dir), os.FileMode(0777))
   109  			if err != nil {
   110  				t.Fatalf("Error creating subdir: %s", err)
   111  			}
   112  		}
   113  		// Write the configuration
   114  		cfgF, err := os.Create(filepath.Join(cfgPath, path))
   115  		if err != nil {
   116  			t.Fatalf("Error creating temporary file for config: %s", err)
   117  		}
   118  
   119  		_, err = io.Copy(cfgF, strings.NewReader(configStr))
   120  		cfgF.Close()
   121  		if err != nil {
   122  			t.Fatalf("Error creating temporary file for config: %s", err)
   123  		}
   124  	}
   125  
   126  	// Parse the configuration
   127  	mod, err := module.NewTreeModule("", cfgPath)
   128  	if err != nil {
   129  		t.Fatalf("Error loading configuration: %s", err)
   130  	}
   131  
   132  	// Load the modules
   133  	modStorage := &getter.FolderStorage{
   134  		StorageDir: filepath.Join(cfgPath, ".tfmodules"),
   135  	}
   136  	err = mod.Load(modStorage, module.GetModeGet)
   137  	if err != nil {
   138  		t.Errorf("Error downloading modules: %s", err)
   139  	}
   140  
   141  	return mod
   142  }
   143  
   144  func testStringMatch(t *testing.T, s fmt.Stringer, expected string) {
   145  	actual := strings.TrimSpace(s.String())
   146  	expected = strings.TrimSpace(expected)
   147  	if actual != expected {
   148  		t.Fatalf("Actual\n\n%s\n\nExpected:\n\n%s", actual, expected)
   149  	}
   150  }
   151  
   152  func testProviderFuncFixed(rp ResourceProvider) ResourceProviderFactory {
   153  	return func() (ResourceProvider, error) {
   154  		return rp, nil
   155  	}
   156  }
   157  
   158  func testProvisionerFuncFixed(rp ResourceProvisioner) ResourceProvisionerFactory {
   159  	return func() (ResourceProvisioner, error) {
   160  		return rp, nil
   161  	}
   162  }
   163  
   164  // HookRecordApplyOrder is a test hook that records the order of applies
   165  // by recording the PreApply event.
   166  type HookRecordApplyOrder struct {
   167  	NilHook
   168  
   169  	Active bool
   170  
   171  	IDs    []string
   172  	States []*InstanceState
   173  	Diffs  []*InstanceDiff
   174  
   175  	l sync.Mutex
   176  }
   177  
   178  func (h *HookRecordApplyOrder) PreApply(
   179  	info *InstanceInfo,
   180  	s *InstanceState,
   181  	d *InstanceDiff) (HookAction, error) {
   182  	if h.Active {
   183  		h.l.Lock()
   184  		defer h.l.Unlock()
   185  
   186  		h.IDs = append(h.IDs, info.Id)
   187  		h.Diffs = append(h.Diffs, d)
   188  		h.States = append(h.States, s)
   189  	}
   190  
   191  	return HookActionContinue, nil
   192  }
   193  
   194  // Below are all the constant strings that are the expected output for
   195  // various tests.
   196  
   197  const testTerraformInputProviderStr = `
   198  aws_instance.bar:
   199    ID = foo
   200    bar = override
   201    foo = us-east-1
   202    type = aws_instance
   203  aws_instance.foo:
   204    ID = foo
   205    bar = baz
   206    num = 2
   207    type = aws_instance
   208  `
   209  
   210  const testTerraformInputProviderOnlyStr = `
   211  aws_instance.foo:
   212    ID = foo
   213    foo = us-west-2
   214    type = aws_instance
   215  `
   216  
   217  const testTerraformInputVarOnlyStr = `
   218  aws_instance.foo:
   219    ID = foo
   220    foo = us-east-1
   221    type = aws_instance
   222  `
   223  
   224  const testTerraformInputVarOnlyUnsetStr = `
   225  aws_instance.foo:
   226    ID = foo
   227    bar = baz
   228    foo = foovalue
   229    type = aws_instance
   230  `
   231  
   232  const testTerraformInputVarsStr = `
   233  aws_instance.bar:
   234    ID = foo
   235    bar = override
   236    foo = us-east-1
   237    type = aws_instance
   238  aws_instance.foo:
   239    ID = foo
   240    bar = baz
   241    num = 2
   242    type = aws_instance
   243  `
   244  
   245  const testTerraformApplyStr = `
   246  aws_instance.bar:
   247    ID = foo
   248    foo = bar
   249    type = aws_instance
   250  aws_instance.foo:
   251    ID = foo
   252    num = 2
   253    type = aws_instance
   254  `
   255  
   256  const testTerraformApplyDataBasicStr = `
   257  data.null_data_source.testing:
   258    ID = yo
   259  `
   260  
   261  const testTerraformApplyRefCountStr = `
   262  aws_instance.bar:
   263    ID = foo
   264    foo = 3
   265    type = aws_instance
   266  
   267    Dependencies:
   268      aws_instance.foo
   269  aws_instance.foo.0:
   270    ID = foo
   271  aws_instance.foo.1:
   272    ID = foo
   273  aws_instance.foo.2:
   274    ID = foo
   275  `
   276  
   277  const testTerraformApplyProviderAliasStr = `
   278  aws_instance.bar:
   279    ID = foo
   280    provider = aws.bar
   281    foo = bar
   282    type = aws_instance
   283  aws_instance.foo:
   284    ID = foo
   285    num = 2
   286    type = aws_instance
   287  `
   288  
   289  const testTerraformApplyProviderAliasConfigStr = `
   290  another_instance.bar:
   291    ID = foo
   292    provider = another.two
   293  another_instance.foo:
   294    ID = foo
   295  `
   296  
   297  const testTerraformApplyEmptyModuleStr = `
   298  <no state>
   299  Outputs:
   300  
   301  end = XXXX
   302  
   303  module.child:
   304  <no state>
   305  Outputs:
   306  
   307  aws_access_key = YYYYY
   308  aws_route53_zone_id = XXXX
   309  aws_secret_key = ZZZZ
   310  `
   311  
   312  const testTerraformApplyDependsCreateBeforeStr = `
   313  aws_instance.lb:
   314    ID = foo
   315    instance = foo
   316    type = aws_instance
   317  
   318    Dependencies:
   319      aws_instance.web
   320  aws_instance.web:
   321    ID = foo
   322    require_new = ami-new
   323    type = aws_instance
   324  `
   325  
   326  const testTerraformApplyCreateBeforeStr = `
   327  aws_instance.bar:
   328    ID = foo
   329    require_new = xyz
   330    type = aws_instance
   331  `
   332  
   333  const testTerraformApplyCreateBeforeUpdateStr = `
   334  aws_instance.bar:
   335    ID = foo
   336    foo = baz
   337    type = aws_instance
   338  `
   339  
   340  const testTerraformApplyCancelStr = `
   341  aws_instance.foo:
   342    ID = foo
   343    num = 2
   344  `
   345  
   346  const testTerraformApplyComputeStr = `
   347  aws_instance.bar:
   348    ID = foo
   349    foo = computed_dynamical
   350    type = aws_instance
   351  
   352    Dependencies:
   353      aws_instance.foo
   354  aws_instance.foo:
   355    ID = foo
   356    dynamical = computed_dynamical
   357    num = 2
   358    type = aws_instance
   359  `
   360  
   361  const testTerraformApplyCountDecStr = `
   362  aws_instance.foo.0:
   363    ID = bar
   364    foo = foo
   365    type = aws_instance
   366  aws_instance.foo.1:
   367    ID = bar
   368    foo = foo
   369    type = aws_instance
   370  `
   371  
   372  const testTerraformApplyCountDecToOneStr = `
   373  aws_instance.foo:
   374    ID = bar
   375    foo = foo
   376    type = aws_instance
   377  `
   378  
   379  const testTerraformApplyCountDecToOneCorruptedStr = `
   380  aws_instance.foo:
   381    ID = bar
   382    foo = foo
   383    type = aws_instance
   384  `
   385  
   386  const testTerraformApplyCountDecToOneCorruptedPlanStr = `
   387  DIFF:
   388  
   389  DESTROY: aws_instance.foo.0
   390  
   391  STATE:
   392  
   393  aws_instance.foo:
   394    ID = bar
   395    foo = foo
   396    type = aws_instance
   397  aws_instance.foo.0:
   398    ID = baz
   399    type = aws_instance
   400  `
   401  
   402  const testTerraformApplyCountTaintedStr = `
   403  <no state>
   404  `
   405  
   406  const testTerraformApplyCountVariableStr = `
   407  aws_instance.foo.0:
   408    ID = foo
   409    foo = foo
   410    type = aws_instance
   411  aws_instance.foo.1:
   412    ID = foo
   413    foo = foo
   414    type = aws_instance
   415  `
   416  
   417  const testTerraformApplyCountVariableRefStr = `
   418  aws_instance.bar:
   419    ID = foo
   420    foo = 2
   421    type = aws_instance
   422  
   423    Dependencies:
   424      aws_instance.foo
   425  aws_instance.foo.0:
   426    ID = foo
   427  aws_instance.foo.1:
   428    ID = foo
   429  `
   430  
   431  const testTerraformApplyMinimalStr = `
   432  aws_instance.bar:
   433    ID = foo
   434  aws_instance.foo:
   435    ID = foo
   436  `
   437  
   438  const testTerraformApplyModuleStr = `
   439  aws_instance.bar:
   440    ID = foo
   441    foo = bar
   442    type = aws_instance
   443  aws_instance.foo:
   444    ID = foo
   445    num = 2
   446    type = aws_instance
   447  
   448  module.child:
   449    aws_instance.baz:
   450      ID = foo
   451      foo = bar
   452      type = aws_instance
   453  `
   454  
   455  const testTerraformApplyModuleBoolStr = `
   456  aws_instance.bar:
   457    ID = foo
   458    foo = 1
   459    type = aws_instance
   460  
   461    Dependencies:
   462      module.child
   463  
   464  module.child:
   465    <no state>
   466    Outputs:
   467  
   468    leader = 1
   469  `
   470  
   471  const testTerraformApplyModuleDestroyOrderStr = `
   472  <no state>
   473  module.child:
   474    <no state>
   475  `
   476  
   477  const testTerraformApplyMultiProviderStr = `
   478  aws_instance.bar:
   479    ID = foo
   480    foo = bar
   481    type = aws_instance
   482  do_instance.foo:
   483    ID = foo
   484    num = 2
   485    type = do_instance
   486  `
   487  
   488  const testTerraformApplyModuleOnlyProviderStr = `
   489  <no state>
   490  module.child:
   491    aws_instance.foo:
   492      ID = foo
   493    test_instance.foo:
   494      ID = foo
   495  `
   496  
   497  const testTerraformApplyModuleProviderAliasStr = `
   498  <no state>
   499  module.child:
   500    aws_instance.foo:
   501      ID = foo
   502      provider = aws.eu
   503  `
   504  
   505  const testTerraformApplyModuleVarRefExistingStr = `
   506  aws_instance.foo:
   507    ID = foo
   508    foo = bar
   509  
   510  module.child:
   511    aws_instance.foo:
   512      ID = foo
   513      type = aws_instance
   514      value = bar
   515  `
   516  
   517  const testTerraformApplyOutputOrphanStr = `
   518  <no state>
   519  Outputs:
   520  
   521  foo = bar
   522  `
   523  
   524  const testTerraformApplyOutputOrphanModuleStr = `
   525  module.child:
   526    <no state>
   527    Outputs:
   528  
   529    foo = bar
   530  `
   531  
   532  const testTerraformApplyProvisionerStr = `
   533  aws_instance.bar:
   534    ID = foo
   535  
   536    Dependencies:
   537      aws_instance.foo
   538  aws_instance.foo:
   539    ID = foo
   540    dynamical = computed_dynamical
   541    num = 2
   542    type = aws_instance
   543  `
   544  
   545  const testTerraformApplyProvisionerModuleStr = `
   546  <no state>
   547  module.child:
   548    aws_instance.bar:
   549      ID = foo
   550  `
   551  
   552  const testTerraformApplyProvisionerFailStr = `
   553  aws_instance.bar: (tainted)
   554    ID = foo
   555  aws_instance.foo:
   556    ID = foo
   557    num = 2
   558    type = aws_instance
   559  `
   560  
   561  const testTerraformApplyProvisionerFailCreateStr = `
   562  aws_instance.bar: (tainted)
   563    ID = foo
   564  `
   565  
   566  const testTerraformApplyProvisionerFailCreateNoIdStr = `
   567  <no state>
   568  `
   569  
   570  const testTerraformApplyProvisionerFailCreateBeforeDestroyStr = `
   571  aws_instance.bar: (1 deposed)
   572    ID = bar
   573    require_new = abc
   574    Deposed ID 1 = foo (tainted)
   575  `
   576  
   577  const testTerraformApplyProvisionerResourceRefStr = `
   578  aws_instance.bar:
   579    ID = foo
   580    num = 2
   581    type = aws_instance
   582  `
   583  
   584  const testTerraformApplyProvisionerSelfRefStr = `
   585  aws_instance.foo:
   586    ID = foo
   587    foo = bar
   588    type = aws_instance
   589  `
   590  
   591  const testTerraformApplyProvisionerMultiSelfRefStr = `
   592  aws_instance.foo.0:
   593    ID = foo
   594    foo = number 0
   595    type = aws_instance
   596  aws_instance.foo.1:
   597    ID = foo
   598    foo = number 1
   599    type = aws_instance
   600  aws_instance.foo.2:
   601    ID = foo
   602    foo = number 2
   603    type = aws_instance
   604  `
   605  
   606  const testTerraformApplyProvisionerMultiSelfRefSingleStr = `
   607  aws_instance.foo.0:
   608    ID = foo
   609    foo = number 0
   610    type = aws_instance
   611  aws_instance.foo.1:
   612    ID = foo
   613    foo = number 1
   614    type = aws_instance
   615  
   616    Dependencies:
   617      aws_instance.foo.0
   618  aws_instance.foo.2:
   619    ID = foo
   620    foo = number 2
   621    type = aws_instance
   622  
   623    Dependencies:
   624      aws_instance.foo.0
   625  `
   626  
   627  const testTerraformApplyProvisionerDiffStr = `
   628  aws_instance.bar:
   629    ID = foo
   630    foo = bar
   631    type = aws_instance
   632  `
   633  
   634  const testTerraformApplyDestroyStr = `
   635  <no state>
   636  `
   637  
   638  const testTerraformApplyDestroyNestedModuleStr = `
   639  module.child.subchild:
   640    <no state>
   641  `
   642  
   643  const testTerraformApplyErrorStr = `
   644  aws_instance.bar:
   645    ID = bar
   646  
   647    Dependencies:
   648      aws_instance.foo
   649  aws_instance.foo:
   650    ID = foo
   651    num = 2
   652  `
   653  
   654  const testTerraformApplyErrorCreateBeforeDestroyStr = `
   655  aws_instance.bar:
   656    ID = bar
   657    require_new = abc
   658  `
   659  
   660  const testTerraformApplyErrorDestroyCreateBeforeDestroyStr = `
   661  aws_instance.bar: (1 deposed)
   662    ID = foo
   663    Deposed ID 1 = bar
   664  `
   665  
   666  const testTerraformApplyErrorPartialStr = `
   667  aws_instance.bar:
   668    ID = bar
   669  
   670    Dependencies:
   671      aws_instance.foo
   672  aws_instance.foo:
   673    ID = foo
   674    num = 2
   675  `
   676  
   677  const testTerraformApplyResourceDependsOnModuleStr = `
   678  aws_instance.a:
   679    ID = foo
   680  
   681    Dependencies:
   682      module.child
   683  
   684  module.child:
   685    aws_instance.child:
   686      ID = foo
   687  `
   688  
   689  const testTerraformApplyResourceDependsOnModuleDeepStr = `
   690  aws_instance.a:
   691    ID = foo
   692  
   693    Dependencies:
   694      module.child
   695  
   696  module.child.grandchild:
   697    aws_instance.c:
   698      ID = foo
   699  `
   700  
   701  const testTerraformApplyResourceDependsOnModuleInModuleStr = `
   702  <no state>
   703  module.child:
   704    aws_instance.b:
   705      ID = foo
   706  
   707      Dependencies:
   708        module.grandchild
   709  module.child.grandchild:
   710    aws_instance.c:
   711      ID = foo
   712  `
   713  
   714  const testTerraformApplyTaintStr = `
   715  aws_instance.bar:
   716    ID = foo
   717    num = 2
   718    type = aws_instance
   719  `
   720  
   721  const testTerraformApplyTaintDepStr = `
   722  aws_instance.bar:
   723    ID = bar
   724    foo = foo
   725    num = 2
   726    type = aws_instance
   727  
   728    Dependencies:
   729      aws_instance.foo
   730  aws_instance.foo:
   731    ID = foo
   732    num = 2
   733    type = aws_instance
   734  `
   735  
   736  const testTerraformApplyTaintDepRequireNewStr = `
   737  aws_instance.bar:
   738    ID = foo
   739    foo = foo
   740    require_new = yes
   741    type = aws_instance
   742  
   743    Dependencies:
   744      aws_instance.foo
   745  aws_instance.foo:
   746    ID = foo
   747    num = 2
   748    type = aws_instance
   749  `
   750  
   751  const testTerraformApplyOutputStr = `
   752  aws_instance.bar:
   753    ID = foo
   754    foo = bar
   755    type = aws_instance
   756  aws_instance.foo:
   757    ID = foo
   758    num = 2
   759    type = aws_instance
   760  
   761  Outputs:
   762  
   763  foo_num = 2
   764  `
   765  
   766  const testTerraformApplyOutputAddStr = `
   767  aws_instance.test.0:
   768    ID = foo
   769    foo = foo0
   770    type = aws_instance
   771  aws_instance.test.1:
   772    ID = foo
   773    foo = foo1
   774    type = aws_instance
   775  
   776  Outputs:
   777  
   778  firstOutput = foo0
   779  secondOutput = foo1
   780  `
   781  
   782  const testTerraformApplyOutputListStr = `
   783  aws_instance.bar.0:
   784    ID = foo
   785    foo = bar
   786    type = aws_instance
   787  aws_instance.bar.1:
   788    ID = foo
   789    foo = bar
   790    type = aws_instance
   791  aws_instance.bar.2:
   792    ID = foo
   793    foo = bar
   794    type = aws_instance
   795  aws_instance.foo:
   796    ID = foo
   797    num = 2
   798    type = aws_instance
   799  
   800  Outputs:
   801  
   802  foo_num = [bar,bar,bar]
   803  `
   804  
   805  const testTerraformApplyOutputMultiStr = `
   806  aws_instance.bar.0:
   807    ID = foo
   808    foo = bar
   809    type = aws_instance
   810  aws_instance.bar.1:
   811    ID = foo
   812    foo = bar
   813    type = aws_instance
   814  aws_instance.bar.2:
   815    ID = foo
   816    foo = bar
   817    type = aws_instance
   818  aws_instance.foo:
   819    ID = foo
   820    num = 2
   821    type = aws_instance
   822  
   823  Outputs:
   824  
   825  foo_num = bar,bar,bar
   826  `
   827  
   828  const testTerraformApplyOutputMultiIndexStr = `
   829  aws_instance.bar.0:
   830    ID = foo
   831    foo = bar
   832    type = aws_instance
   833  aws_instance.bar.1:
   834    ID = foo
   835    foo = bar
   836    type = aws_instance
   837  aws_instance.bar.2:
   838    ID = foo
   839    foo = bar
   840    type = aws_instance
   841  aws_instance.foo:
   842    ID = foo
   843    num = 2
   844    type = aws_instance
   845  
   846  Outputs:
   847  
   848  foo_num = bar
   849  `
   850  
   851  const testTerraformApplyUnknownAttrStr = `
   852  aws_instance.foo:
   853    ID = foo
   854    num = 2
   855    type = aws_instance
   856  `
   857  
   858  const testTerraformApplyVarsStr = `
   859  aws_instance.bar:
   860    ID = foo
   861    bar = foo
   862    baz = override
   863    foo = us-west-2
   864    type = aws_instance
   865  aws_instance.foo:
   866    ID = foo
   867    bar = baz
   868    list = Hello,World
   869    map = Baz,Foo,Hello
   870    num = 2
   871    type = aws_instance
   872  `
   873  
   874  const testTerraformApplyVarsEnvStr = `
   875  aws_instance.bar:
   876    ID = foo
   877    bar = Hello,World
   878    baz = Baz,Foo,Hello
   879    foo = baz
   880    type = aws_instance
   881  `
   882  
   883  const testTerraformPlanStr = `
   884  DIFF:
   885  
   886  CREATE: aws_instance.bar
   887    foo:  "" => "2"
   888    type: "" => "aws_instance"
   889  CREATE: aws_instance.foo
   890    num:  "" => "2"
   891    type: "" => "aws_instance"
   892  
   893  STATE:
   894  
   895  <no state>
   896  `
   897  
   898  const testTerraformPlanComputedStr = `
   899  DIFF:
   900  
   901  CREATE: aws_instance.bar
   902    foo:  "" => "<computed>"
   903    type: "" => "aws_instance"
   904  CREATE: aws_instance.foo
   905    foo:  "" => "<computed>"
   906    num:  "" => "2"
   907    type: "" => "aws_instance"
   908  
   909  STATE:
   910  
   911  <no state>
   912  `
   913  
   914  const testTerraformPlanComputedIdStr = `
   915  DIFF:
   916  
   917  CREATE: aws_instance.bar
   918    foo:  "" => "<computed>"
   919    type: "" => "aws_instance"
   920  CREATE: aws_instance.foo
   921    foo:  "" => "<computed>"
   922    num:  "" => "2"
   923    type: "" => "aws_instance"
   924  
   925  STATE:
   926  
   927  <no state>
   928  `
   929  
   930  const testTerraformPlanComputedListStr = `
   931  DIFF:
   932  
   933  CREATE: aws_instance.bar
   934    foo:  "" => "<computed>"
   935    type: "" => "aws_instance"
   936  CREATE: aws_instance.foo
   937    list.#: "" => "<computed>"
   938    num:    "" => "2"
   939    type:   "" => "aws_instance"
   940  
   941  STATE:
   942  
   943  <no state>
   944  `
   945  
   946  const testTerraformPlanCountStr = `
   947  DIFF:
   948  
   949  CREATE: aws_instance.bar
   950    foo:  "" => "foo,foo,foo,foo,foo"
   951    type: "" => "aws_instance"
   952  CREATE: aws_instance.foo.0
   953    foo:  "" => "foo"
   954    type: "" => "aws_instance"
   955  CREATE: aws_instance.foo.1
   956    foo:  "" => "foo"
   957    type: "" => "aws_instance"
   958  CREATE: aws_instance.foo.2
   959    foo:  "" => "foo"
   960    type: "" => "aws_instance"
   961  CREATE: aws_instance.foo.3
   962    foo:  "" => "foo"
   963    type: "" => "aws_instance"
   964  CREATE: aws_instance.foo.4
   965    foo:  "" => "foo"
   966    type: "" => "aws_instance"
   967  
   968  STATE:
   969  
   970  <no state>
   971  `
   972  
   973  const testTerraformPlanCountIndexStr = `
   974  DIFF:
   975  
   976  CREATE: aws_instance.foo.0
   977    foo:  "" => "0"
   978    type: "" => "aws_instance"
   979  CREATE: aws_instance.foo.1
   980    foo:  "" => "1"
   981    type: "" => "aws_instance"
   982  
   983  STATE:
   984  
   985  <no state>
   986  `
   987  
   988  const testTerraformPlanCountIndexZeroStr = `
   989  DIFF:
   990  
   991  CREATE: aws_instance.foo
   992    foo:  "" => "0"
   993    type: "" => "aws_instance"
   994  
   995  STATE:
   996  
   997  <no state>
   998  `
   999  
  1000  const testTerraformPlanCountOneIndexStr = `
  1001  DIFF:
  1002  
  1003  CREATE: aws_instance.bar
  1004    foo:  "" => "foo"
  1005    type: "" => "aws_instance"
  1006  CREATE: aws_instance.foo
  1007    foo:  "" => "foo"
  1008    type: "" => "aws_instance"
  1009  
  1010  STATE:
  1011  
  1012  <no state>
  1013  `
  1014  
  1015  const testTerraformPlanCountZeroStr = `
  1016  DIFF:
  1017  
  1018  CREATE: aws_instance.bar
  1019    foo:  "" => ""
  1020    type: "" => "aws_instance"
  1021  
  1022  STATE:
  1023  
  1024  <no state>
  1025  `
  1026  
  1027  const testTerraformPlanCountVarStr = `
  1028  DIFF:
  1029  
  1030  CREATE: aws_instance.bar
  1031    foo:  "" => "foo,foo,foo"
  1032    type: "" => "aws_instance"
  1033  CREATE: aws_instance.foo.0
  1034    foo:  "" => "foo"
  1035    type: "" => "aws_instance"
  1036  CREATE: aws_instance.foo.1
  1037    foo:  "" => "foo"
  1038    type: "" => "aws_instance"
  1039  CREATE: aws_instance.foo.2
  1040    foo:  "" => "foo"
  1041    type: "" => "aws_instance"
  1042  
  1043  STATE:
  1044  
  1045  <no state>
  1046  `
  1047  
  1048  const testTerraformPlanCountDecreaseStr = `
  1049  DIFF:
  1050  
  1051  CREATE: aws_instance.bar
  1052    foo:  "" => "bar"
  1053    type: "" => "aws_instance"
  1054  DESTROY: aws_instance.foo.1
  1055  DESTROY: aws_instance.foo.2
  1056  
  1057  STATE:
  1058  
  1059  aws_instance.foo.0:
  1060    ID = bar
  1061    foo = foo
  1062    type = aws_instance
  1063  aws_instance.foo.1:
  1064    ID = bar
  1065  aws_instance.foo.2:
  1066    ID = bar
  1067  `
  1068  
  1069  const testTerraformPlanCountIncreaseStr = `
  1070  DIFF:
  1071  
  1072  CREATE: aws_instance.bar
  1073    foo:  "" => "bar"
  1074    type: "" => "aws_instance"
  1075  CREATE: aws_instance.foo.1
  1076    foo:  "" => "foo"
  1077    type: "" => "aws_instance"
  1078  CREATE: aws_instance.foo.2
  1079    foo:  "" => "foo"
  1080    type: "" => "aws_instance"
  1081  
  1082  STATE:
  1083  
  1084  aws_instance.foo:
  1085    ID = bar
  1086    foo = foo
  1087    type = aws_instance
  1088  `
  1089  
  1090  const testTerraformPlanCountIncreaseFromOneStr = `
  1091  DIFF:
  1092  
  1093  CREATE: aws_instance.bar
  1094    foo:  "" => "bar"
  1095    type: "" => "aws_instance"
  1096  CREATE: aws_instance.foo.1
  1097    foo:  "" => "foo"
  1098    type: "" => "aws_instance"
  1099  CREATE: aws_instance.foo.2
  1100    foo:  "" => "foo"
  1101    type: "" => "aws_instance"
  1102  
  1103  STATE:
  1104  
  1105  aws_instance.foo.0:
  1106    ID = bar
  1107    foo = foo
  1108    type = aws_instance
  1109  `
  1110  
  1111  const testTerraformPlanCountIncreaseFromOneCorruptedStr = `
  1112  DIFF:
  1113  
  1114  CREATE: aws_instance.bar
  1115    foo:  "" => "bar"
  1116    type: "" => "aws_instance"
  1117  DESTROY: aws_instance.foo
  1118  CREATE: aws_instance.foo.1
  1119    foo:  "" => "foo"
  1120    type: "" => "aws_instance"
  1121  CREATE: aws_instance.foo.2
  1122    foo:  "" => "foo"
  1123    type: "" => "aws_instance"
  1124  
  1125  STATE:
  1126  
  1127  aws_instance.foo:
  1128    ID = bar
  1129    foo = foo
  1130    type = aws_instance
  1131  aws_instance.foo.0:
  1132    ID = bar
  1133    foo = foo
  1134    type = aws_instance
  1135  `
  1136  
  1137  const testTerraformPlanDestroyStr = `
  1138  DIFF:
  1139  
  1140  DESTROY: aws_instance.one
  1141  DESTROY: aws_instance.two
  1142  
  1143  STATE:
  1144  
  1145  aws_instance.one:
  1146    ID = bar
  1147  aws_instance.two:
  1148    ID = baz
  1149  `
  1150  
  1151  const testTerraformPlanDiffVarStr = `
  1152  DIFF:
  1153  
  1154  CREATE: aws_instance.bar
  1155    num:  "" => "3"
  1156    type: "" => "aws_instance"
  1157  UPDATE: aws_instance.foo
  1158    num: "2" => "3"
  1159  
  1160  STATE:
  1161  
  1162  aws_instance.foo:
  1163    ID = bar
  1164    num = 2
  1165  `
  1166  
  1167  const testTerraformPlanEmptyStr = `
  1168  DIFF:
  1169  
  1170  CREATE: aws_instance.bar
  1171  CREATE: aws_instance.foo
  1172  
  1173  STATE:
  1174  
  1175  <no state>
  1176  `
  1177  
  1178  const testTerraformPlanEscapedVarStr = `
  1179  DIFF:
  1180  
  1181  CREATE: aws_instance.foo
  1182    foo:  "" => "bar-${baz}"
  1183    type: "" => "aws_instance"
  1184  
  1185  STATE:
  1186  
  1187  <no state>
  1188  `
  1189  
  1190  const testTerraformPlanModulesStr = `
  1191  DIFF:
  1192  
  1193  CREATE: aws_instance.bar
  1194    foo:  "" => "2"
  1195    type: "" => "aws_instance"
  1196  CREATE: aws_instance.foo
  1197    num:  "" => "2"
  1198    type: "" => "aws_instance"
  1199  
  1200  module.child:
  1201    CREATE: aws_instance.foo
  1202      num:  "" => "2"
  1203      type: "" => "aws_instance"
  1204  
  1205  STATE:
  1206  
  1207  <no state>
  1208  `
  1209  
  1210  const testTerraformPlanModuleCycleStr = `
  1211  DIFF:
  1212  
  1213  CREATE: aws_instance.b
  1214  CREATE: aws_instance.c
  1215    some_input: "" => "<computed>"
  1216    type:       "" => "aws_instance"
  1217  
  1218  STATE:
  1219  
  1220  <no state>
  1221  `
  1222  
  1223  const testTerraformPlanModuleDestroyStr = `
  1224  DIFF:
  1225  
  1226  DESTROY: aws_instance.foo
  1227  
  1228  module.child:
  1229    DESTROY: aws_instance.foo
  1230  
  1231  STATE:
  1232  
  1233  aws_instance.foo:
  1234    ID = bar
  1235  
  1236  module.child:
  1237    aws_instance.foo:
  1238      ID = bar
  1239  `
  1240  
  1241  const testTerraformPlanModuleDestroyCycleStr = `
  1242  DIFF:
  1243  
  1244  module.a_module:
  1245    DESTROY: aws_instance.a
  1246  module.b_module:
  1247    DESTROY: aws_instance.b
  1248  
  1249  STATE:
  1250  
  1251  module.a_module:
  1252    aws_instance.a:
  1253      ID = a
  1254  module.b_module:
  1255    aws_instance.b:
  1256      ID = b
  1257  `
  1258  
  1259  const testTerraformPlanModuleDestroyMultivarStr = `
  1260  DIFF:
  1261  
  1262  module.child:
  1263    DESTROY: aws_instance.foo.0
  1264    DESTROY: aws_instance.foo.1
  1265  
  1266  STATE:
  1267  
  1268  <no state>
  1269  module.child:
  1270    aws_instance.foo.0:
  1271      ID = bar0
  1272    aws_instance.foo.1:
  1273      ID = bar1
  1274  `
  1275  
  1276  const testTerraformPlanModuleInputStr = `
  1277  DIFF:
  1278  
  1279  CREATE: aws_instance.bar
  1280    foo:  "" => "2"
  1281    type: "" => "aws_instance"
  1282  
  1283  module.child:
  1284    CREATE: aws_instance.foo
  1285      foo:  "" => "42"
  1286      type: "" => "aws_instance"
  1287  
  1288  STATE:
  1289  
  1290  <no state>
  1291  `
  1292  
  1293  const testTerraformPlanModuleInputComputedStr = `
  1294  DIFF:
  1295  
  1296  CREATE: aws_instance.bar
  1297    foo:  "" => "<computed>"
  1298    type: "" => "aws_instance"
  1299  
  1300  module.child:
  1301    CREATE: aws_instance.foo
  1302      foo:  "" => "<computed>"
  1303      type: "" => "aws_instance"
  1304  
  1305  STATE:
  1306  
  1307  <no state>
  1308  `
  1309  
  1310  const testTerraformPlanModuleInputVarStr = `
  1311  DIFF:
  1312  
  1313  CREATE: aws_instance.bar
  1314    foo:  "" => "2"
  1315    type: "" => "aws_instance"
  1316  
  1317  module.child:
  1318    CREATE: aws_instance.foo
  1319      foo:  "" => "52"
  1320      type: "" => "aws_instance"
  1321  
  1322  STATE:
  1323  
  1324  <no state>
  1325  `
  1326  
  1327  const testTerraformPlanModuleMultiVarStr = `
  1328  DIFF:
  1329  
  1330  CREATE: aws_instance.parent.0
  1331  CREATE: aws_instance.parent.1
  1332  
  1333  module.child:
  1334    CREATE: aws_instance.bar.0
  1335      baz:  "" => "baz"
  1336      type: "" => "aws_instance"
  1337    CREATE: aws_instance.bar.1
  1338      baz:  "" => "baz"
  1339      type: "" => "aws_instance"
  1340    CREATE: aws_instance.foo
  1341      foo:  "" => "baz,baz"
  1342      type: "" => "aws_instance"
  1343  
  1344  STATE:
  1345  
  1346  <no state>
  1347  `
  1348  
  1349  const testTerraformPlanModuleOrphansStr = `
  1350  DIFF:
  1351  
  1352  CREATE: aws_instance.foo
  1353    num:  "" => "2"
  1354    type: "" => "aws_instance"
  1355  
  1356  module.child:
  1357    DESTROY: aws_instance.foo
  1358  
  1359  STATE:
  1360  
  1361  module.child:
  1362    aws_instance.foo:
  1363      ID = baz
  1364  `
  1365  
  1366  const testTerraformPlanModuleVarStr = `
  1367  DIFF:
  1368  
  1369  CREATE: aws_instance.bar
  1370    foo:  "" => "2"
  1371    type: "" => "aws_instance"
  1372  
  1373  module.child:
  1374    CREATE: aws_instance.foo
  1375      num:  "" => "2"
  1376      type: "" => "aws_instance"
  1377  
  1378  STATE:
  1379  
  1380  <no state>
  1381  `
  1382  
  1383  const testTerraformPlanModuleVarComputedStr = `
  1384  DIFF:
  1385  
  1386  CREATE: aws_instance.bar
  1387    foo:  "" => "<computed>"
  1388    type: "" => "aws_instance"
  1389  
  1390  module.child:
  1391    CREATE: aws_instance.foo
  1392      foo:  "" => "<computed>"
  1393      type: "" => "aws_instance"
  1394  
  1395  STATE:
  1396  
  1397  <no state>
  1398  `
  1399  
  1400  const testTerraformPlanModuleVarIntStr = `
  1401  DIFF:
  1402  
  1403  module.child:
  1404    CREATE: aws_instance.foo
  1405      num:  "" => "2"
  1406      type: "" => "aws_instance"
  1407  
  1408  STATE:
  1409  
  1410  <no state>
  1411  `
  1412  
  1413  const testTerraformPlanOrphanStr = `
  1414  DIFF:
  1415  
  1416  DESTROY: aws_instance.baz
  1417  CREATE: aws_instance.foo
  1418    num:  "" => "2"
  1419    type: "" => "aws_instance"
  1420  
  1421  STATE:
  1422  
  1423  aws_instance.baz:
  1424    ID = bar
  1425  `
  1426  
  1427  const testTerraformPlanStateStr = `
  1428  DIFF:
  1429  
  1430  CREATE: aws_instance.bar
  1431    foo:  "" => "2"
  1432    type: "" => "aws_instance"
  1433  UPDATE: aws_instance.foo
  1434    num:  "" => "2"
  1435    type: "" => "aws_instance"
  1436  
  1437  STATE:
  1438  
  1439  aws_instance.foo:
  1440    ID = bar
  1441  `
  1442  
  1443  const testTerraformPlanTaintStr = `
  1444  DIFF:
  1445  
  1446  DESTROY/CREATE: aws_instance.bar
  1447    foo:  "" => "2"
  1448    type: "" => "aws_instance"
  1449  
  1450  STATE:
  1451  
  1452  aws_instance.bar: (tainted)
  1453    ID = baz
  1454  aws_instance.foo:
  1455    ID = bar
  1456    num = 2
  1457  `
  1458  
  1459  const testTerraformPlanTaintIgnoreChangesStr = `
  1460  DIFF:
  1461  
  1462  DESTROY/CREATE: aws_instance.foo
  1463    type: "" => "aws_instance"
  1464    vars: "" => "foo"
  1465  
  1466  STATE:
  1467  
  1468  aws_instance.foo: (tainted)
  1469    ID = foo
  1470    type = aws_instance
  1471    vars = foo
  1472  `
  1473  
  1474  const testTerraformPlanMultipleTaintStr = `
  1475  DIFF:
  1476  
  1477  DESTROY/CREATE: aws_instance.bar
  1478    foo:  "" => "2"
  1479    type: "" => "aws_instance"
  1480  
  1481  STATE:
  1482  
  1483  aws_instance.bar: (2 tainted)
  1484    ID = <not created>
  1485    Tainted ID 1 = baz
  1486    Tainted ID 2 = zip
  1487  aws_instance.foo:
  1488    ID = bar
  1489    num = 2
  1490  `
  1491  
  1492  const testTerraformPlanVarMultiCountOneStr = `
  1493  DIFF:
  1494  
  1495  CREATE: aws_instance.bar
  1496    foo:  "" => "2"
  1497    type: "" => "aws_instance"
  1498  CREATE: aws_instance.foo
  1499    num:  "" => "2"
  1500    type: "" => "aws_instance"
  1501  
  1502  STATE:
  1503  
  1504  <no state>
  1505  `
  1506  
  1507  const testTerraformPlanPathVarStr = `
  1508  DIFF:
  1509  
  1510  CREATE: aws_instance.foo
  1511    cwd:    "" => "%s/barpath"
  1512    module: "" => "%s/foopath"
  1513    root:   "" => "%s/barpath"
  1514    type:   "" => "aws_instance"
  1515  
  1516  STATE:
  1517  
  1518  <no state>
  1519  `
  1520  
  1521  const testTerraformPlanIgnoreChangesStr = `
  1522  DIFF:
  1523  
  1524  UPDATE: aws_instance.foo
  1525    type: "" => "aws_instance"
  1526  
  1527  STATE:
  1528  
  1529  aws_instance.foo:
  1530    ID = bar
  1531    ami = ami-abcd1234
  1532  `
  1533  
  1534  const testTerraformPlanIgnoreChangesWildcardStr = `
  1535  DIFF:
  1536  
  1537  
  1538  
  1539  STATE:
  1540  
  1541  aws_instance.foo:
  1542    ID = bar
  1543    ami = ami-abcd1234
  1544    instance_type = t2.micro
  1545  `
  1546  
  1547  const testTerraformPlanComputedValueInMap = `
  1548  DIFF:
  1549  
  1550  CREATE: aws_computed_source.intermediates
  1551    computed_read_only: "" => "<computed>"
  1552  
  1553  module.test_mod:
  1554    CREATE: aws_instance.inner2
  1555      looked_up: "" => "<computed>"
  1556      type:      "" => "aws_instance"
  1557  
  1558  STATE:
  1559  
  1560  <no state>
  1561  `
  1562  
  1563  const testTerraformPlanModuleVariableFromSplat = `
  1564  DIFF:
  1565  
  1566  module.mod1:
  1567    CREATE: aws_instance.test.0
  1568      thing: "" => "doesnt"
  1569      type:  "" => "aws_instance"
  1570    CREATE: aws_instance.test.1
  1571      thing: "" => "doesnt"
  1572      type:  "" => "aws_instance"
  1573  module.mod2:
  1574    CREATE: aws_instance.test.0
  1575      thing: "" => "doesnt"
  1576      type:  "" => "aws_instance"
  1577    CREATE: aws_instance.test.1
  1578      thing: "" => "doesnt"
  1579      type:  "" => "aws_instance"
  1580  
  1581  STATE:
  1582  
  1583  <no state>`
  1584  
  1585  const testTerraformInputHCL = `
  1586  hcl_instance.hcltest:
  1587    ID = foo
  1588    bar.w = z
  1589    bar.x = y
  1590    foo.# = 2
  1591    foo.0 = a
  1592    foo.1 = b
  1593    type = hcl_instance
  1594  `
  1595  
  1596  const testTerraformRefreshDataRefDataStr = `
  1597  data.null_data_source.bar:
  1598    ID = foo
  1599    bar = yes
  1600    type = null_data_source
  1601  
  1602    Dependencies:
  1603      data.null_data_source.foo
  1604  data.null_data_source.foo:
  1605    ID = foo
  1606    foo = yes
  1607    type = null_data_source
  1608  `