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