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