github.com/pmcatominey/terraform@v0.7.0-rc2.0.20160708105029-1401a52a5cc5/terraform/terraform_test.go (about)

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