github.com/arvindram03/terraform@v0.3.7-0.20150212015210-408f838db36d/terraform/context_test.go (about)

     1  package terraform
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"os"
     7  	"reflect"
     8  	"sort"
     9  	"strings"
    10  	"sync"
    11  	"testing"
    12  )
    13  
    14  func TestContextGraph(t *testing.T) {
    15  	p := testProvider("aws")
    16  	m := testModule(t, "validate-good")
    17  	c := testContext(t, &ContextOpts{
    18  		Module: m,
    19  		Providers: map[string]ResourceProviderFactory{
    20  			"aws": testProviderFuncFixed(p),
    21  		},
    22  	})
    23  
    24  	g, err := c.Graph()
    25  	if err != nil {
    26  		t.Fatalf("err: %s", err)
    27  	}
    28  
    29  	actual := strings.TrimSpace(g.String())
    30  	expected := strings.TrimSpace(testContextGraph)
    31  	if actual != expected {
    32  		t.Fatalf("bad: %s", actual)
    33  	}
    34  }
    35  
    36  func TestContextValidate(t *testing.T) {
    37  	p := testProvider("aws")
    38  	m := testModule(t, "validate-good")
    39  	c := testContext(t, &ContextOpts{
    40  		Module: m,
    41  		Providers: map[string]ResourceProviderFactory{
    42  			"aws": testProviderFuncFixed(p),
    43  		},
    44  	})
    45  
    46  	w, e := c.Validate()
    47  	if len(w) > 0 {
    48  		t.Fatalf("bad: %#v", w)
    49  	}
    50  	if len(e) > 0 {
    51  		t.Fatalf("bad: %#v", e)
    52  	}
    53  }
    54  
    55  func TestContextValidate_goodModule(t *testing.T) {
    56  	p := testProvider("aws")
    57  	m := testModule(t, "validate-good-module")
    58  	c := testContext(t, &ContextOpts{
    59  		Module: m,
    60  		Providers: map[string]ResourceProviderFactory{
    61  			"aws": testProviderFuncFixed(p),
    62  		},
    63  	})
    64  
    65  	w, e := c.Validate()
    66  	if len(w) > 0 {
    67  		t.Fatalf("bad: %#v", w)
    68  	}
    69  	if len(e) > 0 {
    70  		t.Fatalf("bad: %#v", e)
    71  	}
    72  }
    73  
    74  func TestContextValidate_badModuleOutput(t *testing.T) {
    75  	p := testProvider("aws")
    76  	m := testModule(t, "validate-bad-module-output")
    77  	c := testContext(t, &ContextOpts{
    78  		Module: m,
    79  		Providers: map[string]ResourceProviderFactory{
    80  			"aws": testProviderFuncFixed(p),
    81  		},
    82  	})
    83  
    84  	w, e := c.Validate()
    85  	if len(w) > 0 {
    86  		t.Fatalf("bad: %#v", w)
    87  	}
    88  	if len(e) == 0 {
    89  		t.Fatalf("bad: %#v", e)
    90  	}
    91  }
    92  
    93  func TestContextValidate_badVar(t *testing.T) {
    94  	p := testProvider("aws")
    95  	m := testModule(t, "validate-bad-var")
    96  	c := testContext(t, &ContextOpts{
    97  		Module: m,
    98  		Providers: map[string]ResourceProviderFactory{
    99  			"aws": testProviderFuncFixed(p),
   100  		},
   101  	})
   102  
   103  	w, e := c.Validate()
   104  	if len(w) > 0 {
   105  		t.Fatalf("bad: %#v", w)
   106  	}
   107  	if len(e) == 0 {
   108  		t.Fatalf("bad: %#v", e)
   109  	}
   110  }
   111  
   112  func TestContextValidate_countNegative(t *testing.T) {
   113  	p := testProvider("aws")
   114  	m := testModule(t, "validate-count-negative")
   115  	c := testContext(t, &ContextOpts{
   116  		Module: m,
   117  		Providers: map[string]ResourceProviderFactory{
   118  			"aws": testProviderFuncFixed(p),
   119  		},
   120  	})
   121  
   122  	w, e := c.Validate()
   123  	if len(w) > 0 {
   124  		t.Fatalf("bad: %#v", w)
   125  	}
   126  	if len(e) == 0 {
   127  		t.Fatalf("bad: %#v", e)
   128  	}
   129  }
   130  
   131  func TestContextValidate_countVariable(t *testing.T) {
   132  	p := testProvider("aws")
   133  	m := testModule(t, "apply-count-variable")
   134  	c := testContext(t, &ContextOpts{
   135  		Module: m,
   136  		Providers: map[string]ResourceProviderFactory{
   137  			"aws": testProviderFuncFixed(p),
   138  		},
   139  	})
   140  
   141  	w, e := c.Validate()
   142  	if len(w) > 0 {
   143  		t.Fatalf("bad: %#v", w)
   144  	}
   145  	if len(e) > 0 {
   146  		for _, err := range e {
   147  			t.Errorf("bad: %s", err)
   148  		}
   149  		t.FailNow()
   150  	}
   151  }
   152  
   153  func TestContextValidate_countVariableNoDefault(t *testing.T) {
   154  	p := testProvider("aws")
   155  	m := testModule(t, "validate-count-variable")
   156  	c := testContext(t, &ContextOpts{
   157  		Module: m,
   158  		Providers: map[string]ResourceProviderFactory{
   159  			"aws": testProviderFuncFixed(p),
   160  		},
   161  	})
   162  
   163  	w, e := c.Validate()
   164  	if len(w) > 0 {
   165  		t.Fatalf("bad: %#v", w)
   166  	}
   167  	if len(e) > 1 {
   168  		for _, err := range e {
   169  			t.Errorf("bad: %s", err)
   170  		}
   171  		t.FailNow()
   172  	}
   173  }
   174  
   175  func TestContextValidate_moduleBadResource(t *testing.T) {
   176  	m := testModule(t, "validate-module-bad-rc")
   177  	p := testProvider("aws")
   178  	c := testContext(t, &ContextOpts{
   179  		Module: m,
   180  		Providers: map[string]ResourceProviderFactory{
   181  			"aws": testProviderFuncFixed(p),
   182  		},
   183  	})
   184  
   185  	p.ValidateResourceReturnErrors = []error{fmt.Errorf("bad")}
   186  
   187  	w, e := c.Validate()
   188  	if len(w) > 0 {
   189  		t.Fatalf("bad: %#v", w)
   190  	}
   191  	if len(e) == 0 {
   192  		t.Fatalf("bad: %#v", e)
   193  	}
   194  }
   195  
   196  func TestContextValidate_moduleProviderInherit(t *testing.T) {
   197  	m := testModule(t, "validate-module-pc-inherit")
   198  	p := testProvider("aws")
   199  	c := testContext(t, &ContextOpts{
   200  		Module: m,
   201  		Providers: map[string]ResourceProviderFactory{
   202  			"aws": testProviderFuncFixed(p),
   203  		},
   204  	})
   205  
   206  	p.ValidateFn = func(c *ResourceConfig) ([]string, []error) {
   207  		return nil, c.CheckSet([]string{"set"})
   208  	}
   209  
   210  	w, e := c.Validate()
   211  	if len(w) > 0 {
   212  		t.Fatalf("bad: %#v", w)
   213  	}
   214  	if len(e) > 0 {
   215  		t.Fatalf("bad: %#v", e)
   216  	}
   217  }
   218  
   219  func TestContextValidate_orphans(t *testing.T) {
   220  	p := testProvider("aws")
   221  	m := testModule(t, "validate-good")
   222  	state := &State{
   223  		Modules: []*ModuleState{
   224  			&ModuleState{
   225  				Path: rootModulePath,
   226  				Resources: map[string]*ResourceState{
   227  					"aws_instance.web": &ResourceState{
   228  						Type: "aws_instance",
   229  						Primary: &InstanceState{
   230  							ID: "bar",
   231  						},
   232  					},
   233  				},
   234  			},
   235  		},
   236  	}
   237  	c := testContext(t, &ContextOpts{
   238  		Module: m,
   239  		Providers: map[string]ResourceProviderFactory{
   240  			"aws": testProviderFuncFixed(p),
   241  		},
   242  		State: state,
   243  	})
   244  
   245  	p.ValidateResourceFn = func(
   246  		t string, c *ResourceConfig) ([]string, []error) {
   247  		return nil, c.CheckSet([]string{"foo"})
   248  	}
   249  
   250  	w, e := c.Validate()
   251  	if len(w) > 0 {
   252  		t.Fatalf("bad: %#v", w)
   253  	}
   254  	if len(e) > 0 {
   255  		t.Fatalf("bad: %#v", e)
   256  	}
   257  }
   258  
   259  func TestContextValidate_tainted(t *testing.T) {
   260  	p := testProvider("aws")
   261  	m := testModule(t, "validate-good")
   262  	state := &State{
   263  		Modules: []*ModuleState{
   264  			&ModuleState{
   265  				Path: rootModulePath,
   266  				Resources: map[string]*ResourceState{
   267  					"aws_instance.foo": &ResourceState{
   268  						Type: "aws_instance",
   269  						Tainted: []*InstanceState{
   270  							&InstanceState{
   271  								ID: "bar",
   272  							},
   273  						},
   274  					},
   275  				},
   276  			},
   277  		},
   278  	}
   279  	c := testContext(t, &ContextOpts{
   280  		Module: m,
   281  		Providers: map[string]ResourceProviderFactory{
   282  			"aws": testProviderFuncFixed(p),
   283  		},
   284  		State: state,
   285  	})
   286  
   287  	p.ValidateResourceFn = func(
   288  		t string, c *ResourceConfig) ([]string, []error) {
   289  		return nil, c.CheckSet([]string{"foo"})
   290  	}
   291  
   292  	w, e := c.Validate()
   293  	if len(w) > 0 {
   294  		t.Fatalf("bad: %#v", w)
   295  	}
   296  	if len(e) > 0 {
   297  		t.Fatalf("bad: %#v", e)
   298  	}
   299  }
   300  
   301  func TestContextValidate_providerConfig_bad(t *testing.T) {
   302  	m := testModule(t, "validate-bad-pc")
   303  	p := testProvider("aws")
   304  	c := testContext(t, &ContextOpts{
   305  		Module: m,
   306  		Providers: map[string]ResourceProviderFactory{
   307  			"aws": testProviderFuncFixed(p),
   308  		},
   309  	})
   310  
   311  	p.ValidateReturnErrors = []error{fmt.Errorf("bad")}
   312  
   313  	w, e := c.Validate()
   314  	if len(w) > 0 {
   315  		t.Fatalf("bad: %#v", w)
   316  	}
   317  	if len(e) == 0 {
   318  		t.Fatalf("bad: %#v", e)
   319  	}
   320  }
   321  
   322  func TestContextValidate_providerConfig_badEmpty(t *testing.T) {
   323  	m := testModule(t, "validate-bad-pc-empty")
   324  	p := testProvider("aws")
   325  	c := testContext(t, &ContextOpts{
   326  		Module: m,
   327  		Providers: map[string]ResourceProviderFactory{
   328  			"aws": testProviderFuncFixed(p),
   329  		},
   330  	})
   331  
   332  	p.ValidateReturnErrors = []error{fmt.Errorf("bad")}
   333  
   334  	w, e := c.Validate()
   335  	if len(w) > 0 {
   336  		t.Fatalf("bad: %#v", w)
   337  	}
   338  	if len(e) == 0 {
   339  		t.Fatalf("bad: %#v", e)
   340  	}
   341  }
   342  
   343  func TestContextValidate_providerConfig_good(t *testing.T) {
   344  	m := testModule(t, "validate-bad-pc")
   345  	p := testProvider("aws")
   346  	c := testContext(t, &ContextOpts{
   347  		Module: m,
   348  		Providers: map[string]ResourceProviderFactory{
   349  			"aws": testProviderFuncFixed(p),
   350  		},
   351  	})
   352  
   353  	w, e := c.Validate()
   354  	if len(w) > 0 {
   355  		t.Fatalf("bad: %#v", w)
   356  	}
   357  	if len(e) > 0 {
   358  		t.Fatalf("bad: %#v", e)
   359  	}
   360  }
   361  
   362  func TestContextValidate_resourceConfig_bad(t *testing.T) {
   363  	m := testModule(t, "validate-bad-rc")
   364  	p := testProvider("aws")
   365  	c := testContext(t, &ContextOpts{
   366  		Module: m,
   367  		Providers: map[string]ResourceProviderFactory{
   368  			"aws": testProviderFuncFixed(p),
   369  		},
   370  	})
   371  
   372  	p.ValidateResourceReturnErrors = []error{fmt.Errorf("bad")}
   373  
   374  	w, e := c.Validate()
   375  	if len(w) > 0 {
   376  		t.Fatalf("bad: %#v", w)
   377  	}
   378  	if len(e) == 0 {
   379  		t.Fatalf("bad: %#v", e)
   380  	}
   381  }
   382  
   383  func TestContextValidate_resourceConfig_good(t *testing.T) {
   384  	m := testModule(t, "validate-bad-rc")
   385  	p := testProvider("aws")
   386  	c := testContext(t, &ContextOpts{
   387  		Module: m,
   388  		Providers: map[string]ResourceProviderFactory{
   389  			"aws": testProviderFuncFixed(p),
   390  		},
   391  	})
   392  
   393  	w, e := c.Validate()
   394  	if len(w) > 0 {
   395  		t.Fatalf("bad: %#v", w)
   396  	}
   397  	if len(e) > 0 {
   398  		t.Fatalf("bad: %#v", e)
   399  	}
   400  }
   401  
   402  func TestContextValidate_resourceNameSymbol(t *testing.T) {
   403  	p := testProvider("aws")
   404  	m := testModule(t, "validate-resource-name-symbol")
   405  	c := testContext(t, &ContextOpts{
   406  		Module: m,
   407  		Providers: map[string]ResourceProviderFactory{
   408  			"aws": testProviderFuncFixed(p),
   409  		},
   410  	})
   411  
   412  	w, e := c.Validate()
   413  	if len(w) == 0 {
   414  		t.Fatalf("bad: %#v", w)
   415  	}
   416  	if len(e) > 0 {
   417  		t.Fatalf("bad: %#v", e)
   418  	}
   419  }
   420  
   421  func TestContextValidate_requiredVar(t *testing.T) {
   422  	m := testModule(t, "validate-required-var")
   423  	c := testContext(t, &ContextOpts{
   424  		Module: m,
   425  	})
   426  
   427  	w, e := c.Validate()
   428  	if len(w) > 0 {
   429  		t.Fatalf("bad: %#v", w)
   430  	}
   431  	if len(e) == 0 {
   432  		t.Fatalf("bad: %#v", e)
   433  	}
   434  }
   435  
   436  func TestContextValidate_provisionerConfig_bad(t *testing.T) {
   437  	m := testModule(t, "validate-bad-prov-conf")
   438  	p := testProvider("aws")
   439  	pr := testProvisioner()
   440  	c := testContext(t, &ContextOpts{
   441  		Module: m,
   442  		Providers: map[string]ResourceProviderFactory{
   443  			"aws": testProviderFuncFixed(p),
   444  		},
   445  		Provisioners: map[string]ResourceProvisionerFactory{
   446  			"shell": testProvisionerFuncFixed(pr),
   447  		},
   448  	})
   449  
   450  	pr.ValidateReturnErrors = []error{fmt.Errorf("bad")}
   451  
   452  	w, e := c.Validate()
   453  	if len(w) > 0 {
   454  		t.Fatalf("bad: %#v", w)
   455  	}
   456  	if len(e) == 0 {
   457  		t.Fatalf("bad: %#v", e)
   458  	}
   459  }
   460  
   461  func TestContextValidate_provisionerConfig_good(t *testing.T) {
   462  	m := testModule(t, "validate-bad-prov-conf")
   463  	p := testProvider("aws")
   464  	pr := testProvisioner()
   465  	pr.ValidateFn = func(c *ResourceConfig) ([]string, []error) {
   466  		if c == nil {
   467  			t.Fatalf("missing resource config for provisioner")
   468  		}
   469  		return nil, nil
   470  	}
   471  	c := testContext(t, &ContextOpts{
   472  		Module: m,
   473  		Providers: map[string]ResourceProviderFactory{
   474  			"aws": testProviderFuncFixed(p),
   475  		},
   476  		Provisioners: map[string]ResourceProvisionerFactory{
   477  			"shell": testProvisionerFuncFixed(pr),
   478  		},
   479  	})
   480  
   481  	w, e := c.Validate()
   482  	if len(w) > 0 {
   483  		t.Fatalf("bad: %#v", w)
   484  	}
   485  	if len(e) > 0 {
   486  		t.Fatalf("bad: %#v", e)
   487  	}
   488  }
   489  
   490  func TestContextValidate_selfRef(t *testing.T) {
   491  	p := testProvider("aws")
   492  	m := testModule(t, "validate-self-ref")
   493  	c := testContext(t, &ContextOpts{
   494  		Module: m,
   495  		Providers: map[string]ResourceProviderFactory{
   496  			"aws": testProviderFuncFixed(p),
   497  		},
   498  	})
   499  
   500  	w, e := c.Validate()
   501  	if len(w) > 0 {
   502  		t.Fatalf("bad: %#v", w)
   503  	}
   504  	if len(e) == 0 {
   505  		t.Fatalf("bad: %#v", e)
   506  	}
   507  }
   508  
   509  func TestContextValidate_selfRefMulti(t *testing.T) {
   510  	p := testProvider("aws")
   511  	m := testModule(t, "validate-self-ref-multi")
   512  	c := testContext(t, &ContextOpts{
   513  		Module: m,
   514  		Providers: map[string]ResourceProviderFactory{
   515  			"aws": testProviderFuncFixed(p),
   516  		},
   517  	})
   518  
   519  	w, e := c.Validate()
   520  	if len(w) > 0 {
   521  		t.Fatalf("bad: %#v", w)
   522  	}
   523  	if len(e) == 0 {
   524  		t.Fatalf("bad: %#v", e)
   525  	}
   526  }
   527  
   528  func TestContextValidate_selfRefMultiAll(t *testing.T) {
   529  	p := testProvider("aws")
   530  	m := testModule(t, "validate-self-ref-multi-all")
   531  	c := testContext(t, &ContextOpts{
   532  		Module: m,
   533  		Providers: map[string]ResourceProviderFactory{
   534  			"aws": testProviderFuncFixed(p),
   535  		},
   536  	})
   537  
   538  	w, e := c.Validate()
   539  	if len(w) > 0 {
   540  		t.Fatalf("bad: %#v", w)
   541  	}
   542  	if len(e) == 0 {
   543  		t.Fatalf("bad: %#v", e)
   544  	}
   545  }
   546  
   547  func TestContextValidate_varRef(t *testing.T) {
   548  	m := testModule(t, "validate-variable-ref")
   549  	p := testProvider("aws")
   550  	c := testContext(t, &ContextOpts{
   551  		Module: m,
   552  		Providers: map[string]ResourceProviderFactory{
   553  			"aws": testProviderFuncFixed(p),
   554  		},
   555  	})
   556  
   557  	computed := false
   558  	p.ValidateResourceFn = func(t string, c *ResourceConfig) ([]string, []error) {
   559  		computed = c.IsComputed("foo")
   560  		return nil, nil
   561  	}
   562  
   563  	c.Validate()
   564  	if !computed {
   565  		t.Fatal("should be computed")
   566  	}
   567  }
   568  
   569  func TestContextValidate_varRefFilled(t *testing.T) {
   570  	m := testModule(t, "validate-variable-ref")
   571  	p := testProvider("aws")
   572  	c := testContext(t, &ContextOpts{
   573  		Module: m,
   574  		Providers: map[string]ResourceProviderFactory{
   575  			"aws": testProviderFuncFixed(p),
   576  		},
   577  		Variables: map[string]string{
   578  			"foo": "bar",
   579  		},
   580  	})
   581  
   582  	var value interface{}
   583  	p.ValidateResourceFn = func(t string, c *ResourceConfig) ([]string, []error) {
   584  		value, _ = c.Get("foo")
   585  		return nil, nil
   586  	}
   587  
   588  	c.Validate()
   589  	if value != "bar" {
   590  		t.Fatalf("bad: %#v", value)
   591  	}
   592  }
   593  
   594  func TestContextInput(t *testing.T) {
   595  	input := new(MockUIInput)
   596  	m := testModule(t, "input-vars")
   597  	p := testProvider("aws")
   598  	p.ApplyFn = testApplyFn
   599  	p.DiffFn = testDiffFn
   600  	ctx := testContext(t, &ContextOpts{
   601  		Module: m,
   602  		Providers: map[string]ResourceProviderFactory{
   603  			"aws": testProviderFuncFixed(p),
   604  		},
   605  		Variables: map[string]string{
   606  			"foo":            "us-west-2",
   607  			"amis.us-east-1": "override",
   608  		},
   609  		UIInput: input,
   610  	})
   611  
   612  	input.InputReturnMap = map[string]string{
   613  		"var.foo": "us-east-1",
   614  	}
   615  
   616  	if err := ctx.Input(InputModeStd); err != nil {
   617  		t.Fatalf("err: %s", err)
   618  	}
   619  
   620  	if _, err := ctx.Plan(nil); err != nil {
   621  		t.Fatalf("err: %s", err)
   622  	}
   623  
   624  	state, err := ctx.Apply()
   625  	if err != nil {
   626  		t.Fatalf("err: %s", err)
   627  	}
   628  
   629  	actual := strings.TrimSpace(state.String())
   630  	expected := strings.TrimSpace(testTerraformInputVarsStr)
   631  	if actual != expected {
   632  		t.Fatalf("bad: \n%s", actual)
   633  	}
   634  }
   635  
   636  func TestContextInput_provider(t *testing.T) {
   637  	m := testModule(t, "input-provider")
   638  	p := testProvider("aws")
   639  	p.ApplyFn = testApplyFn
   640  	p.DiffFn = testDiffFn
   641  	ctx := testContext(t, &ContextOpts{
   642  		Module: m,
   643  		Providers: map[string]ResourceProviderFactory{
   644  			"aws": testProviderFuncFixed(p),
   645  		},
   646  	})
   647  
   648  	var actual interface{}
   649  	p.InputFn = func(i UIInput, c *ResourceConfig) (*ResourceConfig, error) {
   650  		c.Config["foo"] = "bar"
   651  		return c, nil
   652  	}
   653  	p.ConfigureFn = func(c *ResourceConfig) error {
   654  		actual = c.Config["foo"]
   655  		return nil
   656  	}
   657  
   658  	if err := ctx.Input(InputModeStd); err != nil {
   659  		t.Fatalf("err: %s", err)
   660  	}
   661  
   662  	if _, err := ctx.Plan(nil); err != nil {
   663  		t.Fatalf("err: %s", err)
   664  	}
   665  
   666  	if _, err := ctx.Apply(); err != nil {
   667  		t.Fatalf("err: %s", err)
   668  	}
   669  
   670  	if !reflect.DeepEqual(actual, "bar") {
   671  		t.Fatalf("bad: %#v", actual)
   672  	}
   673  }
   674  
   675  func TestContextInput_providerId(t *testing.T) {
   676  	input := new(MockUIInput)
   677  	m := testModule(t, "input-provider")
   678  	p := testProvider("aws")
   679  	p.ApplyFn = testApplyFn
   680  	p.DiffFn = testDiffFn
   681  	ctx := testContext(t, &ContextOpts{
   682  		Module: m,
   683  		Providers: map[string]ResourceProviderFactory{
   684  			"aws": testProviderFuncFixed(p),
   685  		},
   686  		UIInput: input,
   687  	})
   688  
   689  	var actual interface{}
   690  	p.InputFn = func(i UIInput, c *ResourceConfig) (*ResourceConfig, error) {
   691  		v, err := i.Input(&InputOpts{Id: "foo"})
   692  		if err != nil {
   693  			return nil, err
   694  		}
   695  
   696  		c.Config["foo"] = v
   697  		return c, nil
   698  	}
   699  	p.ConfigureFn = func(c *ResourceConfig) error {
   700  		actual = c.Config["foo"]
   701  		return nil
   702  	}
   703  
   704  	input.InputReturnMap = map[string]string{
   705  		"provider.aws.foo": "bar",
   706  	}
   707  
   708  	if err := ctx.Input(InputModeStd); err != nil {
   709  		t.Fatalf("err: %s", err)
   710  	}
   711  
   712  	if _, err := ctx.Plan(nil); err != nil {
   713  		t.Fatalf("err: %s", err)
   714  	}
   715  
   716  	if _, err := ctx.Apply(); err != nil {
   717  		t.Fatalf("err: %s", err)
   718  	}
   719  
   720  	if !reflect.DeepEqual(actual, "bar") {
   721  		t.Fatalf("bad: %#v", actual)
   722  	}
   723  }
   724  
   725  func TestContextInput_providerOnly(t *testing.T) {
   726  	input := new(MockUIInput)
   727  	m := testModule(t, "input-provider-vars")
   728  	p := testProvider("aws")
   729  	p.ApplyFn = testApplyFn
   730  	p.DiffFn = testDiffFn
   731  	ctx := testContext(t, &ContextOpts{
   732  		Module: m,
   733  		Providers: map[string]ResourceProviderFactory{
   734  			"aws": testProviderFuncFixed(p),
   735  		},
   736  		Variables: map[string]string{
   737  			"foo": "us-west-2",
   738  		},
   739  		UIInput: input,
   740  	})
   741  
   742  	input.InputReturnMap = map[string]string{
   743  		"var.foo": "us-east-1",
   744  	}
   745  
   746  	var actual interface{}
   747  	p.InputFn = func(i UIInput, c *ResourceConfig) (*ResourceConfig, error) {
   748  		c.Config["foo"] = "bar"
   749  		return c, nil
   750  	}
   751  	p.ConfigureFn = func(c *ResourceConfig) error {
   752  		actual = c.Config["foo"]
   753  		return nil
   754  	}
   755  
   756  	if err := ctx.Input(InputModeProvider); err != nil {
   757  		t.Fatalf("err: %s", err)
   758  	}
   759  
   760  	if _, err := ctx.Plan(nil); err != nil {
   761  		t.Fatalf("err: %s", err)
   762  	}
   763  
   764  	state, err := ctx.Apply()
   765  	if err != nil {
   766  		t.Fatalf("err: %s", err)
   767  	}
   768  
   769  	if !reflect.DeepEqual(actual, "bar") {
   770  		t.Fatalf("bad: %#v", actual)
   771  	}
   772  
   773  	actualStr := strings.TrimSpace(state.String())
   774  	expectedStr := strings.TrimSpace(testTerraformInputProviderOnlyStr)
   775  	if actualStr != expectedStr {
   776  		t.Fatalf("bad: \n%s", actualStr)
   777  	}
   778  }
   779  
   780  func TestContextInput_providerVars(t *testing.T) {
   781  	input := new(MockUIInput)
   782  	m := testModule(t, "input-provider-with-vars")
   783  	p := testProvider("aws")
   784  	p.ApplyFn = testApplyFn
   785  	p.DiffFn = testDiffFn
   786  	ctx := testContext(t, &ContextOpts{
   787  		Module: m,
   788  		Providers: map[string]ResourceProviderFactory{
   789  			"aws": testProviderFuncFixed(p),
   790  		},
   791  		Variables: map[string]string{
   792  			"foo": "bar",
   793  		},
   794  		UIInput: input,
   795  	})
   796  
   797  	input.InputReturnMap = map[string]string{
   798  		"var.foo": "bar",
   799  	}
   800  
   801  	var actual interface{}
   802  	p.InputFn = func(i UIInput, c *ResourceConfig) (*ResourceConfig, error) {
   803  		c.Config["bar"] = "baz"
   804  		return c, nil
   805  	}
   806  	p.ConfigureFn = func(c *ResourceConfig) error {
   807  		actual, _ = c.Get("foo")
   808  		return nil
   809  	}
   810  
   811  	if err := ctx.Input(InputModeStd); err != nil {
   812  		t.Fatalf("err: %s", err)
   813  	}
   814  
   815  	if _, err := ctx.Plan(nil); err != nil {
   816  		t.Fatalf("err: %s", err)
   817  	}
   818  
   819  	if _, err := ctx.Apply(); err != nil {
   820  		t.Fatalf("err: %s", err)
   821  	}
   822  
   823  	if !reflect.DeepEqual(actual, "bar") {
   824  		t.Fatalf("bad: %#v", actual)
   825  	}
   826  }
   827  
   828  func TestContextInput_varOnly(t *testing.T) {
   829  	input := new(MockUIInput)
   830  	m := testModule(t, "input-provider-vars")
   831  	p := testProvider("aws")
   832  	p.ApplyFn = testApplyFn
   833  	p.DiffFn = testDiffFn
   834  	ctx := testContext(t, &ContextOpts{
   835  		Module: m,
   836  		Providers: map[string]ResourceProviderFactory{
   837  			"aws": testProviderFuncFixed(p),
   838  		},
   839  		Variables: map[string]string{
   840  			"foo": "us-west-2",
   841  		},
   842  		UIInput: input,
   843  	})
   844  
   845  	input.InputReturnMap = map[string]string{
   846  		"var.foo": "us-east-1",
   847  	}
   848  
   849  	var actual interface{}
   850  	p.InputFn = func(i UIInput, c *ResourceConfig) (*ResourceConfig, error) {
   851  		c.Raw["foo"] = "bar"
   852  		return c, nil
   853  	}
   854  	p.ConfigureFn = func(c *ResourceConfig) error {
   855  		actual = c.Raw["foo"]
   856  		return nil
   857  	}
   858  
   859  	if err := ctx.Input(InputModeVar); err != nil {
   860  		t.Fatalf("err: %s", err)
   861  	}
   862  
   863  	if _, err := ctx.Plan(nil); err != nil {
   864  		t.Fatalf("err: %s", err)
   865  	}
   866  
   867  	state, err := ctx.Apply()
   868  	if err != nil {
   869  		t.Fatalf("err: %s", err)
   870  	}
   871  
   872  	if reflect.DeepEqual(actual, "bar") {
   873  		t.Fatalf("bad: %#v", actual)
   874  	}
   875  
   876  	actualStr := strings.TrimSpace(state.String())
   877  	expectedStr := strings.TrimSpace(testTerraformInputVarOnlyStr)
   878  	if actualStr != expectedStr {
   879  		t.Fatalf("bad: \n%s", actualStr)
   880  	}
   881  }
   882  
   883  func TestContextApply(t *testing.T) {
   884  	m := testModule(t, "apply-good")
   885  	p := testProvider("aws")
   886  	p.ApplyFn = testApplyFn
   887  	p.DiffFn = testDiffFn
   888  	ctx := testContext(t, &ContextOpts{
   889  		Module: m,
   890  		Providers: map[string]ResourceProviderFactory{
   891  			"aws": testProviderFuncFixed(p),
   892  		},
   893  	})
   894  
   895  	if _, err := ctx.Plan(nil); err != nil {
   896  		t.Fatalf("err: %s", err)
   897  	}
   898  
   899  	state, err := ctx.Apply()
   900  	if err != nil {
   901  		t.Fatalf("err: %s", err)
   902  	}
   903  
   904  	mod := state.RootModule()
   905  	if len(mod.Resources) < 2 {
   906  		t.Fatalf("bad: %#v", mod.Resources)
   907  	}
   908  
   909  	actual := strings.TrimSpace(state.String())
   910  	expected := strings.TrimSpace(testTerraformApplyStr)
   911  	if actual != expected {
   912  		t.Fatalf("bad: \n%s", actual)
   913  	}
   914  }
   915  
   916  func TestContextApply_emptyModule(t *testing.T) {
   917  	m := testModule(t, "apply-empty-module")
   918  	p := testProvider("aws")
   919  	p.ApplyFn = testApplyFn
   920  	p.DiffFn = testDiffFn
   921  	ctx := testContext(t, &ContextOpts{
   922  		Module: m,
   923  		Providers: map[string]ResourceProviderFactory{
   924  			"aws": testProviderFuncFixed(p),
   925  		},
   926  	})
   927  
   928  	if _, err := ctx.Plan(nil); err != nil {
   929  		t.Fatalf("err: %s", err)
   930  	}
   931  
   932  	state, err := ctx.Apply()
   933  	if err != nil {
   934  		t.Fatalf("err: %s", err)
   935  	}
   936  
   937  	actual := strings.TrimSpace(state.String())
   938  	actual = strings.Replace(actual, "  ", "", -1)
   939  	expected := strings.TrimSpace(testTerraformApplyEmptyModuleStr)
   940  	if actual != expected {
   941  		t.Fatalf("bad: \n%s\nexpect:\n%s", actual, expected)
   942  	}
   943  }
   944  
   945  func TestContextApply_createBeforeDestroy(t *testing.T) {
   946  	m := testModule(t, "apply-good-create-before")
   947  	p := testProvider("aws")
   948  	p.ApplyFn = testApplyFn
   949  	p.DiffFn = testDiffFn
   950  	state := &State{
   951  		Modules: []*ModuleState{
   952  			&ModuleState{
   953  				Path: rootModulePath,
   954  				Resources: map[string]*ResourceState{
   955  					"aws_instance.bar": &ResourceState{
   956  						Type: "aws_instance",
   957  						Primary: &InstanceState{
   958  							ID: "bar",
   959  							Attributes: map[string]string{
   960  								"require_new": "abc",
   961  							},
   962  						},
   963  					},
   964  				},
   965  			},
   966  		},
   967  	}
   968  	ctx := testContext(t, &ContextOpts{
   969  		Module: m,
   970  		Providers: map[string]ResourceProviderFactory{
   971  			"aws": testProviderFuncFixed(p),
   972  		},
   973  		State: state,
   974  	})
   975  
   976  	if _, err := ctx.Plan(nil); err != nil {
   977  		t.Fatalf("err: %s", err)
   978  	}
   979  
   980  	state, err := ctx.Apply()
   981  	if err != nil {
   982  		t.Fatalf("err: %s", err)
   983  	}
   984  
   985  	mod := state.RootModule()
   986  	if len(mod.Resources) != 1 {
   987  		t.Fatalf("bad: %#v", mod.Resources)
   988  	}
   989  
   990  	actual := strings.TrimSpace(state.String())
   991  	expected := strings.TrimSpace(testTerraformApplyCreateBeforeStr)
   992  	if actual != expected {
   993  		t.Fatalf("bad: \n%s", actual)
   994  	}
   995  }
   996  
   997  func TestContextApply_Minimal(t *testing.T) {
   998  	m := testModule(t, "apply-minimal")
   999  	p := testProvider("aws")
  1000  	p.ApplyFn = testApplyFn
  1001  	p.DiffFn = testDiffFn
  1002  	ctx := testContext(t, &ContextOpts{
  1003  		Module: m,
  1004  		Providers: map[string]ResourceProviderFactory{
  1005  			"aws": testProviderFuncFixed(p),
  1006  		},
  1007  	})
  1008  
  1009  	if _, err := ctx.Plan(nil); err != nil {
  1010  		t.Fatalf("err: %s", err)
  1011  	}
  1012  
  1013  	state, err := ctx.Apply()
  1014  	if err != nil {
  1015  		t.Fatalf("err: %s", err)
  1016  	}
  1017  
  1018  	actual := strings.TrimSpace(state.String())
  1019  	expected := strings.TrimSpace(testTerraformApplyMinimalStr)
  1020  	if actual != expected {
  1021  		t.Fatalf("bad: \n%s", actual)
  1022  	}
  1023  }
  1024  
  1025  func TestContextApply_badDiff(t *testing.T) {
  1026  	m := testModule(t, "apply-good")
  1027  	p := testProvider("aws")
  1028  	p.ApplyFn = testApplyFn
  1029  	p.DiffFn = testDiffFn
  1030  	ctx := testContext(t, &ContextOpts{
  1031  		Module: m,
  1032  		Providers: map[string]ResourceProviderFactory{
  1033  			"aws": testProviderFuncFixed(p),
  1034  		},
  1035  	})
  1036  
  1037  	if _, err := ctx.Plan(nil); err != nil {
  1038  		t.Fatalf("err: %s", err)
  1039  	}
  1040  
  1041  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  1042  		return &InstanceDiff{
  1043  			Attributes: map[string]*ResourceAttrDiff{
  1044  				"newp": nil,
  1045  			},
  1046  		}, nil
  1047  	}
  1048  
  1049  	if _, err := ctx.Apply(); err == nil {
  1050  		t.Fatal("should error")
  1051  	}
  1052  }
  1053  
  1054  func TestContextApply_cancel(t *testing.T) {
  1055  	stopped := false
  1056  
  1057  	m := testModule(t, "apply-cancel")
  1058  	p := testProvider("aws")
  1059  	ctx := testContext(t, &ContextOpts{
  1060  		Module: m,
  1061  		Providers: map[string]ResourceProviderFactory{
  1062  			"aws": testProviderFuncFixed(p),
  1063  		},
  1064  	})
  1065  
  1066  	p.ApplyFn = func(*InstanceInfo, *InstanceState, *InstanceDiff) (*InstanceState, error) {
  1067  		if !stopped {
  1068  			stopped = true
  1069  			go ctx.Stop()
  1070  
  1071  			for {
  1072  				if ctx.sh.Stopped() {
  1073  					break
  1074  				}
  1075  			}
  1076  		}
  1077  
  1078  		return &InstanceState{
  1079  			ID: "foo",
  1080  			Attributes: map[string]string{
  1081  				"num": "2",
  1082  			},
  1083  		}, nil
  1084  	}
  1085  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  1086  		return &InstanceDiff{
  1087  			Attributes: map[string]*ResourceAttrDiff{
  1088  				"num": &ResourceAttrDiff{
  1089  					New: "bar",
  1090  				},
  1091  			},
  1092  		}, nil
  1093  	}
  1094  
  1095  	if _, err := ctx.Plan(nil); err != nil {
  1096  		t.Fatalf("err: %s", err)
  1097  	}
  1098  
  1099  	// Start the Apply in a goroutine
  1100  	stateCh := make(chan *State)
  1101  	go func() {
  1102  		state, err := ctx.Apply()
  1103  		if err != nil {
  1104  			panic(err)
  1105  		}
  1106  
  1107  		stateCh <- state
  1108  	}()
  1109  
  1110  	state := <-stateCh
  1111  
  1112  	mod := state.RootModule()
  1113  	if len(mod.Resources) != 1 {
  1114  		t.Fatalf("bad: %#v", mod.Resources)
  1115  	}
  1116  
  1117  	actual := strings.TrimSpace(state.String())
  1118  	expected := strings.TrimSpace(testTerraformApplyCancelStr)
  1119  	if actual != expected {
  1120  		t.Fatalf("bad: \n%s", actual)
  1121  	}
  1122  }
  1123  
  1124  func TestContextApply_compute(t *testing.T) {
  1125  	m := testModule(t, "apply-compute")
  1126  	p := testProvider("aws")
  1127  	p.ApplyFn = testApplyFn
  1128  	p.DiffFn = testDiffFn
  1129  	ctx := testContext(t, &ContextOpts{
  1130  		Module: m,
  1131  		Providers: map[string]ResourceProviderFactory{
  1132  			"aws": testProviderFuncFixed(p),
  1133  		},
  1134  	})
  1135  
  1136  	if _, err := ctx.Plan(nil); err != nil {
  1137  		t.Fatalf("err: %s", err)
  1138  	}
  1139  
  1140  	ctx.variables = map[string]string{"value": "1"}
  1141  
  1142  	state, err := ctx.Apply()
  1143  	if err != nil {
  1144  		t.Fatalf("err: %s", err)
  1145  	}
  1146  
  1147  	actual := strings.TrimSpace(state.String())
  1148  	expected := strings.TrimSpace(testTerraformApplyComputeStr)
  1149  	if actual != expected {
  1150  		t.Fatalf("bad: \n%s", actual)
  1151  	}
  1152  }
  1153  
  1154  func TestContextApply_countDecrease(t *testing.T) {
  1155  	m := testModule(t, "apply-count-dec")
  1156  	p := testProvider("aws")
  1157  	p.DiffFn = testDiffFn
  1158  	s := &State{
  1159  		Modules: []*ModuleState{
  1160  			&ModuleState{
  1161  				Path: rootModulePath,
  1162  				Resources: map[string]*ResourceState{
  1163  					"aws_instance.foo.0": &ResourceState{
  1164  						Type: "aws_instance",
  1165  						Primary: &InstanceState{
  1166  							ID: "bar",
  1167  							Attributes: map[string]string{
  1168  								"foo":  "foo",
  1169  								"type": "aws_instance",
  1170  							},
  1171  						},
  1172  					},
  1173  					"aws_instance.foo.1": &ResourceState{
  1174  						Type: "aws_instance",
  1175  						Primary: &InstanceState{
  1176  							ID: "bar",
  1177  							Attributes: map[string]string{
  1178  								"foo":  "foo",
  1179  								"type": "aws_instance",
  1180  							},
  1181  						},
  1182  					},
  1183  					"aws_instance.foo.2": &ResourceState{
  1184  						Type: "aws_instance",
  1185  						Primary: &InstanceState{
  1186  							ID: "bar",
  1187  							Attributes: map[string]string{
  1188  								"foo":  "foo",
  1189  								"type": "aws_instance",
  1190  							},
  1191  						},
  1192  					},
  1193  				},
  1194  			},
  1195  		},
  1196  	}
  1197  	ctx := testContext(t, &ContextOpts{
  1198  		Module: m,
  1199  		Providers: map[string]ResourceProviderFactory{
  1200  			"aws": testProviderFuncFixed(p),
  1201  		},
  1202  		State: s,
  1203  	})
  1204  
  1205  	if _, err := ctx.Plan(nil); err != nil {
  1206  		t.Fatalf("err: %s", err)
  1207  	}
  1208  
  1209  	state, err := ctx.Apply()
  1210  	if err != nil {
  1211  		t.Fatalf("err: %s", err)
  1212  	}
  1213  
  1214  	actual := strings.TrimSpace(state.String())
  1215  	expected := strings.TrimSpace(testTerraformApplyCountDecStr)
  1216  	if actual != expected {
  1217  		t.Fatalf("bad: \n%s", actual)
  1218  	}
  1219  }
  1220  
  1221  func TestContextApply_countDecreaseToOne(t *testing.T) {
  1222  	m := testModule(t, "apply-count-dec-one")
  1223  	p := testProvider("aws")
  1224  	p.DiffFn = testDiffFn
  1225  	s := &State{
  1226  		Modules: []*ModuleState{
  1227  			&ModuleState{
  1228  				Path: rootModulePath,
  1229  				Resources: map[string]*ResourceState{
  1230  					"aws_instance.foo.0": &ResourceState{
  1231  						Type: "aws_instance",
  1232  						Primary: &InstanceState{
  1233  							ID: "bar",
  1234  							Attributes: map[string]string{
  1235  								"foo":  "foo",
  1236  								"type": "aws_instance",
  1237  							},
  1238  						},
  1239  					},
  1240  					"aws_instance.foo.1": &ResourceState{
  1241  						Type: "aws_instance",
  1242  						Primary: &InstanceState{
  1243  							ID: "bar",
  1244  						},
  1245  					},
  1246  					"aws_instance.foo.2": &ResourceState{
  1247  						Type: "aws_instance",
  1248  						Primary: &InstanceState{
  1249  							ID: "bar",
  1250  						},
  1251  					},
  1252  				},
  1253  			},
  1254  		},
  1255  	}
  1256  	ctx := testContext(t, &ContextOpts{
  1257  		Module: m,
  1258  		Providers: map[string]ResourceProviderFactory{
  1259  			"aws": testProviderFuncFixed(p),
  1260  		},
  1261  		State: s,
  1262  	})
  1263  
  1264  	if _, err := ctx.Plan(nil); err != nil {
  1265  		t.Fatalf("err: %s", err)
  1266  	}
  1267  
  1268  	state, err := ctx.Apply()
  1269  	if err != nil {
  1270  		t.Fatalf("err: %s", err)
  1271  	}
  1272  
  1273  	actual := strings.TrimSpace(state.String())
  1274  	expected := strings.TrimSpace(testTerraformApplyCountDecToOneStr)
  1275  	if actual != expected {
  1276  		t.Fatalf("bad: \n%s", actual)
  1277  	}
  1278  }
  1279  
  1280  func TestContextApply_countTainted(t *testing.T) {
  1281  	m := testModule(t, "apply-count-tainted")
  1282  	p := testProvider("aws")
  1283  	p.DiffFn = testDiffFn
  1284  	s := &State{
  1285  		Modules: []*ModuleState{
  1286  			&ModuleState{
  1287  				Path: rootModulePath,
  1288  				Resources: map[string]*ResourceState{
  1289  					"aws_instance.foo.0": &ResourceState{
  1290  						Type: "aws_instance",
  1291  						Tainted: []*InstanceState{
  1292  							&InstanceState{
  1293  								ID: "bar",
  1294  								Attributes: map[string]string{
  1295  									"foo":  "foo",
  1296  									"type": "aws_instance",
  1297  								},
  1298  							},
  1299  						},
  1300  					},
  1301  				},
  1302  			},
  1303  		},
  1304  	}
  1305  	ctx := testContext(t, &ContextOpts{
  1306  		Module: m,
  1307  		Providers: map[string]ResourceProviderFactory{
  1308  			"aws": testProviderFuncFixed(p),
  1309  		},
  1310  		State: s,
  1311  	})
  1312  
  1313  	if _, err := ctx.Plan(nil); err != nil {
  1314  		t.Fatalf("err: %s", err)
  1315  	}
  1316  
  1317  	state, err := ctx.Apply()
  1318  	if err != nil {
  1319  		t.Fatalf("err: %s", err)
  1320  	}
  1321  
  1322  	actual := strings.TrimSpace(state.String())
  1323  	expected := strings.TrimSpace(testTerraformApplyCountTaintedStr)
  1324  	if actual != expected {
  1325  		t.Fatalf("bad: \n%s", actual)
  1326  	}
  1327  }
  1328  
  1329  func TestContextApply_countVariable(t *testing.T) {
  1330  	m := testModule(t, "apply-count-variable")
  1331  	p := testProvider("aws")
  1332  	p.ApplyFn = testApplyFn
  1333  	p.DiffFn = testDiffFn
  1334  	ctx := testContext(t, &ContextOpts{
  1335  		Module: m,
  1336  		Providers: map[string]ResourceProviderFactory{
  1337  			"aws": testProviderFuncFixed(p),
  1338  		},
  1339  	})
  1340  
  1341  	if _, err := ctx.Plan(nil); err != nil {
  1342  		t.Fatalf("err: %s", err)
  1343  	}
  1344  
  1345  	state, err := ctx.Apply()
  1346  	if err != nil {
  1347  		t.Fatalf("err: %s", err)
  1348  	}
  1349  
  1350  	actual := strings.TrimSpace(state.String())
  1351  	expected := strings.TrimSpace(testTerraformApplyCountVariableStr)
  1352  	if actual != expected {
  1353  		t.Fatalf("bad: \n%s", actual)
  1354  	}
  1355  }
  1356  
  1357  func TestContextApply_module(t *testing.T) {
  1358  	m := testModule(t, "apply-module")
  1359  	p := testProvider("aws")
  1360  	p.ApplyFn = testApplyFn
  1361  	p.DiffFn = testDiffFn
  1362  	ctx := testContext(t, &ContextOpts{
  1363  		Module: m,
  1364  		Providers: map[string]ResourceProviderFactory{
  1365  			"aws": testProviderFuncFixed(p),
  1366  		},
  1367  	})
  1368  
  1369  	if _, err := ctx.Plan(nil); err != nil {
  1370  		t.Fatalf("err: %s", err)
  1371  	}
  1372  
  1373  	state, err := ctx.Apply()
  1374  	if err != nil {
  1375  		t.Fatalf("err: %s", err)
  1376  	}
  1377  
  1378  	actual := strings.TrimSpace(state.String())
  1379  	expected := strings.TrimSpace(testTerraformApplyModuleStr)
  1380  	if actual != expected {
  1381  		t.Fatalf("bad: \n%s", actual)
  1382  	}
  1383  }
  1384  
  1385  func TestContextApply_nilDiff(t *testing.T) {
  1386  	m := testModule(t, "apply-good")
  1387  	p := testProvider("aws")
  1388  	p.ApplyFn = testApplyFn
  1389  	p.DiffFn = testDiffFn
  1390  	ctx := testContext(t, &ContextOpts{
  1391  		Module: m,
  1392  		Providers: map[string]ResourceProviderFactory{
  1393  			"aws": testProviderFuncFixed(p),
  1394  		},
  1395  	})
  1396  
  1397  	if _, err := ctx.Plan(nil); err != nil {
  1398  		t.Fatalf("err: %s", err)
  1399  	}
  1400  
  1401  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  1402  		return nil, nil
  1403  	}
  1404  
  1405  	if _, err := ctx.Apply(); err == nil {
  1406  		t.Fatal("should error")
  1407  	}
  1408  }
  1409  
  1410  func TestContextApply_Provisioner_compute(t *testing.T) {
  1411  	m := testModule(t, "apply-provisioner-compute")
  1412  	p := testProvider("aws")
  1413  	pr := testProvisioner()
  1414  	p.ApplyFn = testApplyFn
  1415  	p.DiffFn = testDiffFn
  1416  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  1417  		val, ok := c.Config["foo"]
  1418  		if !ok || val != "computed_dynamical" {
  1419  			t.Fatalf("bad value for foo: %v %#v", val, c)
  1420  		}
  1421  
  1422  		return nil
  1423  	}
  1424  	ctx := testContext(t, &ContextOpts{
  1425  		Module: m,
  1426  		Providers: map[string]ResourceProviderFactory{
  1427  			"aws": testProviderFuncFixed(p),
  1428  		},
  1429  		Provisioners: map[string]ResourceProvisionerFactory{
  1430  			"shell": testProvisionerFuncFixed(pr),
  1431  		},
  1432  		Variables: map[string]string{
  1433  			"value": "1",
  1434  		},
  1435  	})
  1436  
  1437  	if _, err := ctx.Plan(nil); err != nil {
  1438  		t.Fatalf("err: %s", err)
  1439  	}
  1440  
  1441  	state, err := ctx.Apply()
  1442  	if err != nil {
  1443  		t.Fatalf("err: %s", err)
  1444  	}
  1445  
  1446  	actual := strings.TrimSpace(state.String())
  1447  	expected := strings.TrimSpace(testTerraformApplyProvisionerStr)
  1448  	if actual != expected {
  1449  		t.Fatalf("bad: \n%s", actual)
  1450  	}
  1451  
  1452  	// Verify apply was invoked
  1453  	if !pr.ApplyCalled {
  1454  		t.Fatalf("provisioner not invoked")
  1455  	}
  1456  }
  1457  
  1458  func TestContextApply_provisionerCreateFail(t *testing.T) {
  1459  	m := testModule(t, "apply-provisioner-fail-create")
  1460  	p := testProvider("aws")
  1461  	pr := testProvisioner()
  1462  	p.DiffFn = testDiffFn
  1463  
  1464  	p.ApplyFn = func(
  1465  		info *InstanceInfo,
  1466  		is *InstanceState,
  1467  		id *InstanceDiff) (*InstanceState, error) {
  1468  		is.ID = "foo"
  1469  		return is, fmt.Errorf("error")
  1470  	}
  1471  
  1472  	ctx := testContext(t, &ContextOpts{
  1473  		Module: m,
  1474  		Providers: map[string]ResourceProviderFactory{
  1475  			"aws": testProviderFuncFixed(p),
  1476  		},
  1477  		Provisioners: map[string]ResourceProvisionerFactory{
  1478  			"shell": testProvisionerFuncFixed(pr),
  1479  		},
  1480  	})
  1481  
  1482  	if _, err := ctx.Plan(nil); err != nil {
  1483  		t.Fatalf("err: %s", err)
  1484  	}
  1485  
  1486  	state, err := ctx.Apply()
  1487  	if err == nil {
  1488  		t.Fatal("should error")
  1489  	}
  1490  
  1491  	actual := strings.TrimSpace(state.String())
  1492  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailCreateStr)
  1493  	if actual != expected {
  1494  		t.Fatalf("bad: \n%s", actual)
  1495  	}
  1496  }
  1497  
  1498  func TestContextApply_provisionerCreateFailNoId(t *testing.T) {
  1499  	m := testModule(t, "apply-provisioner-fail-create")
  1500  	p := testProvider("aws")
  1501  	pr := testProvisioner()
  1502  	p.DiffFn = testDiffFn
  1503  
  1504  	p.ApplyFn = func(
  1505  		info *InstanceInfo,
  1506  		is *InstanceState,
  1507  		id *InstanceDiff) (*InstanceState, error) {
  1508  		return nil, fmt.Errorf("error")
  1509  	}
  1510  
  1511  	ctx := testContext(t, &ContextOpts{
  1512  		Module: m,
  1513  		Providers: map[string]ResourceProviderFactory{
  1514  			"aws": testProviderFuncFixed(p),
  1515  		},
  1516  		Provisioners: map[string]ResourceProvisionerFactory{
  1517  			"shell": testProvisionerFuncFixed(pr),
  1518  		},
  1519  	})
  1520  
  1521  	if _, err := ctx.Plan(nil); err != nil {
  1522  		t.Fatalf("err: %s", err)
  1523  	}
  1524  
  1525  	state, err := ctx.Apply()
  1526  	if err == nil {
  1527  		t.Fatal("should error")
  1528  	}
  1529  
  1530  	actual := strings.TrimSpace(state.String())
  1531  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailCreateNoIdStr)
  1532  	if actual != expected {
  1533  		t.Fatalf("bad: \n%s", actual)
  1534  	}
  1535  }
  1536  
  1537  func TestContextApply_provisionerFail(t *testing.T) {
  1538  	m := testModule(t, "apply-provisioner-fail")
  1539  	p := testProvider("aws")
  1540  	pr := testProvisioner()
  1541  	p.ApplyFn = testApplyFn
  1542  	p.DiffFn = testDiffFn
  1543  
  1544  	pr.ApplyFn = func(*InstanceState, *ResourceConfig) error {
  1545  		return fmt.Errorf("EXPLOSION")
  1546  	}
  1547  
  1548  	ctx := testContext(t, &ContextOpts{
  1549  		Module: m,
  1550  		Providers: map[string]ResourceProviderFactory{
  1551  			"aws": testProviderFuncFixed(p),
  1552  		},
  1553  		Provisioners: map[string]ResourceProvisionerFactory{
  1554  			"shell": testProvisionerFuncFixed(pr),
  1555  		},
  1556  		Variables: map[string]string{
  1557  			"value": "1",
  1558  		},
  1559  	})
  1560  
  1561  	if _, err := ctx.Plan(nil); err != nil {
  1562  		t.Fatalf("err: %s", err)
  1563  	}
  1564  
  1565  	state, err := ctx.Apply()
  1566  	if err == nil {
  1567  		t.Fatal("should error")
  1568  	}
  1569  
  1570  	actual := strings.TrimSpace(state.String())
  1571  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailStr)
  1572  	if actual != expected {
  1573  		t.Fatalf("bad: \n%s", actual)
  1574  	}
  1575  }
  1576  
  1577  func TestContextApply_provisionerFail_createBeforeDestroy(t *testing.T) {
  1578  	m := testModule(t, "apply-provisioner-fail-create-before")
  1579  	p := testProvider("aws")
  1580  	pr := testProvisioner()
  1581  	p.ApplyFn = testApplyFn
  1582  	p.DiffFn = testDiffFn
  1583  	pr.ApplyFn = func(*InstanceState, *ResourceConfig) error {
  1584  		return fmt.Errorf("EXPLOSION")
  1585  	}
  1586  
  1587  	state := &State{
  1588  		Modules: []*ModuleState{
  1589  			&ModuleState{
  1590  				Path: rootModulePath,
  1591  				Resources: map[string]*ResourceState{
  1592  					"aws_instance.bar": &ResourceState{
  1593  						Type: "aws_instance",
  1594  						Primary: &InstanceState{
  1595  							ID: "bar",
  1596  							Attributes: map[string]string{
  1597  								"require_new": "abc",
  1598  							},
  1599  						},
  1600  					},
  1601  				},
  1602  			},
  1603  		},
  1604  	}
  1605  	ctx := testContext(t, &ContextOpts{
  1606  		Module: m,
  1607  		Providers: map[string]ResourceProviderFactory{
  1608  			"aws": testProviderFuncFixed(p),
  1609  		},
  1610  		Provisioners: map[string]ResourceProvisionerFactory{
  1611  			"shell": testProvisionerFuncFixed(pr),
  1612  		},
  1613  		State: state,
  1614  	})
  1615  
  1616  	if _, err := ctx.Plan(nil); err != nil {
  1617  		t.Fatalf("err: %s", err)
  1618  	}
  1619  
  1620  	state, err := ctx.Apply()
  1621  	if err == nil {
  1622  		t.Fatal("should error")
  1623  	}
  1624  
  1625  	actual := strings.TrimSpace(state.String())
  1626  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailCreateBeforeDestroyStr)
  1627  	if actual != expected {
  1628  		t.Fatalf("bad: \n%s", actual)
  1629  	}
  1630  }
  1631  
  1632  func TestContextApply_error_createBeforeDestroy(t *testing.T) {
  1633  	m := testModule(t, "apply-error-create-before")
  1634  	p := testProvider("aws")
  1635  	state := &State{
  1636  		Modules: []*ModuleState{
  1637  			&ModuleState{
  1638  				Path: rootModulePath,
  1639  				Resources: map[string]*ResourceState{
  1640  					"aws_instance.bar": &ResourceState{
  1641  						Type: "aws_instance",
  1642  						Primary: &InstanceState{
  1643  							ID: "bar",
  1644  							Attributes: map[string]string{
  1645  								"require_new": "abc",
  1646  							},
  1647  						},
  1648  					},
  1649  				},
  1650  			},
  1651  		},
  1652  	}
  1653  	ctx := testContext(t, &ContextOpts{
  1654  		Module: m,
  1655  		Providers: map[string]ResourceProviderFactory{
  1656  			"aws": testProviderFuncFixed(p),
  1657  		},
  1658  		State: state,
  1659  	})
  1660  	p.ApplyFn = func(info *InstanceInfo, is *InstanceState, id *InstanceDiff) (*InstanceState, error) {
  1661  		return nil, fmt.Errorf("error")
  1662  	}
  1663  	p.DiffFn = testDiffFn
  1664  
  1665  	if _, err := ctx.Plan(nil); err != nil {
  1666  		t.Fatalf("err: %s", err)
  1667  	}
  1668  
  1669  	state, err := ctx.Apply()
  1670  	if err == nil {
  1671  		t.Fatal("should have error")
  1672  	}
  1673  
  1674  	actual := strings.TrimSpace(state.String())
  1675  	expected := strings.TrimSpace(testTerraformApplyErrorCreateBeforeDestroyStr)
  1676  	if actual != expected {
  1677  		t.Fatalf("bad: \n%s\n\n\n%s", actual, expected)
  1678  	}
  1679  }
  1680  
  1681  func TestContextApply_errorDestroy_createBeforeDestroy(t *testing.T) {
  1682  	m := testModule(t, "apply-error-create-before")
  1683  	p := testProvider("aws")
  1684  	state := &State{
  1685  		Modules: []*ModuleState{
  1686  			&ModuleState{
  1687  				Path: rootModulePath,
  1688  				Resources: map[string]*ResourceState{
  1689  					"aws_instance.bar": &ResourceState{
  1690  						Type: "aws_instance",
  1691  						Primary: &InstanceState{
  1692  							ID: "bar",
  1693  							Attributes: map[string]string{
  1694  								"require_new": "abc",
  1695  							},
  1696  						},
  1697  					},
  1698  				},
  1699  			},
  1700  		},
  1701  	}
  1702  	ctx := testContext(t, &ContextOpts{
  1703  		Module: m,
  1704  		Providers: map[string]ResourceProviderFactory{
  1705  			"aws": testProviderFuncFixed(p),
  1706  		},
  1707  		State: state,
  1708  	})
  1709  	p.ApplyFn = func(info *InstanceInfo, is *InstanceState, id *InstanceDiff) (*InstanceState, error) {
  1710  		// Fail the destroy!
  1711  		if id.Destroy {
  1712  			return is, fmt.Errorf("error")
  1713  		}
  1714  
  1715  		// Create should work
  1716  		is = &InstanceState{
  1717  			ID: "foo",
  1718  		}
  1719  		return is, nil
  1720  	}
  1721  	p.DiffFn = testDiffFn
  1722  
  1723  	if _, err := ctx.Plan(nil); err != nil {
  1724  		t.Fatalf("err: %s", err)
  1725  	}
  1726  
  1727  	state, err := ctx.Apply()
  1728  	if err == nil {
  1729  		t.Fatal("should have error")
  1730  	}
  1731  
  1732  	actual := strings.TrimSpace(state.String())
  1733  	expected := strings.TrimSpace(testTerraformApplyErrorDestroyCreateBeforeDestroyStr)
  1734  	if actual != expected {
  1735  		t.Fatalf("bad: actual:\n%s\n\nexpected:\n%s", actual, expected)
  1736  	}
  1737  }
  1738  
  1739  func TestContextApply_provisionerResourceRef(t *testing.T) {
  1740  	m := testModule(t, "apply-provisioner-resource-ref")
  1741  	p := testProvider("aws")
  1742  	pr := testProvisioner()
  1743  	p.ApplyFn = testApplyFn
  1744  	p.DiffFn = testDiffFn
  1745  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  1746  		val, ok := c.Config["foo"]
  1747  		if !ok || val != "2" {
  1748  			t.Fatalf("bad value for foo: %v %#v", val, c)
  1749  		}
  1750  
  1751  		return nil
  1752  	}
  1753  
  1754  	ctx := testContext(t, &ContextOpts{
  1755  		Module: m,
  1756  		Providers: map[string]ResourceProviderFactory{
  1757  			"aws": testProviderFuncFixed(p),
  1758  		},
  1759  		Provisioners: map[string]ResourceProvisionerFactory{
  1760  			"shell": testProvisionerFuncFixed(pr),
  1761  		},
  1762  	})
  1763  
  1764  	if _, err := ctx.Plan(nil); err != nil {
  1765  		t.Fatalf("err: %s", err)
  1766  	}
  1767  
  1768  	state, err := ctx.Apply()
  1769  	if err != nil {
  1770  		t.Fatalf("err: %s", err)
  1771  	}
  1772  
  1773  	actual := strings.TrimSpace(state.String())
  1774  	expected := strings.TrimSpace(testTerraformApplyProvisionerResourceRefStr)
  1775  	if actual != expected {
  1776  		t.Fatalf("bad: \n%s", actual)
  1777  	}
  1778  
  1779  	// Verify apply was invoked
  1780  	if !pr.ApplyCalled {
  1781  		t.Fatalf("provisioner not invoked")
  1782  	}
  1783  }
  1784  
  1785  // Provisioner should NOT run on a diff, only create
  1786  func TestContextApply_Provisioner_Diff(t *testing.T) {
  1787  	m := testModule(t, "apply-provisioner-diff")
  1788  	p := testProvider("aws")
  1789  	pr := testProvisioner()
  1790  	p.ApplyFn = testApplyFn
  1791  	p.DiffFn = testDiffFn
  1792  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  1793  		return nil
  1794  	}
  1795  	ctx := testContext(t, &ContextOpts{
  1796  		Module: m,
  1797  		Providers: map[string]ResourceProviderFactory{
  1798  			"aws": testProviderFuncFixed(p),
  1799  		},
  1800  		Provisioners: map[string]ResourceProvisionerFactory{
  1801  			"shell": testProvisionerFuncFixed(pr),
  1802  		},
  1803  	})
  1804  
  1805  	if _, err := ctx.Plan(nil); err != nil {
  1806  		t.Fatalf("err: %s", err)
  1807  	}
  1808  
  1809  	state, err := ctx.Apply()
  1810  	if err != nil {
  1811  		t.Fatalf("err: %s", err)
  1812  	}
  1813  
  1814  	actual := strings.TrimSpace(state.String())
  1815  	expected := strings.TrimSpace(testTerraformApplyProvisionerDiffStr)
  1816  	if actual != expected {
  1817  		t.Fatalf("bad: \n%s", actual)
  1818  	}
  1819  
  1820  	// Verify apply was invoked
  1821  	if !pr.ApplyCalled {
  1822  		t.Fatalf("provisioner not invoked")
  1823  	}
  1824  	pr.ApplyCalled = false
  1825  
  1826  	// Change the state to force a diff
  1827  	mod := state.RootModule()
  1828  	mod.Resources["aws_instance.bar"].Primary.Attributes["foo"] = "baz"
  1829  
  1830  	// Re-create context with state
  1831  	ctx = testContext(t, &ContextOpts{
  1832  		Module: m,
  1833  		Providers: map[string]ResourceProviderFactory{
  1834  			"aws": testProviderFuncFixed(p),
  1835  		},
  1836  		Provisioners: map[string]ResourceProvisionerFactory{
  1837  			"shell": testProvisionerFuncFixed(pr),
  1838  		},
  1839  		State: state,
  1840  	})
  1841  
  1842  	if _, err := ctx.Plan(nil); err != nil {
  1843  		t.Fatalf("err: %s", err)
  1844  	}
  1845  
  1846  	state2, err := ctx.Apply()
  1847  	if err != nil {
  1848  		t.Fatalf("err: %s", err)
  1849  	}
  1850  
  1851  	actual = strings.TrimSpace(state2.String())
  1852  	if actual != expected {
  1853  		t.Fatalf("bad: \n%s", actual)
  1854  	}
  1855  
  1856  	// Verify apply was NOT invoked
  1857  	if pr.ApplyCalled {
  1858  		t.Fatalf("provisioner invoked")
  1859  	}
  1860  }
  1861  
  1862  func TestContextApply_outputDiffVars(t *testing.T) {
  1863  	m := testModule(t, "apply-good")
  1864  	p := testProvider("aws")
  1865  	s := &State{
  1866  		Modules: []*ModuleState{
  1867  			&ModuleState{
  1868  				Path: rootModulePath,
  1869  				Resources: map[string]*ResourceState{
  1870  					"aws_instance.baz": &ResourceState{
  1871  						Type: "aws_instance",
  1872  						Primary: &InstanceState{
  1873  							ID: "bar",
  1874  						},
  1875  					},
  1876  				},
  1877  			},
  1878  		},
  1879  	}
  1880  	ctx := testContext(t, &ContextOpts{
  1881  		Module: m,
  1882  		Providers: map[string]ResourceProviderFactory{
  1883  			"aws": testProviderFuncFixed(p),
  1884  		},
  1885  		State: s,
  1886  	})
  1887  
  1888  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  1889  		for k, ad := range d.Attributes {
  1890  			if ad.NewComputed {
  1891  				return nil, fmt.Errorf("%s: computed", k)
  1892  			}
  1893  		}
  1894  
  1895  		result := s.MergeDiff(d)
  1896  		result.ID = "foo"
  1897  		return result, nil
  1898  	}
  1899  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  1900  		return &InstanceDiff{
  1901  			Attributes: map[string]*ResourceAttrDiff{
  1902  				"foo": &ResourceAttrDiff{
  1903  					NewComputed: true,
  1904  					Type:        DiffAttrOutput,
  1905  				},
  1906  				"bar": &ResourceAttrDiff{
  1907  					New: "baz",
  1908  				},
  1909  			},
  1910  		}, nil
  1911  	}
  1912  
  1913  	if _, err := ctx.Plan(nil); err != nil {
  1914  		t.Fatalf("err: %s", err)
  1915  	}
  1916  	if _, err := ctx.Apply(); err != nil {
  1917  		t.Fatalf("err: %s", err)
  1918  	}
  1919  }
  1920  
  1921  func TestContextApply_Provisioner_ConnInfo(t *testing.T) {
  1922  	m := testModule(t, "apply-provisioner-conninfo")
  1923  	p := testProvider("aws")
  1924  	pr := testProvisioner()
  1925  
  1926  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  1927  		if s.Ephemeral.ConnInfo == nil {
  1928  			t.Fatalf("ConnInfo not initialized")
  1929  		}
  1930  
  1931  		result, _ := testApplyFn(info, s, d)
  1932  		result.Ephemeral.ConnInfo = map[string]string{
  1933  			"type": "ssh",
  1934  			"host": "127.0.0.1",
  1935  			"port": "22",
  1936  		}
  1937  		return result, nil
  1938  	}
  1939  	p.DiffFn = testDiffFn
  1940  
  1941  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  1942  		conn := rs.Ephemeral.ConnInfo
  1943  		if conn["type"] != "telnet" {
  1944  			t.Fatalf("Bad: %#v", conn)
  1945  		}
  1946  		if conn["host"] != "127.0.0.1" {
  1947  			t.Fatalf("Bad: %#v", conn)
  1948  		}
  1949  		if conn["port"] != "2222" {
  1950  			t.Fatalf("Bad: %#v", conn)
  1951  		}
  1952  		if conn["user"] != "superuser" {
  1953  			t.Fatalf("Bad: %#v", conn)
  1954  		}
  1955  		if conn["pass"] != "test" {
  1956  			t.Fatalf("Bad: %#v", conn)
  1957  		}
  1958  
  1959  		return nil
  1960  	}
  1961  
  1962  	ctx := testContext(t, &ContextOpts{
  1963  		Module: m,
  1964  		Providers: map[string]ResourceProviderFactory{
  1965  			"aws": testProviderFuncFixed(p),
  1966  		},
  1967  		Provisioners: map[string]ResourceProvisionerFactory{
  1968  			"shell": testProvisionerFuncFixed(pr),
  1969  		},
  1970  		Variables: map[string]string{
  1971  			"value": "1",
  1972  			"pass":  "test",
  1973  		},
  1974  	})
  1975  
  1976  	if _, err := ctx.Plan(nil); err != nil {
  1977  		t.Fatalf("err: %s", err)
  1978  	}
  1979  
  1980  	state, err := ctx.Apply()
  1981  	if err != nil {
  1982  		t.Fatalf("err: %s", err)
  1983  	}
  1984  
  1985  	actual := strings.TrimSpace(state.String())
  1986  	expected := strings.TrimSpace(testTerraformApplyProvisionerStr)
  1987  	if actual != expected {
  1988  		t.Fatalf("bad: \n%s", actual)
  1989  	}
  1990  
  1991  	// Verify apply was invoked
  1992  	if !pr.ApplyCalled {
  1993  		t.Fatalf("provisioner not invoked")
  1994  	}
  1995  }
  1996  
  1997  func TestContextApply_destroy(t *testing.T) {
  1998  	m := testModule(t, "apply-destroy")
  1999  	h := new(HookRecordApplyOrder)
  2000  	p := testProvider("aws")
  2001  	p.ApplyFn = testApplyFn
  2002  	p.DiffFn = testDiffFn
  2003  	ctx := testContext(t, &ContextOpts{
  2004  		Module: m,
  2005  		Hooks:  []Hook{h},
  2006  		Providers: map[string]ResourceProviderFactory{
  2007  			"aws": testProviderFuncFixed(p),
  2008  		},
  2009  	})
  2010  
  2011  	// First plan and apply a create operation
  2012  	if _, err := ctx.Plan(nil); err != nil {
  2013  		t.Fatalf("err: %s", err)
  2014  	}
  2015  
  2016  	if _, err := ctx.Apply(); err != nil {
  2017  		t.Fatalf("err: %s", err)
  2018  	}
  2019  
  2020  	// Next, plan and apply a destroy operation
  2021  	if _, err := ctx.Plan(&PlanOpts{Destroy: true}); err != nil {
  2022  		t.Fatalf("err: %s", err)
  2023  	}
  2024  
  2025  	h.Active = true
  2026  
  2027  	state, err := ctx.Apply()
  2028  	if err != nil {
  2029  		t.Fatalf("err: %s", err)
  2030  	}
  2031  
  2032  	// Test that things were destroyed
  2033  	actual := strings.TrimSpace(state.String())
  2034  	expected := strings.TrimSpace(testTerraformApplyDestroyStr)
  2035  	if actual != expected {
  2036  		t.Fatalf("bad: \n%s", actual)
  2037  	}
  2038  
  2039  	// Test that things were destroyed _in the right order_
  2040  	expected2 := []string{"aws_instance.bar", "aws_instance.foo"}
  2041  	actual2 := h.IDs
  2042  	if !reflect.DeepEqual(actual2, expected2) {
  2043  		t.Fatalf("bad: %#v", actual2)
  2044  	}
  2045  }
  2046  
  2047  func TestContextApply_destroyOutputs(t *testing.T) {
  2048  	m := testModule(t, "apply-destroy-outputs")
  2049  	h := new(HookRecordApplyOrder)
  2050  	p := testProvider("aws")
  2051  	p.ApplyFn = testApplyFn
  2052  	p.DiffFn = testDiffFn
  2053  	ctx := testContext(t, &ContextOpts{
  2054  		Module: m,
  2055  		Hooks:  []Hook{h},
  2056  		Providers: map[string]ResourceProviderFactory{
  2057  			"aws": testProviderFuncFixed(p),
  2058  		},
  2059  	})
  2060  
  2061  	// First plan and apply a create operation
  2062  	if _, err := ctx.Plan(nil); err != nil {
  2063  		t.Fatalf("err: %s", err)
  2064  	}
  2065  
  2066  	if _, err := ctx.Apply(); err != nil {
  2067  		t.Fatalf("err: %s", err)
  2068  	}
  2069  
  2070  	// Next, plan and apply a destroy operation
  2071  	if _, err := ctx.Plan(&PlanOpts{Destroy: true}); err != nil {
  2072  		t.Fatalf("err: %s", err)
  2073  	}
  2074  
  2075  	h.Active = true
  2076  
  2077  	state, err := ctx.Apply()
  2078  	if err != nil {
  2079  		t.Fatalf("err: %s", err)
  2080  	}
  2081  
  2082  	mod := state.RootModule()
  2083  	if len(mod.Resources) > 0 {
  2084  		t.Fatalf("bad: %#v", mod)
  2085  	}
  2086  }
  2087  
  2088  func TestContextApply_destroyOrphan(t *testing.T) {
  2089  	m := testModule(t, "apply-error")
  2090  	p := testProvider("aws")
  2091  	s := &State{
  2092  		Modules: []*ModuleState{
  2093  			&ModuleState{
  2094  				Path: rootModulePath,
  2095  				Resources: map[string]*ResourceState{
  2096  					"aws_instance.baz": &ResourceState{
  2097  						Type: "aws_instance",
  2098  						Primary: &InstanceState{
  2099  							ID: "bar",
  2100  						},
  2101  					},
  2102  				},
  2103  			},
  2104  		},
  2105  	}
  2106  	ctx := testContext(t, &ContextOpts{
  2107  		Module: m,
  2108  		Providers: map[string]ResourceProviderFactory{
  2109  			"aws": testProviderFuncFixed(p),
  2110  		},
  2111  		State: s,
  2112  	})
  2113  
  2114  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  2115  		if d.Destroy {
  2116  			return nil, nil
  2117  		}
  2118  
  2119  		result := s.MergeDiff(d)
  2120  		result.ID = "foo"
  2121  		return result, nil
  2122  	}
  2123  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  2124  		return &InstanceDiff{
  2125  			Attributes: map[string]*ResourceAttrDiff{
  2126  				"num": &ResourceAttrDiff{
  2127  					New: "bar",
  2128  				},
  2129  			},
  2130  		}, nil
  2131  	}
  2132  
  2133  	if _, err := ctx.Plan(nil); err != nil {
  2134  		t.Fatalf("err: %s", err)
  2135  	}
  2136  
  2137  	state, err := ctx.Apply()
  2138  	if err != nil {
  2139  		t.Fatalf("err: %s", err)
  2140  	}
  2141  
  2142  	mod := state.RootModule()
  2143  	if _, ok := mod.Resources["aws_instance.baz"]; ok {
  2144  		t.Fatalf("bad: %#v", mod.Resources)
  2145  	}
  2146  }
  2147  
  2148  func TestContextApply_destroyTaintedProvisioner(t *testing.T) {
  2149  	m := testModule(t, "apply-destroy-provisioner")
  2150  	p := testProvider("aws")
  2151  	pr := testProvisioner()
  2152  	p.ApplyFn = testApplyFn
  2153  	p.DiffFn = testDiffFn
  2154  
  2155  	called := false
  2156  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  2157  		called = true
  2158  		return nil
  2159  	}
  2160  
  2161  	s := &State{
  2162  		Modules: []*ModuleState{
  2163  			&ModuleState{
  2164  				Path: rootModulePath,
  2165  				Resources: map[string]*ResourceState{
  2166  					"aws_instance.foo": &ResourceState{
  2167  						Type: "aws_instance",
  2168  						Tainted: []*InstanceState{
  2169  							&InstanceState{
  2170  								ID: "bar",
  2171  								Attributes: map[string]string{
  2172  									"id": "bar",
  2173  								},
  2174  							},
  2175  						},
  2176  					},
  2177  				},
  2178  			},
  2179  		},
  2180  	}
  2181  
  2182  	ctx := testContext(t, &ContextOpts{
  2183  		Module: m,
  2184  		Providers: map[string]ResourceProviderFactory{
  2185  			"aws": testProviderFuncFixed(p),
  2186  		},
  2187  		Provisioners: map[string]ResourceProvisionerFactory{
  2188  			"shell": testProvisionerFuncFixed(pr),
  2189  		},
  2190  		State: s,
  2191  	})
  2192  
  2193  	if _, err := ctx.Plan(&PlanOpts{Destroy: true}); err != nil {
  2194  		t.Fatalf("err: %s", err)
  2195  	}
  2196  
  2197  	state, err := ctx.Apply()
  2198  	if err != nil {
  2199  		t.Fatalf("err: %s", err)
  2200  	}
  2201  
  2202  	if called {
  2203  		t.Fatal("provisioner should not be called")
  2204  	}
  2205  
  2206  	actual := strings.TrimSpace(state.String())
  2207  	expected := strings.TrimSpace("<no state>")
  2208  	if actual != expected {
  2209  		t.Fatalf("bad: \n%s", actual)
  2210  	}
  2211  }
  2212  
  2213  func TestContextApply_error(t *testing.T) {
  2214  	errored := false
  2215  
  2216  	m := testModule(t, "apply-error")
  2217  	p := testProvider("aws")
  2218  	ctx := testContext(t, &ContextOpts{
  2219  		Module: m,
  2220  		Providers: map[string]ResourceProviderFactory{
  2221  			"aws": testProviderFuncFixed(p),
  2222  		},
  2223  	})
  2224  
  2225  	p.ApplyFn = func(*InstanceInfo, *InstanceState, *InstanceDiff) (*InstanceState, error) {
  2226  		if errored {
  2227  			state := &InstanceState{
  2228  				ID: "bar",
  2229  			}
  2230  			return state, fmt.Errorf("error")
  2231  		}
  2232  		errored = true
  2233  
  2234  		return &InstanceState{
  2235  			ID: "foo",
  2236  			Attributes: map[string]string{
  2237  				"num": "2",
  2238  			},
  2239  		}, nil
  2240  	}
  2241  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  2242  		return &InstanceDiff{
  2243  			Attributes: map[string]*ResourceAttrDiff{
  2244  				"num": &ResourceAttrDiff{
  2245  					New: "bar",
  2246  				},
  2247  			},
  2248  		}, nil
  2249  	}
  2250  
  2251  	if _, err := ctx.Plan(nil); err != nil {
  2252  		t.Fatalf("err: %s", err)
  2253  	}
  2254  
  2255  	state, err := ctx.Apply()
  2256  	if err == nil {
  2257  		t.Fatal("should have error")
  2258  	}
  2259  
  2260  	actual := strings.TrimSpace(state.String())
  2261  	expected := strings.TrimSpace(testTerraformApplyErrorStr)
  2262  	if actual != expected {
  2263  		t.Fatalf("bad: \n%s", actual)
  2264  	}
  2265  }
  2266  
  2267  func TestContextApply_errorPartial(t *testing.T) {
  2268  	errored := false
  2269  
  2270  	m := testModule(t, "apply-error")
  2271  	p := testProvider("aws")
  2272  	s := &State{
  2273  		Modules: []*ModuleState{
  2274  			&ModuleState{
  2275  				Path: rootModulePath,
  2276  				Resources: map[string]*ResourceState{
  2277  					"aws_instance.bar": &ResourceState{
  2278  						Type: "aws_instance",
  2279  						Primary: &InstanceState{
  2280  							ID: "bar",
  2281  						},
  2282  					},
  2283  				},
  2284  			},
  2285  		},
  2286  	}
  2287  	ctx := testContext(t, &ContextOpts{
  2288  		Module: m,
  2289  		Providers: map[string]ResourceProviderFactory{
  2290  			"aws": testProviderFuncFixed(p),
  2291  		},
  2292  		State: s,
  2293  	})
  2294  
  2295  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  2296  		if errored {
  2297  			return s, fmt.Errorf("error")
  2298  		}
  2299  		errored = true
  2300  
  2301  		return &InstanceState{
  2302  			ID: "foo",
  2303  			Attributes: map[string]string{
  2304  				"num": "2",
  2305  			},
  2306  		}, nil
  2307  	}
  2308  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  2309  		return &InstanceDiff{
  2310  			Attributes: map[string]*ResourceAttrDiff{
  2311  				"num": &ResourceAttrDiff{
  2312  					New: "bar",
  2313  				},
  2314  			},
  2315  		}, nil
  2316  	}
  2317  
  2318  	if _, err := ctx.Plan(nil); err != nil {
  2319  		t.Fatalf("err: %s", err)
  2320  	}
  2321  
  2322  	state, err := ctx.Apply()
  2323  	if err == nil {
  2324  		t.Fatal("should have error")
  2325  	}
  2326  
  2327  	mod := state.RootModule()
  2328  	if len(mod.Resources) != 2 {
  2329  		t.Fatalf("bad: %#v", mod.Resources)
  2330  	}
  2331  
  2332  	actual := strings.TrimSpace(state.String())
  2333  	expected := strings.TrimSpace(testTerraformApplyErrorPartialStr)
  2334  	if actual != expected {
  2335  		t.Fatalf("bad: \n%s", actual)
  2336  	}
  2337  }
  2338  
  2339  func TestContextApply_hook(t *testing.T) {
  2340  	m := testModule(t, "apply-good")
  2341  	h := new(MockHook)
  2342  	p := testProvider("aws")
  2343  	p.ApplyFn = testApplyFn
  2344  	p.DiffFn = testDiffFn
  2345  	ctx := testContext(t, &ContextOpts{
  2346  		Module: m,
  2347  		Hooks:  []Hook{h},
  2348  		Providers: map[string]ResourceProviderFactory{
  2349  			"aws": testProviderFuncFixed(p),
  2350  		},
  2351  	})
  2352  
  2353  	if _, err := ctx.Plan(nil); err != nil {
  2354  		t.Fatalf("err: %s", err)
  2355  	}
  2356  
  2357  	if _, err := ctx.Apply(); err != nil {
  2358  		t.Fatalf("err: %s", err)
  2359  	}
  2360  
  2361  	if !h.PreApplyCalled {
  2362  		t.Fatal("should be called")
  2363  	}
  2364  	if !h.PostApplyCalled {
  2365  		t.Fatal("should be called")
  2366  	}
  2367  }
  2368  
  2369  func TestContextApply_idAttr(t *testing.T) {
  2370  	m := testModule(t, "apply-idattr")
  2371  	p := testProvider("aws")
  2372  	ctx := testContext(t, &ContextOpts{
  2373  		Module: m,
  2374  		Providers: map[string]ResourceProviderFactory{
  2375  			"aws": testProviderFuncFixed(p),
  2376  		},
  2377  	})
  2378  
  2379  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  2380  		result := s.MergeDiff(d)
  2381  		result.ID = "foo"
  2382  		result.Attributes = map[string]string{
  2383  			"id": "bar",
  2384  		}
  2385  
  2386  		return result, nil
  2387  	}
  2388  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  2389  		return &InstanceDiff{
  2390  			Attributes: map[string]*ResourceAttrDiff{
  2391  				"num": &ResourceAttrDiff{
  2392  					New: "bar",
  2393  				},
  2394  			},
  2395  		}, nil
  2396  	}
  2397  
  2398  	if _, err := ctx.Plan(nil); err != nil {
  2399  		t.Fatalf("err: %s", err)
  2400  	}
  2401  
  2402  	state, err := ctx.Apply()
  2403  	if err != nil {
  2404  		t.Fatalf("err: %s", err)
  2405  	}
  2406  
  2407  	mod := state.RootModule()
  2408  	rs, ok := mod.Resources["aws_instance.foo"]
  2409  	if !ok {
  2410  		t.Fatal("not in state")
  2411  	}
  2412  	if rs.Primary.ID != "foo" {
  2413  		t.Fatalf("bad: %#v", rs.Primary.ID)
  2414  	}
  2415  	if rs.Primary.Attributes["id"] != "foo" {
  2416  		t.Fatalf("bad: %#v", rs.Primary.Attributes)
  2417  	}
  2418  }
  2419  
  2420  func TestContextApply_output(t *testing.T) {
  2421  	m := testModule(t, "apply-output")
  2422  	p := testProvider("aws")
  2423  	p.ApplyFn = testApplyFn
  2424  	p.DiffFn = testDiffFn
  2425  	ctx := testContext(t, &ContextOpts{
  2426  		Module: m,
  2427  		Providers: map[string]ResourceProviderFactory{
  2428  			"aws": testProviderFuncFixed(p),
  2429  		},
  2430  	})
  2431  
  2432  	if _, err := ctx.Plan(nil); err != nil {
  2433  		t.Fatalf("err: %s", err)
  2434  	}
  2435  
  2436  	state, err := ctx.Apply()
  2437  	if err != nil {
  2438  		t.Fatalf("err: %s", err)
  2439  	}
  2440  
  2441  	actual := strings.TrimSpace(state.String())
  2442  	expected := strings.TrimSpace(testTerraformApplyOutputStr)
  2443  	if actual != expected {
  2444  		t.Fatalf("bad: \n%s", actual)
  2445  	}
  2446  }
  2447  
  2448  func TestContextApply_outputInvalid(t *testing.T) {
  2449  	m := testModule(t, "apply-output-invalid")
  2450  	p := testProvider("aws")
  2451  	p.ApplyFn = testApplyFn
  2452  	p.DiffFn = testDiffFn
  2453  	ctx := testContext(t, &ContextOpts{
  2454  		Module: m,
  2455  		Providers: map[string]ResourceProviderFactory{
  2456  			"aws": testProviderFuncFixed(p),
  2457  		},
  2458  	})
  2459  
  2460  	_, err := ctx.Plan(nil)
  2461  	if err == nil {
  2462  		t.Fatalf("err: %s", err)
  2463  	}
  2464  	if !strings.Contains(err.Error(), "is not a string") {
  2465  		t.Fatalf("err: %s", err)
  2466  	}
  2467  }
  2468  
  2469  func TestContextApply_outputList(t *testing.T) {
  2470  	m := testModule(t, "apply-output-list")
  2471  	p := testProvider("aws")
  2472  	p.ApplyFn = testApplyFn
  2473  	p.DiffFn = testDiffFn
  2474  	ctx := testContext(t, &ContextOpts{
  2475  		Module: m,
  2476  		Providers: map[string]ResourceProviderFactory{
  2477  			"aws": testProviderFuncFixed(p),
  2478  		},
  2479  	})
  2480  
  2481  	if _, err := ctx.Plan(nil); err != nil {
  2482  		t.Fatalf("err: %s", err)
  2483  	}
  2484  
  2485  	state, err := ctx.Apply()
  2486  	if err != nil {
  2487  		t.Fatalf("err: %s", err)
  2488  	}
  2489  
  2490  	actual := strings.TrimSpace(state.String())
  2491  	expected := strings.TrimSpace(testTerraformApplyOutputListStr)
  2492  	if actual != expected {
  2493  		t.Fatalf("bad: \n%s", actual)
  2494  	}
  2495  }
  2496  
  2497  func TestContextApply_outputMulti(t *testing.T) {
  2498  	m := testModule(t, "apply-output-multi")
  2499  	p := testProvider("aws")
  2500  	p.ApplyFn = testApplyFn
  2501  	p.DiffFn = testDiffFn
  2502  	ctx := testContext(t, &ContextOpts{
  2503  		Module: m,
  2504  		Providers: map[string]ResourceProviderFactory{
  2505  			"aws": testProviderFuncFixed(p),
  2506  		},
  2507  	})
  2508  
  2509  	if _, err := ctx.Plan(nil); err != nil {
  2510  		t.Fatalf("err: %s", err)
  2511  	}
  2512  
  2513  	state, err := ctx.Apply()
  2514  	if err != nil {
  2515  		t.Fatalf("err: %s", err)
  2516  	}
  2517  
  2518  	actual := strings.TrimSpace(state.String())
  2519  	expected := strings.TrimSpace(testTerraformApplyOutputMultiStr)
  2520  	if actual != expected {
  2521  		t.Fatalf("bad: \n%s", actual)
  2522  	}
  2523  }
  2524  
  2525  func TestContextApply_outputMultiIndex(t *testing.T) {
  2526  	m := testModule(t, "apply-output-multi-index")
  2527  	p := testProvider("aws")
  2528  	p.ApplyFn = testApplyFn
  2529  	p.DiffFn = testDiffFn
  2530  	ctx := testContext(t, &ContextOpts{
  2531  		Module: m,
  2532  		Providers: map[string]ResourceProviderFactory{
  2533  			"aws": testProviderFuncFixed(p),
  2534  		},
  2535  	})
  2536  
  2537  	if _, err := ctx.Plan(nil); err != nil {
  2538  		t.Fatalf("err: %s", err)
  2539  	}
  2540  
  2541  	state, err := ctx.Apply()
  2542  	if err != nil {
  2543  		t.Fatalf("err: %s", err)
  2544  	}
  2545  
  2546  	actual := strings.TrimSpace(state.String())
  2547  	expected := strings.TrimSpace(testTerraformApplyOutputMultiIndexStr)
  2548  	if actual != expected {
  2549  		t.Fatalf("bad: \n%s", actual)
  2550  	}
  2551  }
  2552  
  2553  func TestContextApply_taint(t *testing.T) {
  2554  	m := testModule(t, "apply-taint")
  2555  	p := testProvider("aws")
  2556  	p.ApplyFn = testApplyFn
  2557  	p.DiffFn = testDiffFn
  2558  	s := &State{
  2559  		Modules: []*ModuleState{
  2560  			&ModuleState{
  2561  				Path: rootModulePath,
  2562  				Resources: map[string]*ResourceState{
  2563  					"aws_instance.bar": &ResourceState{
  2564  						Type: "aws_instance",
  2565  						Tainted: []*InstanceState{
  2566  							&InstanceState{
  2567  								ID: "baz",
  2568  								Attributes: map[string]string{
  2569  									"num":  "2",
  2570  									"type": "aws_instance",
  2571  								},
  2572  							},
  2573  						},
  2574  					},
  2575  				},
  2576  			},
  2577  		},
  2578  	}
  2579  	ctx := testContext(t, &ContextOpts{
  2580  		Module: m,
  2581  		Providers: map[string]ResourceProviderFactory{
  2582  			"aws": testProviderFuncFixed(p),
  2583  		},
  2584  		State: s,
  2585  	})
  2586  
  2587  	if _, err := ctx.Plan(nil); err != nil {
  2588  		t.Fatalf("err: %s", err)
  2589  	}
  2590  
  2591  	state, err := ctx.Apply()
  2592  	if err != nil {
  2593  		t.Fatalf("err: %s", err)
  2594  	}
  2595  
  2596  	actual := strings.TrimSpace(state.String())
  2597  	expected := strings.TrimSpace(testTerraformApplyTaintStr)
  2598  	if actual != expected {
  2599  		t.Fatalf("bad:\n%s", actual)
  2600  	}
  2601  }
  2602  
  2603  func TestContextApply_unknownAttribute(t *testing.T) {
  2604  	m := testModule(t, "apply-unknown")
  2605  	p := testProvider("aws")
  2606  	p.ApplyFn = testApplyFn
  2607  	p.DiffFn = testDiffFn
  2608  	ctx := testContext(t, &ContextOpts{
  2609  		Module: m,
  2610  		Providers: map[string]ResourceProviderFactory{
  2611  			"aws": testProviderFuncFixed(p),
  2612  		},
  2613  	})
  2614  
  2615  	if _, err := ctx.Plan(nil); err != nil {
  2616  		t.Fatalf("err: %s", err)
  2617  	}
  2618  
  2619  	state, err := ctx.Apply()
  2620  	if err == nil {
  2621  		t.Fatal("should error")
  2622  	}
  2623  
  2624  	actual := strings.TrimSpace(state.String())
  2625  	expected := strings.TrimSpace(testTerraformApplyUnknownAttrStr)
  2626  	if actual != expected {
  2627  		t.Fatalf("bad: \n%s", actual)
  2628  	}
  2629  }
  2630  
  2631  func TestContextApply_vars(t *testing.T) {
  2632  	m := testModule(t, "apply-vars")
  2633  	p := testProvider("aws")
  2634  	p.ApplyFn = testApplyFn
  2635  	p.DiffFn = testDiffFn
  2636  	ctx := testContext(t, &ContextOpts{
  2637  		Module: m,
  2638  		Providers: map[string]ResourceProviderFactory{
  2639  			"aws": testProviderFuncFixed(p),
  2640  		},
  2641  		Variables: map[string]string{
  2642  			"foo":            "us-west-2",
  2643  			"amis.us-east-1": "override",
  2644  		},
  2645  	})
  2646  
  2647  	w, e := ctx.Validate()
  2648  	if len(w) > 0 {
  2649  		t.Fatalf("bad: %#v", w)
  2650  	}
  2651  	if len(e) > 0 {
  2652  		t.Fatalf("bad: %s", e)
  2653  	}
  2654  
  2655  	if _, err := ctx.Plan(nil); err != nil {
  2656  		t.Fatalf("err: %s", err)
  2657  	}
  2658  
  2659  	state, err := ctx.Apply()
  2660  	if err != nil {
  2661  		t.Fatalf("err: %s", err)
  2662  	}
  2663  
  2664  	actual := strings.TrimSpace(state.String())
  2665  	expected := strings.TrimSpace(testTerraformApplyVarsStr)
  2666  	if actual != expected {
  2667  		t.Fatalf("bad: \n%s", actual)
  2668  	}
  2669  }
  2670  
  2671  func TestContextApply_createBefore_depends(t *testing.T) {
  2672  	m := testModule(t, "apply-depends-create-before")
  2673  	h := new(HookRecordApplyOrder)
  2674  	p := testProvider("aws")
  2675  	p.ApplyFn = testApplyFn
  2676  	p.DiffFn = testDiffFn
  2677  	state := &State{
  2678  		Modules: []*ModuleState{
  2679  			&ModuleState{
  2680  				Path: rootModulePath,
  2681  				Resources: map[string]*ResourceState{
  2682  					"aws_instance.web": &ResourceState{
  2683  						Type: "aws_instance",
  2684  						Primary: &InstanceState{
  2685  							ID: "bar",
  2686  							Attributes: map[string]string{
  2687  								"require_new": "ami-old",
  2688  							},
  2689  						},
  2690  					},
  2691  					"aws_instance.lb": &ResourceState{
  2692  						Type: "aws_instance",
  2693  						Primary: &InstanceState{
  2694  							ID: "baz",
  2695  							Attributes: map[string]string{
  2696  								"instance": "bar",
  2697  							},
  2698  						},
  2699  					},
  2700  				},
  2701  			},
  2702  		},
  2703  	}
  2704  	ctx := testContext(t, &ContextOpts{
  2705  		Module: m,
  2706  		Hooks:  []Hook{h},
  2707  		Providers: map[string]ResourceProviderFactory{
  2708  			"aws": testProviderFuncFixed(p),
  2709  		},
  2710  		State: state,
  2711  	})
  2712  
  2713  	if _, err := ctx.Plan(nil); err != nil {
  2714  		t.Fatalf("err: %s", err)
  2715  	}
  2716  
  2717  	h.Active = true
  2718  	state, err := ctx.Apply()
  2719  	if err != nil {
  2720  		t.Fatalf("err: %s", err)
  2721  	}
  2722  
  2723  	mod := state.RootModule()
  2724  	if len(mod.Resources) < 2 {
  2725  		t.Fatalf("bad: %#v", mod.Resources)
  2726  	}
  2727  
  2728  	actual := strings.TrimSpace(state.String())
  2729  	expected := strings.TrimSpace(testTerraformApplyDependsCreateBeforeStr)
  2730  	if actual != expected {
  2731  		t.Fatalf("bad: \n%s\n%s", actual, expected)
  2732  	}
  2733  
  2734  	// Test that things were managed _in the right order_
  2735  	order := h.States
  2736  	diffs := h.Diffs
  2737  	if order[0].ID != "" || diffs[0].Destroy {
  2738  		t.Fatalf("should create new instance first: %#v", order)
  2739  	}
  2740  
  2741  	if order[1].ID != "baz" {
  2742  		t.Fatalf("update must happen after create: %#v", order)
  2743  	}
  2744  
  2745  	if order[2].ID != "bar" || !diffs[2].Destroy {
  2746  		t.Fatalf("destroy must happen after update: %#v", order)
  2747  	}
  2748  }
  2749  
  2750  func TestContextApply_singleDestroy(t *testing.T) {
  2751  	m := testModule(t, "apply-depends-create-before")
  2752  	h := new(HookRecordApplyOrder)
  2753  	p := testProvider("aws")
  2754  
  2755  	invokeCount := 0
  2756  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  2757  		invokeCount++
  2758  		switch invokeCount {
  2759  		case 1:
  2760  			if d.Destroy {
  2761  				t.Fatalf("should not destroy")
  2762  			}
  2763  			if s.ID != "" {
  2764  				t.Fatalf("should not have ID")
  2765  			}
  2766  		case 2:
  2767  			if d.Destroy {
  2768  				t.Fatalf("should not destroy")
  2769  			}
  2770  			if s.ID != "baz" {
  2771  				t.Fatalf("should have id")
  2772  			}
  2773  		case 3:
  2774  			if !d.Destroy {
  2775  				t.Fatalf("should destroy")
  2776  			}
  2777  			if s.ID == "" {
  2778  				t.Fatalf("should have ID")
  2779  			}
  2780  		default:
  2781  			t.Fatalf("bad invoke count %d", invokeCount)
  2782  		}
  2783  		return testApplyFn(info, s, d)
  2784  	}
  2785  	p.DiffFn = testDiffFn
  2786  	state := &State{
  2787  		Modules: []*ModuleState{
  2788  			&ModuleState{
  2789  				Path: rootModulePath,
  2790  				Resources: map[string]*ResourceState{
  2791  					"aws_instance.web": &ResourceState{
  2792  						Type: "aws_instance",
  2793  						Primary: &InstanceState{
  2794  							ID: "bar",
  2795  							Attributes: map[string]string{
  2796  								"require_new": "ami-old",
  2797  							},
  2798  						},
  2799  					},
  2800  					"aws_instance.lb": &ResourceState{
  2801  						Type: "aws_instance",
  2802  						Primary: &InstanceState{
  2803  							ID: "baz",
  2804  							Attributes: map[string]string{
  2805  								"instance": "bar",
  2806  							},
  2807  						},
  2808  					},
  2809  				},
  2810  			},
  2811  		},
  2812  	}
  2813  	ctx := testContext(t, &ContextOpts{
  2814  		Module: m,
  2815  		Hooks:  []Hook{h},
  2816  		Providers: map[string]ResourceProviderFactory{
  2817  			"aws": testProviderFuncFixed(p),
  2818  		},
  2819  		State: state,
  2820  	})
  2821  
  2822  	if _, err := ctx.Plan(nil); err != nil {
  2823  		t.Fatalf("err: %s", err)
  2824  	}
  2825  
  2826  	h.Active = true
  2827  	state, err := ctx.Apply()
  2828  	if err != nil {
  2829  		t.Fatalf("err: %s", err)
  2830  	}
  2831  
  2832  	if invokeCount != 3 {
  2833  		t.Fatalf("bad: %d", invokeCount)
  2834  	}
  2835  }
  2836  
  2837  func TestContextPlan(t *testing.T) {
  2838  	m := testModule(t, "plan-good")
  2839  	p := testProvider("aws")
  2840  	p.DiffFn = testDiffFn
  2841  	ctx := testContext(t, &ContextOpts{
  2842  		Module: m,
  2843  		Providers: map[string]ResourceProviderFactory{
  2844  			"aws": testProviderFuncFixed(p),
  2845  		},
  2846  	})
  2847  
  2848  	plan, err := ctx.Plan(nil)
  2849  	if err != nil {
  2850  		t.Fatalf("err: %s", err)
  2851  	}
  2852  
  2853  	if len(plan.Diff.RootModule().Resources) < 2 {
  2854  		t.Fatalf("bad: %#v", plan.Diff.RootModule().Resources)
  2855  	}
  2856  
  2857  	actual := strings.TrimSpace(plan.String())
  2858  	expected := strings.TrimSpace(testTerraformPlanStr)
  2859  	if actual != expected {
  2860  		t.Fatalf("bad:\n%s", actual)
  2861  	}
  2862  }
  2863  
  2864  func TestContextPlan_emptyDiff(t *testing.T) {
  2865  	m := testModule(t, "plan-empty")
  2866  	p := testProvider("aws")
  2867  	p.DiffFn = func(
  2868  		info *InstanceInfo,
  2869  		s *InstanceState,
  2870  		c *ResourceConfig) (*InstanceDiff, error) {
  2871  		return nil, nil
  2872  	}
  2873  
  2874  	ctx := testContext(t, &ContextOpts{
  2875  		Module: m,
  2876  		Providers: map[string]ResourceProviderFactory{
  2877  			"aws": testProviderFuncFixed(p),
  2878  		},
  2879  	})
  2880  
  2881  	plan, err := ctx.Plan(nil)
  2882  	if err != nil {
  2883  		t.Fatalf("err: %s", err)
  2884  	}
  2885  
  2886  	actual := strings.TrimSpace(plan.String())
  2887  	expected := strings.TrimSpace(testTerraformPlanEmptyStr)
  2888  	if actual != expected {
  2889  		t.Fatalf("bad:\n%s", actual)
  2890  	}
  2891  }
  2892  
  2893  func TestContextPlan_minimal(t *testing.T) {
  2894  	m := testModule(t, "plan-empty")
  2895  	p := testProvider("aws")
  2896  	p.DiffFn = testDiffFn
  2897  	ctx := testContext(t, &ContextOpts{
  2898  		Module: m,
  2899  		Providers: map[string]ResourceProviderFactory{
  2900  			"aws": testProviderFuncFixed(p),
  2901  		},
  2902  	})
  2903  
  2904  	plan, err := ctx.Plan(nil)
  2905  	if err != nil {
  2906  		t.Fatalf("err: %s", err)
  2907  	}
  2908  
  2909  	actual := strings.TrimSpace(plan.String())
  2910  	expected := strings.TrimSpace(testTerraformPlanEmptyStr)
  2911  	if actual != expected {
  2912  		t.Fatalf("bad:\n%s", actual)
  2913  	}
  2914  }
  2915  
  2916  func TestContextPlan_modules(t *testing.T) {
  2917  	m := testModule(t, "plan-modules")
  2918  	p := testProvider("aws")
  2919  	p.DiffFn = testDiffFn
  2920  	ctx := testContext(t, &ContextOpts{
  2921  		Module: m,
  2922  		Providers: map[string]ResourceProviderFactory{
  2923  			"aws": testProviderFuncFixed(p),
  2924  		},
  2925  	})
  2926  
  2927  	plan, err := ctx.Plan(nil)
  2928  	if err != nil {
  2929  		t.Fatalf("err: %s", err)
  2930  	}
  2931  
  2932  	actual := strings.TrimSpace(plan.String())
  2933  	expected := strings.TrimSpace(testTerraformPlanModulesStr)
  2934  	if actual != expected {
  2935  		t.Fatalf("bad:\n%s", actual)
  2936  	}
  2937  }
  2938  
  2939  func TestContextPlan_moduleInput(t *testing.T) {
  2940  	m := testModule(t, "plan-module-input")
  2941  	p := testProvider("aws")
  2942  	p.DiffFn = testDiffFn
  2943  	ctx := testContext(t, &ContextOpts{
  2944  		Module: m,
  2945  		Providers: map[string]ResourceProviderFactory{
  2946  			"aws": testProviderFuncFixed(p),
  2947  		},
  2948  	})
  2949  
  2950  	plan, err := ctx.Plan(nil)
  2951  	if err != nil {
  2952  		t.Fatalf("err: %s", err)
  2953  	}
  2954  
  2955  	actual := strings.TrimSpace(plan.String())
  2956  	expected := strings.TrimSpace(testTerraformPlanModuleInputStr)
  2957  	if actual != expected {
  2958  		t.Fatalf("bad:\n%s", actual)
  2959  	}
  2960  }
  2961  
  2962  func TestContextPlan_moduleInputComputed(t *testing.T) {
  2963  	m := testModule(t, "plan-module-input-computed")
  2964  	p := testProvider("aws")
  2965  	p.DiffFn = testDiffFn
  2966  	ctx := testContext(t, &ContextOpts{
  2967  		Module: m,
  2968  		Providers: map[string]ResourceProviderFactory{
  2969  			"aws": testProviderFuncFixed(p),
  2970  		},
  2971  	})
  2972  
  2973  	plan, err := ctx.Plan(nil)
  2974  	if err != nil {
  2975  		t.Fatalf("err: %s", err)
  2976  	}
  2977  
  2978  	actual := strings.TrimSpace(plan.String())
  2979  	expected := strings.TrimSpace(testTerraformPlanModuleInputComputedStr)
  2980  	if actual != expected {
  2981  		t.Fatalf("bad:\n%s", actual)
  2982  	}
  2983  }
  2984  
  2985  func TestContextPlan_moduleInputFromVar(t *testing.T) {
  2986  	m := testModule(t, "plan-module-input-var")
  2987  	p := testProvider("aws")
  2988  	p.DiffFn = testDiffFn
  2989  	ctx := testContext(t, &ContextOpts{
  2990  		Module: m,
  2991  		Providers: map[string]ResourceProviderFactory{
  2992  			"aws": testProviderFuncFixed(p),
  2993  		},
  2994  		Variables: map[string]string{
  2995  			"foo": "52",
  2996  		},
  2997  	})
  2998  
  2999  	plan, err := ctx.Plan(nil)
  3000  	if err != nil {
  3001  		t.Fatalf("err: %s", err)
  3002  	}
  3003  
  3004  	actual := strings.TrimSpace(plan.String())
  3005  	expected := strings.TrimSpace(testTerraformPlanModuleInputVarStr)
  3006  	if actual != expected {
  3007  		t.Fatalf("bad:\n%s", actual)
  3008  	}
  3009  }
  3010  func TestContextPlan_moduleMultiVar(t *testing.T) {
  3011  	m := testModule(t, "plan-module-multi-var")
  3012  	p := testProvider("aws")
  3013  	p.DiffFn = testDiffFn
  3014  	ctx := testContext(t, &ContextOpts{
  3015  		Module: m,
  3016  		Providers: map[string]ResourceProviderFactory{
  3017  			"aws": testProviderFuncFixed(p),
  3018  		},
  3019  	})
  3020  
  3021  	plan, err := ctx.Plan(nil)
  3022  	if err != nil {
  3023  		t.Fatalf("err: %s", err)
  3024  	}
  3025  
  3026  	actual := strings.TrimSpace(plan.String())
  3027  	expected := strings.TrimSpace(testTerraformPlanModuleMultiVarStr)
  3028  	if actual != expected {
  3029  		t.Fatalf("bad:\n%s", actual)
  3030  	}
  3031  }
  3032  func TestContextPlan_moduleOrphans(t *testing.T) {
  3033  	m := testModule(t, "plan-modules-remove")
  3034  	p := testProvider("aws")
  3035  	p.DiffFn = testDiffFn
  3036  	s := &State{
  3037  		Modules: []*ModuleState{
  3038  			&ModuleState{
  3039  				Path: []string{"root", "child"},
  3040  				Resources: map[string]*ResourceState{
  3041  					"aws_instance.foo": &ResourceState{
  3042  						Type: "aws_instance",
  3043  						Primary: &InstanceState{
  3044  							ID: "baz",
  3045  						},
  3046  					},
  3047  				},
  3048  			},
  3049  		},
  3050  	}
  3051  	ctx := testContext(t, &ContextOpts{
  3052  		Module: m,
  3053  		Providers: map[string]ResourceProviderFactory{
  3054  			"aws": testProviderFuncFixed(p),
  3055  		},
  3056  		State: s,
  3057  	})
  3058  
  3059  	plan, err := ctx.Plan(nil)
  3060  	if err != nil {
  3061  		t.Fatalf("err: %s", err)
  3062  	}
  3063  
  3064  	actual := strings.TrimSpace(plan.String())
  3065  	expected := strings.TrimSpace(testTerraformPlanModuleOrphansStr)
  3066  	if actual != expected {
  3067  		t.Fatalf("bad:\n%s", actual)
  3068  	}
  3069  }
  3070  
  3071  func TestContextPlan_moduleProviderInherit(t *testing.T) {
  3072  	var l sync.Mutex
  3073  	var calls []string
  3074  
  3075  	m := testModule(t, "plan-module-provider-inherit")
  3076  	ctx := testContext(t, &ContextOpts{
  3077  		Module: m,
  3078  		Providers: map[string]ResourceProviderFactory{
  3079  			"aws": func() (ResourceProvider, error) {
  3080  				l.Lock()
  3081  				defer l.Unlock()
  3082  
  3083  				p := testProvider("aws")
  3084  				p.ConfigureFn = func(c *ResourceConfig) error {
  3085  					if v, ok := c.Get("from"); !ok || v.(string) != "root" {
  3086  						return fmt.Errorf("bad")
  3087  					}
  3088  
  3089  					return nil
  3090  				}
  3091  				p.DiffFn = func(
  3092  					info *InstanceInfo,
  3093  					state *InstanceState,
  3094  					c *ResourceConfig) (*InstanceDiff, error) {
  3095  					v, _ := c.Get("from")
  3096  					calls = append(calls, v.(string))
  3097  					return testDiffFn(info, state, c)
  3098  				}
  3099  				return p, nil
  3100  			},
  3101  		},
  3102  	})
  3103  
  3104  	_, err := ctx.Plan(nil)
  3105  	if err != nil {
  3106  		t.Fatalf("err: %s", err)
  3107  	}
  3108  
  3109  	actual := calls
  3110  	sort.Strings(actual)
  3111  	expected := []string{"child", "root"}
  3112  	if !reflect.DeepEqual(actual, expected) {
  3113  		t.Fatalf("bad: %#v", actual)
  3114  	}
  3115  }
  3116  
  3117  func TestContextPlan_moduleProviderDefaults(t *testing.T) {
  3118  	var l sync.Mutex
  3119  	var calls []string
  3120  	toCount := 0
  3121  
  3122  	m := testModule(t, "plan-module-provider-defaults")
  3123  	ctx := testContext(t, &ContextOpts{
  3124  		Module: m,
  3125  		Providers: map[string]ResourceProviderFactory{
  3126  			"aws": func() (ResourceProvider, error) {
  3127  				l.Lock()
  3128  				defer l.Unlock()
  3129  
  3130  				p := testProvider("aws")
  3131  				p.ConfigureFn = func(c *ResourceConfig) error {
  3132  					if v, ok := c.Get("from"); !ok || v.(string) != "root" {
  3133  						return fmt.Errorf("bad")
  3134  					}
  3135  					if v, ok := c.Get("to"); ok && v.(string) == "child" {
  3136  						toCount++
  3137  					}
  3138  
  3139  					return nil
  3140  				}
  3141  				p.DiffFn = func(
  3142  					info *InstanceInfo,
  3143  					state *InstanceState,
  3144  					c *ResourceConfig) (*InstanceDiff, error) {
  3145  					v, _ := c.Get("from")
  3146  					calls = append(calls, v.(string))
  3147  					return testDiffFn(info, state, c)
  3148  				}
  3149  				return p, nil
  3150  			},
  3151  		},
  3152  	})
  3153  
  3154  	_, err := ctx.Plan(nil)
  3155  	if err != nil {
  3156  		t.Fatalf("err: %s", err)
  3157  	}
  3158  
  3159  	if toCount != 1 {
  3160  		t.Fatal("provider in child didn't set proper config")
  3161  	}
  3162  
  3163  	actual := calls
  3164  	sort.Strings(actual)
  3165  	expected := []string{"child", "root"}
  3166  	if !reflect.DeepEqual(actual, expected) {
  3167  		t.Fatalf("bad: %#v", actual)
  3168  	}
  3169  }
  3170  
  3171  func TestContextPlan_moduleProviderDefaultsVar(t *testing.T) {
  3172  	var l sync.Mutex
  3173  	var calls []string
  3174  
  3175  	m := testModule(t, "plan-module-provider-defaults-var")
  3176  	ctx := testContext(t, &ContextOpts{
  3177  		Module: m,
  3178  		Providers: map[string]ResourceProviderFactory{
  3179  			"aws": func() (ResourceProvider, error) {
  3180  				l.Lock()
  3181  				defer l.Unlock()
  3182  
  3183  				p := testProvider("aws")
  3184  				p.ConfigureFn = func(c *ResourceConfig) error {
  3185  					var buf bytes.Buffer
  3186  					if v, ok := c.Get("from"); ok {
  3187  						buf.WriteString(v.(string) + "\n")
  3188  					}
  3189  					if v, ok := c.Get("to"); ok {
  3190  						buf.WriteString(v.(string) + "\n")
  3191  					}
  3192  
  3193  					calls = append(calls, buf.String())
  3194  					return nil
  3195  				}
  3196  				p.DiffFn = testDiffFn
  3197  				return p, nil
  3198  			},
  3199  		},
  3200  		Variables: map[string]string{
  3201  			"foo": "root",
  3202  		},
  3203  	})
  3204  
  3205  	_, err := ctx.Plan(nil)
  3206  	if err != nil {
  3207  		t.Fatalf("err: %s", err)
  3208  	}
  3209  
  3210  	expected := []string{
  3211  		"root\n",
  3212  		"root\nchild\n",
  3213  	}
  3214  	if !reflect.DeepEqual(calls, expected) {
  3215  		t.Fatalf("BAD: %#v", calls)
  3216  	}
  3217  }
  3218  
  3219  func TestContextPlan_moduleVar(t *testing.T) {
  3220  	m := testModule(t, "plan-module-var")
  3221  	p := testProvider("aws")
  3222  	p.DiffFn = testDiffFn
  3223  	ctx := testContext(t, &ContextOpts{
  3224  		Module: m,
  3225  		Providers: map[string]ResourceProviderFactory{
  3226  			"aws": testProviderFuncFixed(p),
  3227  		},
  3228  	})
  3229  
  3230  	plan, err := ctx.Plan(nil)
  3231  	if err != nil {
  3232  		t.Fatalf("err: %s", err)
  3233  	}
  3234  
  3235  	actual := strings.TrimSpace(plan.String())
  3236  	expected := strings.TrimSpace(testTerraformPlanModuleVarStr)
  3237  	if actual != expected {
  3238  		t.Fatalf("bad:\n%s", actual)
  3239  	}
  3240  }
  3241  
  3242  func TestContextPlan_moduleVarComputed(t *testing.T) {
  3243  	m := testModule(t, "plan-module-var-computed")
  3244  	p := testProvider("aws")
  3245  	p.DiffFn = testDiffFn
  3246  	ctx := testContext(t, &ContextOpts{
  3247  		Module: m,
  3248  		Providers: map[string]ResourceProviderFactory{
  3249  			"aws": testProviderFuncFixed(p),
  3250  		},
  3251  	})
  3252  
  3253  	plan, err := ctx.Plan(nil)
  3254  	if err != nil {
  3255  		t.Fatalf("err: %s", err)
  3256  	}
  3257  
  3258  	actual := strings.TrimSpace(plan.String())
  3259  	expected := strings.TrimSpace(testTerraformPlanModuleVarComputedStr)
  3260  	if actual != expected {
  3261  		t.Fatalf("bad:\n%s", actual)
  3262  	}
  3263  }
  3264  
  3265  func TestContextPlan_nil(t *testing.T) {
  3266  	m := testModule(t, "plan-nil")
  3267  	p := testProvider("aws")
  3268  	p.DiffFn = testDiffFn
  3269  	ctx := testContext(t, &ContextOpts{
  3270  		Module: m,
  3271  		Providers: map[string]ResourceProviderFactory{
  3272  			"aws": testProviderFuncFixed(p),
  3273  		},
  3274  		State: &State{
  3275  			Modules: []*ModuleState{
  3276  				&ModuleState{
  3277  					Path: rootModulePath,
  3278  					Resources: map[string]*ResourceState{
  3279  						"aws_instance.foo": &ResourceState{
  3280  							Type: "aws_instance",
  3281  							Primary: &InstanceState{
  3282  								ID: "bar",
  3283  							},
  3284  						},
  3285  					},
  3286  				},
  3287  			},
  3288  		},
  3289  	})
  3290  
  3291  	plan, err := ctx.Plan(nil)
  3292  	if err != nil {
  3293  		t.Fatalf("err: %s", err)
  3294  	}
  3295  	if len(plan.Diff.RootModule().Resources) != 0 {
  3296  		t.Fatalf("bad: %#v", plan.Diff.RootModule().Resources)
  3297  	}
  3298  }
  3299  
  3300  func TestContextPlan_computed(t *testing.T) {
  3301  	m := testModule(t, "plan-computed")
  3302  	p := testProvider("aws")
  3303  	p.DiffFn = testDiffFn
  3304  	ctx := testContext(t, &ContextOpts{
  3305  		Module: m,
  3306  		Providers: map[string]ResourceProviderFactory{
  3307  			"aws": testProviderFuncFixed(p),
  3308  		},
  3309  	})
  3310  
  3311  	plan, err := ctx.Plan(nil)
  3312  	if err != nil {
  3313  		t.Fatalf("err: %s", err)
  3314  	}
  3315  
  3316  	actual := strings.TrimSpace(plan.String())
  3317  	expected := strings.TrimSpace(testTerraformPlanComputedStr)
  3318  	if actual != expected {
  3319  		t.Fatalf("bad:\n%s", actual)
  3320  	}
  3321  }
  3322  
  3323  func TestContextPlan_computedList(t *testing.T) {
  3324  	m := testModule(t, "plan-computed-list")
  3325  	p := testProvider("aws")
  3326  	p.DiffFn = testDiffFn
  3327  	ctx := testContext(t, &ContextOpts{
  3328  		Module: m,
  3329  		Providers: map[string]ResourceProviderFactory{
  3330  			"aws": testProviderFuncFixed(p),
  3331  		},
  3332  	})
  3333  
  3334  	plan, err := ctx.Plan(nil)
  3335  	if err != nil {
  3336  		t.Fatalf("err: %s", err)
  3337  	}
  3338  
  3339  	actual := strings.TrimSpace(plan.String())
  3340  	expected := strings.TrimSpace(testTerraformPlanComputedListStr)
  3341  	if actual != expected {
  3342  		t.Fatalf("bad:\n%s", actual)
  3343  	}
  3344  }
  3345  
  3346  func TestContextPlan_count(t *testing.T) {
  3347  	m := testModule(t, "plan-count")
  3348  	p := testProvider("aws")
  3349  	p.DiffFn = testDiffFn
  3350  	ctx := testContext(t, &ContextOpts{
  3351  		Module: m,
  3352  		Providers: map[string]ResourceProviderFactory{
  3353  			"aws": testProviderFuncFixed(p),
  3354  		},
  3355  	})
  3356  
  3357  	plan, err := ctx.Plan(nil)
  3358  	if err != nil {
  3359  		t.Fatalf("err: %s", err)
  3360  	}
  3361  
  3362  	if len(plan.Diff.RootModule().Resources) < 6 {
  3363  		t.Fatalf("bad: %#v", plan.Diff.RootModule().Resources)
  3364  	}
  3365  
  3366  	actual := strings.TrimSpace(plan.String())
  3367  	expected := strings.TrimSpace(testTerraformPlanCountStr)
  3368  	if actual != expected {
  3369  		t.Fatalf("bad:\n%s", actual)
  3370  	}
  3371  }
  3372  
  3373  func TestContextPlan_countComputed(t *testing.T) {
  3374  	m := testModule(t, "plan-count-computed")
  3375  	p := testProvider("aws")
  3376  	p.DiffFn = testDiffFn
  3377  	ctx := testContext(t, &ContextOpts{
  3378  		Module: m,
  3379  		Providers: map[string]ResourceProviderFactory{
  3380  			"aws": testProviderFuncFixed(p),
  3381  		},
  3382  	})
  3383  
  3384  	_, err := ctx.Plan(nil)
  3385  	if err == nil {
  3386  		t.Fatal("should error")
  3387  	}
  3388  }
  3389  
  3390  func TestContextPlan_countIndex(t *testing.T) {
  3391  	m := testModule(t, "plan-count-index")
  3392  	p := testProvider("aws")
  3393  	p.DiffFn = testDiffFn
  3394  	ctx := testContext(t, &ContextOpts{
  3395  		Module: m,
  3396  		Providers: map[string]ResourceProviderFactory{
  3397  			"aws": testProviderFuncFixed(p),
  3398  		},
  3399  	})
  3400  
  3401  	plan, err := ctx.Plan(nil)
  3402  	if err != nil {
  3403  		t.Fatalf("err: %s", err)
  3404  	}
  3405  
  3406  	actual := strings.TrimSpace(plan.String())
  3407  	expected := strings.TrimSpace(testTerraformPlanCountIndexStr)
  3408  	if actual != expected {
  3409  		t.Fatalf("bad:\n%s", actual)
  3410  	}
  3411  }
  3412  
  3413  func TestContextPlan_countIndexZero(t *testing.T) {
  3414  	m := testModule(t, "plan-count-index-zero")
  3415  	p := testProvider("aws")
  3416  	p.DiffFn = testDiffFn
  3417  	ctx := testContext(t, &ContextOpts{
  3418  		Module: m,
  3419  		Providers: map[string]ResourceProviderFactory{
  3420  			"aws": testProviderFuncFixed(p),
  3421  		},
  3422  	})
  3423  
  3424  	plan, err := ctx.Plan(nil)
  3425  	if err != nil {
  3426  		t.Fatalf("err: %s", err)
  3427  	}
  3428  
  3429  	actual := strings.TrimSpace(plan.String())
  3430  	expected := strings.TrimSpace(testTerraformPlanCountIndexZeroStr)
  3431  	if actual != expected {
  3432  		t.Fatalf("bad:\n%s", actual)
  3433  	}
  3434  }
  3435  
  3436  func TestContextPlan_countVar(t *testing.T) {
  3437  	m := testModule(t, "plan-count-var")
  3438  	p := testProvider("aws")
  3439  	p.DiffFn = testDiffFn
  3440  	ctx := testContext(t, &ContextOpts{
  3441  		Module: m,
  3442  		Providers: map[string]ResourceProviderFactory{
  3443  			"aws": testProviderFuncFixed(p),
  3444  		},
  3445  		Variables: map[string]string{
  3446  			"count": "3",
  3447  		},
  3448  	})
  3449  
  3450  	plan, err := ctx.Plan(nil)
  3451  	if err != nil {
  3452  		t.Fatalf("err: %s", err)
  3453  	}
  3454  
  3455  	actual := strings.TrimSpace(plan.String())
  3456  	expected := strings.TrimSpace(testTerraformPlanCountVarStr)
  3457  	if actual != expected {
  3458  		t.Fatalf("bad:\n%s", actual)
  3459  	}
  3460  }
  3461  
  3462  func TestContextPlan_countZero(t *testing.T) {
  3463  	m := testModule(t, "plan-count-zero")
  3464  	p := testProvider("aws")
  3465  	p.DiffFn = testDiffFn
  3466  	ctx := testContext(t, &ContextOpts{
  3467  		Module: m,
  3468  		Providers: map[string]ResourceProviderFactory{
  3469  			"aws": testProviderFuncFixed(p),
  3470  		},
  3471  	})
  3472  
  3473  	plan, err := ctx.Plan(nil)
  3474  	if err != nil {
  3475  		t.Fatalf("err: %s", err)
  3476  	}
  3477  
  3478  	actual := strings.TrimSpace(plan.String())
  3479  	expected := strings.TrimSpace(testTerraformPlanCountZeroStr)
  3480  	if actual != expected {
  3481  		t.Fatalf("bad:\n%s", actual)
  3482  	}
  3483  }
  3484  
  3485  func TestContextPlan_countOneIndex(t *testing.T) {
  3486  	m := testModule(t, "plan-count-one-index")
  3487  	p := testProvider("aws")
  3488  	p.DiffFn = testDiffFn
  3489  	ctx := testContext(t, &ContextOpts{
  3490  		Module: m,
  3491  		Providers: map[string]ResourceProviderFactory{
  3492  			"aws": testProviderFuncFixed(p),
  3493  		},
  3494  	})
  3495  
  3496  	plan, err := ctx.Plan(nil)
  3497  	if err != nil {
  3498  		t.Fatalf("err: %s", err)
  3499  	}
  3500  
  3501  	actual := strings.TrimSpace(plan.String())
  3502  	expected := strings.TrimSpace(testTerraformPlanCountOneIndexStr)
  3503  	if actual != expected {
  3504  		t.Fatalf("bad:\n%s", actual)
  3505  	}
  3506  }
  3507  
  3508  func TestContextPlan_countDecreaseToOne(t *testing.T) {
  3509  	m := testModule(t, "plan-count-dec")
  3510  	p := testProvider("aws")
  3511  	p.DiffFn = testDiffFn
  3512  	s := &State{
  3513  		Modules: []*ModuleState{
  3514  			&ModuleState{
  3515  				Path: rootModulePath,
  3516  				Resources: map[string]*ResourceState{
  3517  					"aws_instance.foo.0": &ResourceState{
  3518  						Type: "aws_instance",
  3519  						Primary: &InstanceState{
  3520  							ID: "bar",
  3521  							Attributes: map[string]string{
  3522  								"foo":  "foo",
  3523  								"type": "aws_instance",
  3524  							},
  3525  						},
  3526  					},
  3527  					"aws_instance.foo.1": &ResourceState{
  3528  						Type: "aws_instance",
  3529  						Primary: &InstanceState{
  3530  							ID: "bar",
  3531  						},
  3532  					},
  3533  					"aws_instance.foo.2": &ResourceState{
  3534  						Type: "aws_instance",
  3535  						Primary: &InstanceState{
  3536  							ID: "bar",
  3537  						},
  3538  					},
  3539  				},
  3540  			},
  3541  		},
  3542  	}
  3543  	ctx := testContext(t, &ContextOpts{
  3544  		Module: m,
  3545  		Providers: map[string]ResourceProviderFactory{
  3546  			"aws": testProviderFuncFixed(p),
  3547  		},
  3548  		State: s,
  3549  	})
  3550  
  3551  	plan, err := ctx.Plan(nil)
  3552  	if err != nil {
  3553  		t.Fatalf("err: %s", err)
  3554  	}
  3555  
  3556  	actual := strings.TrimSpace(plan.String())
  3557  	expected := strings.TrimSpace(testTerraformPlanCountDecreaseStr)
  3558  	if actual != expected {
  3559  		t.Fatalf("bad:\n%s", actual)
  3560  	}
  3561  }
  3562  
  3563  func TestContextPlan_countIncreaseFromNotSet(t *testing.T) {
  3564  	m := testModule(t, "plan-count-inc")
  3565  	p := testProvider("aws")
  3566  	p.DiffFn = testDiffFn
  3567  	s := &State{
  3568  		Modules: []*ModuleState{
  3569  			&ModuleState{
  3570  				Path: rootModulePath,
  3571  				Resources: map[string]*ResourceState{
  3572  					"aws_instance.foo": &ResourceState{
  3573  						Type: "aws_instance",
  3574  						Primary: &InstanceState{
  3575  							ID: "bar",
  3576  							Attributes: map[string]string{
  3577  								"foo":  "foo",
  3578  								"type": "aws_instance",
  3579  							},
  3580  						},
  3581  					},
  3582  				},
  3583  			},
  3584  		},
  3585  	}
  3586  	ctx := testContext(t, &ContextOpts{
  3587  		Module: m,
  3588  		Providers: map[string]ResourceProviderFactory{
  3589  			"aws": testProviderFuncFixed(p),
  3590  		},
  3591  		State: s,
  3592  	})
  3593  
  3594  	plan, err := ctx.Plan(nil)
  3595  	if err != nil {
  3596  		t.Fatalf("err: %s", err)
  3597  	}
  3598  
  3599  	actual := strings.TrimSpace(plan.String())
  3600  	expected := strings.TrimSpace(testTerraformPlanCountIncreaseStr)
  3601  	if actual != expected {
  3602  		t.Fatalf("bad:\n%s", actual)
  3603  	}
  3604  }
  3605  
  3606  func TestContextPlan_countIncreaseFromOne(t *testing.T) {
  3607  	m := testModule(t, "plan-count-inc")
  3608  	p := testProvider("aws")
  3609  	p.DiffFn = testDiffFn
  3610  	s := &State{
  3611  		Modules: []*ModuleState{
  3612  			&ModuleState{
  3613  				Path: rootModulePath,
  3614  				Resources: map[string]*ResourceState{
  3615  					"aws_instance.foo.0": &ResourceState{
  3616  						Type: "aws_instance",
  3617  						Primary: &InstanceState{
  3618  							ID: "bar",
  3619  							Attributes: map[string]string{
  3620  								"foo":  "foo",
  3621  								"type": "aws_instance",
  3622  							},
  3623  						},
  3624  					},
  3625  				},
  3626  			},
  3627  		},
  3628  	}
  3629  	ctx := testContext(t, &ContextOpts{
  3630  		Module: m,
  3631  		Providers: map[string]ResourceProviderFactory{
  3632  			"aws": testProviderFuncFixed(p),
  3633  		},
  3634  		State: s,
  3635  	})
  3636  
  3637  	plan, err := ctx.Plan(nil)
  3638  	if err != nil {
  3639  		t.Fatalf("err: %s", err)
  3640  	}
  3641  
  3642  	actual := strings.TrimSpace(plan.String())
  3643  	expected := strings.TrimSpace(testTerraformPlanCountIncreaseFromOneStr)
  3644  	if actual != expected {
  3645  		t.Fatalf("bad:\n%s", actual)
  3646  	}
  3647  }
  3648  
  3649  func TestContextPlan_destroy(t *testing.T) {
  3650  	m := testModule(t, "plan-destroy")
  3651  	p := testProvider("aws")
  3652  	p.DiffFn = testDiffFn
  3653  	s := &State{
  3654  		Modules: []*ModuleState{
  3655  			&ModuleState{
  3656  				Path: rootModulePath,
  3657  				Resources: map[string]*ResourceState{
  3658  					"aws_instance.one": &ResourceState{
  3659  						Type: "aws_instance",
  3660  						Primary: &InstanceState{
  3661  							ID: "bar",
  3662  						},
  3663  					},
  3664  					"aws_instance.two": &ResourceState{
  3665  						Type: "aws_instance",
  3666  						Primary: &InstanceState{
  3667  							ID: "baz",
  3668  						},
  3669  					},
  3670  				},
  3671  			},
  3672  		},
  3673  	}
  3674  	ctx := testContext(t, &ContextOpts{
  3675  		Module: m,
  3676  		Providers: map[string]ResourceProviderFactory{
  3677  			"aws": testProviderFuncFixed(p),
  3678  		},
  3679  		State: s,
  3680  	})
  3681  
  3682  	plan, err := ctx.Plan(&PlanOpts{Destroy: true})
  3683  	if err != nil {
  3684  		t.Fatalf("err: %s", err)
  3685  	}
  3686  
  3687  	if len(plan.Diff.RootModule().Resources) != 2 {
  3688  		t.Fatalf("bad: %#v", plan.Diff.RootModule().Resources)
  3689  	}
  3690  
  3691  	actual := strings.TrimSpace(plan.String())
  3692  	expected := strings.TrimSpace(testTerraformPlanDestroyStr)
  3693  	if actual != expected {
  3694  		t.Fatalf("bad:\n%s", actual)
  3695  	}
  3696  }
  3697  
  3698  func TestContextPlan_moduleDestroy(t *testing.T) {
  3699  	m := testModule(t, "plan-module-destroy")
  3700  	p := testProvider("aws")
  3701  	p.DiffFn = testDiffFn
  3702  	s := &State{
  3703  		Modules: []*ModuleState{
  3704  			&ModuleState{
  3705  				Path: rootModulePath,
  3706  				Resources: map[string]*ResourceState{
  3707  					"aws_instance.foo": &ResourceState{
  3708  						Type: "aws_instance",
  3709  						Primary: &InstanceState{
  3710  							ID: "bar",
  3711  						},
  3712  					},
  3713  				},
  3714  			},
  3715  			&ModuleState{
  3716  				Path: []string{"root", "child"},
  3717  				Resources: map[string]*ResourceState{
  3718  					"aws_instance.foo": &ResourceState{
  3719  						Type: "aws_instance",
  3720  						Primary: &InstanceState{
  3721  							ID: "bar",
  3722  						},
  3723  					},
  3724  				},
  3725  			},
  3726  		},
  3727  	}
  3728  	ctx := testContext(t, &ContextOpts{
  3729  		Module: m,
  3730  		Providers: map[string]ResourceProviderFactory{
  3731  			"aws": testProviderFuncFixed(p),
  3732  		},
  3733  		State: s,
  3734  	})
  3735  
  3736  	plan, err := ctx.Plan(&PlanOpts{Destroy: true})
  3737  	if err != nil {
  3738  		t.Fatalf("err: %s", err)
  3739  	}
  3740  
  3741  	actual := strings.TrimSpace(plan.String())
  3742  	expected := strings.TrimSpace(testTerraformPlanModuleDestroyStr)
  3743  	if actual != expected {
  3744  		t.Fatalf("bad:\n%s", actual)
  3745  	}
  3746  }
  3747  
  3748  func TestContextPlan_moduleDestroyMultivar(t *testing.T) {
  3749  	m := testModule(t, "plan-module-destroy-multivar")
  3750  	p := testProvider("aws")
  3751  	p.DiffFn = testDiffFn
  3752  	s := &State{
  3753  		Modules: []*ModuleState{
  3754  			&ModuleState{
  3755  				Path:      rootModulePath,
  3756  				Resources: map[string]*ResourceState{},
  3757  			},
  3758  			&ModuleState{
  3759  				Path: []string{"root", "child"},
  3760  				Resources: map[string]*ResourceState{
  3761  					"aws_instance.foo.0": &ResourceState{
  3762  						Type: "aws_instance",
  3763  						Primary: &InstanceState{
  3764  							ID: "bar0",
  3765  						},
  3766  					},
  3767  					"aws_instance.foo.1": &ResourceState{
  3768  						Type: "aws_instance",
  3769  						Primary: &InstanceState{
  3770  							ID: "bar1",
  3771  						},
  3772  					},
  3773  				},
  3774  			},
  3775  		},
  3776  	}
  3777  	ctx := testContext(t, &ContextOpts{
  3778  		Module: m,
  3779  		Providers: map[string]ResourceProviderFactory{
  3780  			"aws": testProviderFuncFixed(p),
  3781  		},
  3782  		State: s,
  3783  	})
  3784  
  3785  	plan, err := ctx.Plan(&PlanOpts{Destroy: true})
  3786  	if err != nil {
  3787  		t.Fatalf("err: %s", err)
  3788  	}
  3789  
  3790  	actual := strings.TrimSpace(plan.String())
  3791  	expected := strings.TrimSpace(testTerraformPlanModuleDestroyMultivarStr)
  3792  	if actual != expected {
  3793  		t.Fatalf("bad:\n%s", actual)
  3794  	}
  3795  }
  3796  
  3797  func TestContextPlan_pathVar(t *testing.T) {
  3798  	cwd, err := os.Getwd()
  3799  	if err != nil {
  3800  		t.Fatalf("err: %s", err)
  3801  	}
  3802  
  3803  	m := testModule(t, "plan-path-var")
  3804  	p := testProvider("aws")
  3805  	p.DiffFn = testDiffFn
  3806  	ctx := testContext(t, &ContextOpts{
  3807  		Module: m,
  3808  		Providers: map[string]ResourceProviderFactory{
  3809  			"aws": testProviderFuncFixed(p),
  3810  		},
  3811  	})
  3812  
  3813  	plan, err := ctx.Plan(nil)
  3814  	if err != nil {
  3815  		t.Fatalf("err: %s", err)
  3816  	}
  3817  
  3818  	actual := strings.TrimSpace(plan.String())
  3819  	expected := strings.TrimSpace(testTerraformPlanPathVarStr)
  3820  
  3821  	// Warning: this ordering REALLY matters for this test. The
  3822  	// order is: cwd, module, root.
  3823  	expected = fmt.Sprintf(
  3824  		expected,
  3825  		cwd,
  3826  		m.Config().Dir,
  3827  		m.Config().Dir)
  3828  
  3829  	if actual != expected {
  3830  		t.Fatalf("bad:\n%s\n\nexpected:\n\n%s", actual, expected)
  3831  	}
  3832  }
  3833  
  3834  func TestContextPlan_diffVar(t *testing.T) {
  3835  	m := testModule(t, "plan-diffvar")
  3836  	p := testProvider("aws")
  3837  	s := &State{
  3838  		Modules: []*ModuleState{
  3839  			&ModuleState{
  3840  				Path: rootModulePath,
  3841  				Resources: map[string]*ResourceState{
  3842  					"aws_instance.foo": &ResourceState{
  3843  						Primary: &InstanceState{
  3844  							ID: "bar",
  3845  							Attributes: map[string]string{
  3846  								"num": "2",
  3847  							},
  3848  						},
  3849  					},
  3850  				},
  3851  			},
  3852  		},
  3853  	}
  3854  	ctx := testContext(t, &ContextOpts{
  3855  		Module: m,
  3856  		Providers: map[string]ResourceProviderFactory{
  3857  			"aws": testProviderFuncFixed(p),
  3858  		},
  3859  		State: s,
  3860  	})
  3861  
  3862  	p.DiffFn = func(
  3863  		info *InstanceInfo,
  3864  		s *InstanceState,
  3865  		c *ResourceConfig) (*InstanceDiff, error) {
  3866  		if s.ID != "bar" {
  3867  			return testDiffFn(info, s, c)
  3868  		}
  3869  
  3870  		return &InstanceDiff{
  3871  			Attributes: map[string]*ResourceAttrDiff{
  3872  				"num": &ResourceAttrDiff{
  3873  					Old: "2",
  3874  					New: "3",
  3875  				},
  3876  			},
  3877  		}, nil
  3878  	}
  3879  
  3880  	plan, err := ctx.Plan(nil)
  3881  	if err != nil {
  3882  		t.Fatalf("err: %s", err)
  3883  	}
  3884  
  3885  	actual := strings.TrimSpace(plan.String())
  3886  	expected := strings.TrimSpace(testTerraformPlanDiffVarStr)
  3887  	if actual != expected {
  3888  		t.Fatalf("actual:\n%s\n\nexpected:\n%s", actual, expected)
  3889  	}
  3890  }
  3891  
  3892  func TestContextPlan_hook(t *testing.T) {
  3893  	m := testModule(t, "plan-good")
  3894  	h := new(MockHook)
  3895  	p := testProvider("aws")
  3896  	p.DiffFn = testDiffFn
  3897  	ctx := testContext(t, &ContextOpts{
  3898  		Module: m,
  3899  		Hooks:  []Hook{h},
  3900  		Providers: map[string]ResourceProviderFactory{
  3901  			"aws": testProviderFuncFixed(p),
  3902  		},
  3903  	})
  3904  
  3905  	_, err := ctx.Plan(nil)
  3906  	if err != nil {
  3907  		t.Fatalf("err: %s", err)
  3908  	}
  3909  
  3910  	if !h.PreDiffCalled {
  3911  		t.Fatal("should be called")
  3912  	}
  3913  	if !h.PostDiffCalled {
  3914  		t.Fatal("should be called")
  3915  	}
  3916  }
  3917  
  3918  func TestContextPlan_orphan(t *testing.T) {
  3919  	m := testModule(t, "plan-orphan")
  3920  	p := testProvider("aws")
  3921  	p.DiffFn = testDiffFn
  3922  	s := &State{
  3923  		Modules: []*ModuleState{
  3924  			&ModuleState{
  3925  				Path: rootModulePath,
  3926  				Resources: map[string]*ResourceState{
  3927  					"aws_instance.baz": &ResourceState{
  3928  						Type: "aws_instance",
  3929  						Primary: &InstanceState{
  3930  							ID: "bar",
  3931  						},
  3932  					},
  3933  				},
  3934  			},
  3935  		},
  3936  	}
  3937  	ctx := testContext(t, &ContextOpts{
  3938  		Module: m,
  3939  		Providers: map[string]ResourceProviderFactory{
  3940  			"aws": testProviderFuncFixed(p),
  3941  		},
  3942  		State: s,
  3943  	})
  3944  
  3945  	plan, err := ctx.Plan(nil)
  3946  	if err != nil {
  3947  		t.Fatalf("err: %s", err)
  3948  	}
  3949  
  3950  	actual := strings.TrimSpace(plan.String())
  3951  	expected := strings.TrimSpace(testTerraformPlanOrphanStr)
  3952  	if actual != expected {
  3953  		t.Fatalf("bad:\n%s", actual)
  3954  	}
  3955  }
  3956  
  3957  func TestContextPlan_state(t *testing.T) {
  3958  	m := testModule(t, "plan-good")
  3959  	p := testProvider("aws")
  3960  	p.DiffFn = testDiffFn
  3961  	s := &State{
  3962  		Modules: []*ModuleState{
  3963  			&ModuleState{
  3964  				Path: rootModulePath,
  3965  				Resources: map[string]*ResourceState{
  3966  					"aws_instance.foo": &ResourceState{
  3967  						Primary: &InstanceState{
  3968  							ID: "bar",
  3969  						},
  3970  					},
  3971  				},
  3972  			},
  3973  		},
  3974  	}
  3975  	ctx := testContext(t, &ContextOpts{
  3976  		Module: m,
  3977  		Providers: map[string]ResourceProviderFactory{
  3978  			"aws": testProviderFuncFixed(p),
  3979  		},
  3980  		State: s,
  3981  	})
  3982  
  3983  	plan, err := ctx.Plan(nil)
  3984  	if err != nil {
  3985  		t.Fatalf("err: %s", err)
  3986  	}
  3987  
  3988  	if len(plan.Diff.RootModule().Resources) < 2 {
  3989  		t.Fatalf("bad: %#v", plan.Diff.RootModule().Resources)
  3990  	}
  3991  
  3992  	actual := strings.TrimSpace(plan.String())
  3993  	expected := strings.TrimSpace(testTerraformPlanStateStr)
  3994  	if actual != expected {
  3995  		t.Fatalf("bad:\n%s\n\nexpected:\n\n%s", actual, expected)
  3996  	}
  3997  }
  3998  
  3999  func TestContextPlan_taint(t *testing.T) {
  4000  	m := testModule(t, "plan-taint")
  4001  	p := testProvider("aws")
  4002  	p.DiffFn = testDiffFn
  4003  	s := &State{
  4004  		Modules: []*ModuleState{
  4005  			&ModuleState{
  4006  				Path: rootModulePath,
  4007  				Resources: map[string]*ResourceState{
  4008  					"aws_instance.foo": &ResourceState{
  4009  						Type: "aws_instance",
  4010  						Primary: &InstanceState{
  4011  							ID:         "bar",
  4012  							Attributes: map[string]string{"num": "2"},
  4013  						},
  4014  					},
  4015  					"aws_instance.bar": &ResourceState{
  4016  						Type: "aws_instance",
  4017  						Tainted: []*InstanceState{
  4018  							&InstanceState{
  4019  								ID: "baz",
  4020  							},
  4021  						},
  4022  					},
  4023  				},
  4024  			},
  4025  		},
  4026  	}
  4027  	ctx := testContext(t, &ContextOpts{
  4028  		Module: m,
  4029  		Providers: map[string]ResourceProviderFactory{
  4030  			"aws": testProviderFuncFixed(p),
  4031  		},
  4032  		State: s,
  4033  	})
  4034  
  4035  	plan, err := ctx.Plan(nil)
  4036  	if err != nil {
  4037  		t.Fatalf("err: %s", err)
  4038  	}
  4039  
  4040  	actual := strings.TrimSpace(plan.String())
  4041  	expected := strings.TrimSpace(testTerraformPlanTaintStr)
  4042  	if actual != expected {
  4043  		t.Fatalf("bad:\n%s", actual)
  4044  	}
  4045  }
  4046  
  4047  // Doing a Refresh (or any operation really, but Refresh usually
  4048  // happens first) with a config with an unknown provider should result in
  4049  // an error. The key bug this found was that this wasn't happening if
  4050  // Providers was _empty_.
  4051  func TestContextRefresh_unknownProvider(t *testing.T) {
  4052  	m := testModule(t, "refresh-unknown-provider")
  4053  	p := testProvider("aws")
  4054  	p.ApplyFn = testApplyFn
  4055  	p.DiffFn = testDiffFn
  4056  	ctx := testContext(t, &ContextOpts{
  4057  		Module:    m,
  4058  		Providers: map[string]ResourceProviderFactory{},
  4059  	})
  4060  
  4061  	if _, err := ctx.Refresh(); err == nil {
  4062  		t.Fatal("should error")
  4063  	}
  4064  }
  4065  
  4066  func TestContextPlan_multiple_taint(t *testing.T) {
  4067  	m := testModule(t, "plan-taint")
  4068  	p := testProvider("aws")
  4069  	p.DiffFn = testDiffFn
  4070  	s := &State{
  4071  		Modules: []*ModuleState{
  4072  			&ModuleState{
  4073  				Path: rootModulePath,
  4074  				Resources: map[string]*ResourceState{
  4075  					"aws_instance.foo": &ResourceState{
  4076  						Type: "aws_instance",
  4077  						Primary: &InstanceState{
  4078  							ID:         "bar",
  4079  							Attributes: map[string]string{"num": "2"},
  4080  						},
  4081  					},
  4082  					"aws_instance.bar": &ResourceState{
  4083  						Type: "aws_instance",
  4084  						Tainted: []*InstanceState{
  4085  							&InstanceState{
  4086  								ID: "baz",
  4087  							},
  4088  							&InstanceState{
  4089  								ID: "zip",
  4090  							},
  4091  						},
  4092  					},
  4093  				},
  4094  			},
  4095  		},
  4096  	}
  4097  	ctx := testContext(t, &ContextOpts{
  4098  		Module: m,
  4099  		Providers: map[string]ResourceProviderFactory{
  4100  			"aws": testProviderFuncFixed(p),
  4101  		},
  4102  		State: s,
  4103  	})
  4104  
  4105  	plan, err := ctx.Plan(nil)
  4106  	if err != nil {
  4107  		t.Fatalf("err: %s", err)
  4108  	}
  4109  
  4110  	actual := strings.TrimSpace(plan.String())
  4111  	expected := strings.TrimSpace(testTerraformPlanMultipleTaintStr)
  4112  	if actual != expected {
  4113  		t.Fatalf("bad:\n%s", actual)
  4114  	}
  4115  }
  4116  
  4117  func TestContextPlan_provider(t *testing.T) {
  4118  	m := testModule(t, "plan-provider")
  4119  	p := testProvider("aws")
  4120  	p.DiffFn = testDiffFn
  4121  
  4122  	var value interface{}
  4123  	p.ConfigureFn = func(c *ResourceConfig) error {
  4124  		value, _ = c.Get("foo")
  4125  		return nil
  4126  	}
  4127  
  4128  	ctx := testContext(t, &ContextOpts{
  4129  		Module: m,
  4130  		Providers: map[string]ResourceProviderFactory{
  4131  			"aws": testProviderFuncFixed(p),
  4132  		},
  4133  		Variables: map[string]string{
  4134  			"foo": "bar",
  4135  		},
  4136  	})
  4137  
  4138  	if _, err := ctx.Plan(nil); err != nil {
  4139  		t.Fatalf("err: %s", err)
  4140  	}
  4141  
  4142  	if value != "bar" {
  4143  		t.Fatalf("bad: %#v", value)
  4144  	}
  4145  }
  4146  
  4147  func TestContextPlan_varMultiCountOne(t *testing.T) {
  4148  	m := testModule(t, "plan-var-multi-count-one")
  4149  	p := testProvider("aws")
  4150  	p.DiffFn = testDiffFn
  4151  	ctx := testContext(t, &ContextOpts{
  4152  		Module: m,
  4153  		Providers: map[string]ResourceProviderFactory{
  4154  			"aws": testProviderFuncFixed(p),
  4155  		},
  4156  	})
  4157  
  4158  	plan, err := ctx.Plan(nil)
  4159  	if err != nil {
  4160  		t.Fatalf("err: %s", err)
  4161  	}
  4162  
  4163  	actual := strings.TrimSpace(plan.String())
  4164  	expected := strings.TrimSpace(testTerraformPlanVarMultiCountOneStr)
  4165  	if actual != expected {
  4166  		t.Fatalf("bad:\n%s", actual)
  4167  	}
  4168  }
  4169  
  4170  func TestContextPlan_varListErr(t *testing.T) {
  4171  	m := testModule(t, "plan-var-list-err")
  4172  	p := testProvider("aws")
  4173  	ctx := testContext(t, &ContextOpts{
  4174  		Module: m,
  4175  		Providers: map[string]ResourceProviderFactory{
  4176  			"aws": testProviderFuncFixed(p),
  4177  		},
  4178  	})
  4179  
  4180  	_, err := ctx.Plan(nil)
  4181  	if err == nil {
  4182  		t.Fatal("should error")
  4183  	}
  4184  }
  4185  
  4186  func TestContextRefresh(t *testing.T) {
  4187  	p := testProvider("aws")
  4188  	m := testModule(t, "refresh-basic")
  4189  	ctx := testContext(t, &ContextOpts{
  4190  		Module: m,
  4191  		Providers: map[string]ResourceProviderFactory{
  4192  			"aws": testProviderFuncFixed(p),
  4193  		},
  4194  		State: &State{
  4195  			Modules: []*ModuleState{
  4196  				&ModuleState{
  4197  					Path: rootModulePath,
  4198  					Resources: map[string]*ResourceState{
  4199  						"aws_instance.web": &ResourceState{
  4200  							Type: "aws_instance",
  4201  							Primary: &InstanceState{
  4202  								ID: "foo",
  4203  							},
  4204  						},
  4205  					},
  4206  				},
  4207  			},
  4208  		},
  4209  	})
  4210  
  4211  	p.RefreshFn = nil
  4212  	p.RefreshReturn = &InstanceState{
  4213  		ID: "foo",
  4214  	}
  4215  
  4216  	s, err := ctx.Refresh()
  4217  	mod := s.RootModule()
  4218  	if err != nil {
  4219  		t.Fatalf("err: %s", err)
  4220  	}
  4221  	if !p.RefreshCalled {
  4222  		t.Fatal("refresh should be called")
  4223  	}
  4224  	if p.RefreshState.ID != "foo" {
  4225  		t.Fatalf("bad: %#v", p.RefreshState)
  4226  	}
  4227  	if !reflect.DeepEqual(mod.Resources["aws_instance.web"].Primary, p.RefreshReturn) {
  4228  		t.Fatalf("bad: %#v %#v", mod.Resources["aws_instance.web"], p.RefreshReturn)
  4229  	}
  4230  
  4231  	for _, r := range mod.Resources {
  4232  		if r.Type == "" {
  4233  			t.Fatalf("no type: %#v", r)
  4234  		}
  4235  	}
  4236  }
  4237  
  4238  func TestContextRefresh_delete(t *testing.T) {
  4239  	p := testProvider("aws")
  4240  	m := testModule(t, "refresh-basic")
  4241  	ctx := testContext(t, &ContextOpts{
  4242  		Module: m,
  4243  		Providers: map[string]ResourceProviderFactory{
  4244  			"aws": testProviderFuncFixed(p),
  4245  		},
  4246  		State: &State{
  4247  			Modules: []*ModuleState{
  4248  				&ModuleState{
  4249  					Path: rootModulePath,
  4250  					Resources: map[string]*ResourceState{
  4251  						"aws_instance.web": &ResourceState{
  4252  							Type: "aws_instance",
  4253  							Primary: &InstanceState{
  4254  								ID: "foo",
  4255  							},
  4256  						},
  4257  					},
  4258  				},
  4259  			},
  4260  		},
  4261  	})
  4262  
  4263  	p.RefreshFn = nil
  4264  	p.RefreshReturn = nil
  4265  
  4266  	s, err := ctx.Refresh()
  4267  	if err != nil {
  4268  		t.Fatalf("err: %s", err)
  4269  	}
  4270  
  4271  	mod := s.RootModule()
  4272  	if len(mod.Resources) > 0 {
  4273  		t.Fatal("resources should be empty")
  4274  	}
  4275  }
  4276  
  4277  func TestContextRefresh_ignoreUncreated(t *testing.T) {
  4278  	p := testProvider("aws")
  4279  	m := testModule(t, "refresh-basic")
  4280  	ctx := testContext(t, &ContextOpts{
  4281  		Module: m,
  4282  		Providers: map[string]ResourceProviderFactory{
  4283  			"aws": testProviderFuncFixed(p),
  4284  		},
  4285  		State: nil,
  4286  	})
  4287  
  4288  	p.RefreshFn = nil
  4289  	p.RefreshReturn = &InstanceState{
  4290  		ID: "foo",
  4291  	}
  4292  
  4293  	_, err := ctx.Refresh()
  4294  	if err != nil {
  4295  		t.Fatalf("err: %s", err)
  4296  	}
  4297  	if p.RefreshCalled {
  4298  		t.Fatal("refresh should not be called")
  4299  	}
  4300  }
  4301  
  4302  func TestContextRefresh_hook(t *testing.T) {
  4303  	h := new(MockHook)
  4304  	p := testProvider("aws")
  4305  	m := testModule(t, "refresh-basic")
  4306  	ctx := testContext(t, &ContextOpts{
  4307  		Module: m,
  4308  		Hooks:  []Hook{h},
  4309  		Providers: map[string]ResourceProviderFactory{
  4310  			"aws": testProviderFuncFixed(p),
  4311  		},
  4312  		State: &State{
  4313  			Modules: []*ModuleState{
  4314  				&ModuleState{
  4315  					Path: rootModulePath,
  4316  					Resources: map[string]*ResourceState{
  4317  						"aws_instance.web": &ResourceState{
  4318  							Type: "aws_instance",
  4319  							Primary: &InstanceState{
  4320  								ID: "foo",
  4321  							},
  4322  						},
  4323  					},
  4324  				},
  4325  			},
  4326  		},
  4327  	})
  4328  
  4329  	if _, err := ctx.Refresh(); err != nil {
  4330  		t.Fatalf("err: %s", err)
  4331  	}
  4332  	if !h.PreRefreshCalled {
  4333  		t.Fatal("should be called")
  4334  	}
  4335  	/*
  4336  		TODO(mitchcellh): remove when we add InstanceInfo param
  4337  		if h.PreRefreshState.Type != "aws_instance" {
  4338  			t.Fatalf("bad: %#v", h.PreRefreshState)
  4339  		}
  4340  	*/
  4341  	if !h.PostRefreshCalled {
  4342  		t.Fatal("should be called")
  4343  	}
  4344  	/*
  4345  		TODO(mitchcellh): remove when we add InstanceInfo param
  4346  		if h.PostRefreshState.Type != "aws_instance" {
  4347  			t.Fatalf("bad: %#v", h.PostRefreshState)
  4348  		}
  4349  	*/
  4350  }
  4351  
  4352  func TestContextRefresh_modules(t *testing.T) {
  4353  	p := testProvider("aws")
  4354  	m := testModule(t, "refresh-modules")
  4355  	state := &State{
  4356  		Modules: []*ModuleState{
  4357  			&ModuleState{
  4358  				Path: rootModulePath,
  4359  				Resources: map[string]*ResourceState{
  4360  					"aws_instance.web": &ResourceState{
  4361  						Type: "aws_instance",
  4362  						Tainted: []*InstanceState{
  4363  							&InstanceState{
  4364  								ID: "bar",
  4365  							},
  4366  						},
  4367  					},
  4368  				},
  4369  			},
  4370  
  4371  			&ModuleState{
  4372  				Path: []string{"root", "child"},
  4373  				Resources: map[string]*ResourceState{
  4374  					"aws_instance.web": &ResourceState{
  4375  						Type: "aws_instance",
  4376  						Primary: &InstanceState{
  4377  							ID: "baz",
  4378  						},
  4379  					},
  4380  				},
  4381  			},
  4382  		},
  4383  	}
  4384  	ctx := testContext(t, &ContextOpts{
  4385  		Module: m,
  4386  		Providers: map[string]ResourceProviderFactory{
  4387  			"aws": testProviderFuncFixed(p),
  4388  		},
  4389  		State: state,
  4390  	})
  4391  
  4392  	p.RefreshFn = func(info *InstanceInfo, s *InstanceState) (*InstanceState, error) {
  4393  		if s.ID != "baz" {
  4394  			return s, nil
  4395  		}
  4396  
  4397  		s.ID = "new"
  4398  		return s, nil
  4399  	}
  4400  
  4401  	s, err := ctx.Refresh()
  4402  	if err != nil {
  4403  		t.Fatalf("err: %s", err)
  4404  	}
  4405  
  4406  	actual := strings.TrimSpace(s.String())
  4407  	expected := strings.TrimSpace(testContextRefreshModuleStr)
  4408  	if actual != expected {
  4409  		t.Fatalf("bad:\n\n%s\n\n%s", actual, expected)
  4410  	}
  4411  }
  4412  
  4413  func TestContextRefresh_moduleInputComputedOutput(t *testing.T) {
  4414  	m := testModule(t, "refresh-module-input-computed-output")
  4415  	p := testProvider("aws")
  4416  	p.DiffFn = testDiffFn
  4417  	ctx := testContext(t, &ContextOpts{
  4418  		Module: m,
  4419  		Providers: map[string]ResourceProviderFactory{
  4420  			"aws": testProviderFuncFixed(p),
  4421  		},
  4422  	})
  4423  
  4424  	if _, err := ctx.Refresh(); err != nil {
  4425  		t.Fatalf("err: %s", err)
  4426  	}
  4427  }
  4428  
  4429  func TestContextRefresh_moduleVarModule(t *testing.T) {
  4430  	m := testModule(t, "refresh-module-var-module")
  4431  	p := testProvider("aws")
  4432  	p.DiffFn = testDiffFn
  4433  	ctx := testContext(t, &ContextOpts{
  4434  		Module: m,
  4435  		Providers: map[string]ResourceProviderFactory{
  4436  			"aws": testProviderFuncFixed(p),
  4437  		},
  4438  	})
  4439  
  4440  	if _, err := ctx.Refresh(); err != nil {
  4441  		t.Fatalf("err: %s", err)
  4442  	}
  4443  }
  4444  
  4445  // GH-70
  4446  func TestContextRefresh_noState(t *testing.T) {
  4447  	p := testProvider("aws")
  4448  	m := testModule(t, "refresh-no-state")
  4449  	ctx := testContext(t, &ContextOpts{
  4450  		Module: m,
  4451  		Providers: map[string]ResourceProviderFactory{
  4452  			"aws": testProviderFuncFixed(p),
  4453  		},
  4454  	})
  4455  
  4456  	p.RefreshFn = nil
  4457  	p.RefreshReturn = &InstanceState{
  4458  		ID: "foo",
  4459  	}
  4460  
  4461  	if _, err := ctx.Refresh(); err != nil {
  4462  		t.Fatalf("err: %s", err)
  4463  	}
  4464  }
  4465  
  4466  func TestContextRefresh_outputPartial(t *testing.T) {
  4467  	p := testProvider("aws")
  4468  	m := testModule(t, "refresh-output-partial")
  4469  	ctx := testContext(t, &ContextOpts{
  4470  		Module: m,
  4471  		Providers: map[string]ResourceProviderFactory{
  4472  			"aws": testProviderFuncFixed(p),
  4473  		},
  4474  		State: &State{
  4475  			Modules: []*ModuleState{
  4476  				&ModuleState{
  4477  					Path: rootModulePath,
  4478  					Resources: map[string]*ResourceState{
  4479  						"aws_instance.foo": &ResourceState{
  4480  							Type: "aws_instance",
  4481  							Primary: &InstanceState{
  4482  								ID: "foo",
  4483  							},
  4484  						},
  4485  					},
  4486  				},
  4487  			},
  4488  		},
  4489  	})
  4490  
  4491  	p.RefreshFn = nil
  4492  	p.RefreshReturn = nil
  4493  
  4494  	s, err := ctx.Refresh()
  4495  	if err != nil {
  4496  		t.Fatalf("err: %s", err)
  4497  	}
  4498  
  4499  	actual := strings.TrimSpace(s.String())
  4500  	expected := strings.TrimSpace(testContextRefreshOutputPartialStr)
  4501  	if actual != expected {
  4502  		t.Fatalf("bad:\n\n%s\n\n%s", actual, expected)
  4503  	}
  4504  }
  4505  
  4506  func TestContextRefresh_state(t *testing.T) {
  4507  	p := testProvider("aws")
  4508  	m := testModule(t, "refresh-basic")
  4509  	state := &State{
  4510  		Modules: []*ModuleState{
  4511  			&ModuleState{
  4512  				Path: rootModulePath,
  4513  				Resources: map[string]*ResourceState{
  4514  					"aws_instance.web": &ResourceState{
  4515  						Primary: &InstanceState{
  4516  							ID: "bar",
  4517  						},
  4518  					},
  4519  				},
  4520  			},
  4521  		},
  4522  	}
  4523  	ctx := testContext(t, &ContextOpts{
  4524  		Module: m,
  4525  		Providers: map[string]ResourceProviderFactory{
  4526  			"aws": testProviderFuncFixed(p),
  4527  		},
  4528  		State: state,
  4529  	})
  4530  
  4531  	p.RefreshFn = nil
  4532  	p.RefreshReturn = &InstanceState{
  4533  		ID: "foo",
  4534  	}
  4535  
  4536  	s, err := ctx.Refresh()
  4537  	if err != nil {
  4538  		t.Fatalf("err: %s", err)
  4539  	}
  4540  	originalMod := state.RootModule()
  4541  	mod := s.RootModule()
  4542  	if !p.RefreshCalled {
  4543  		t.Fatal("refresh should be called")
  4544  	}
  4545  	if !reflect.DeepEqual(p.RefreshState, originalMod.Resources["aws_instance.web"].Primary) {
  4546  		t.Fatalf("bad: %#v %#v", p.RefreshState, originalMod.Resources["aws_instance.web"].Primary)
  4547  	}
  4548  	if !reflect.DeepEqual(mod.Resources["aws_instance.web"].Primary, p.RefreshReturn) {
  4549  		t.Fatalf("bad: %#v", mod.Resources)
  4550  	}
  4551  }
  4552  
  4553  func TestContextRefresh_tainted(t *testing.T) {
  4554  	p := testProvider("aws")
  4555  	m := testModule(t, "refresh-basic")
  4556  	state := &State{
  4557  		Modules: []*ModuleState{
  4558  			&ModuleState{
  4559  				Path: rootModulePath,
  4560  				Resources: map[string]*ResourceState{
  4561  					"aws_instance.web": &ResourceState{
  4562  						Type: "aws_instance",
  4563  						Tainted: []*InstanceState{
  4564  							&InstanceState{
  4565  								ID: "bar",
  4566  							},
  4567  						},
  4568  					},
  4569  				},
  4570  			},
  4571  		},
  4572  	}
  4573  	ctx := testContext(t, &ContextOpts{
  4574  		Module: m,
  4575  		Providers: map[string]ResourceProviderFactory{
  4576  			"aws": testProviderFuncFixed(p),
  4577  		},
  4578  		State: state,
  4579  	})
  4580  
  4581  	p.RefreshFn = nil
  4582  	p.RefreshReturn = &InstanceState{
  4583  		ID: "foo",
  4584  	}
  4585  
  4586  	s, err := ctx.Refresh()
  4587  	if err != nil {
  4588  		t.Fatalf("err: %s", err)
  4589  	}
  4590  	if !p.RefreshCalled {
  4591  		t.Fatal("refresh should be called")
  4592  	}
  4593  
  4594  	actual := strings.TrimSpace(s.String())
  4595  	expected := strings.TrimSpace(testContextRefreshTaintedStr)
  4596  	if actual != expected {
  4597  		t.Fatalf("bad:\n\n%s\n\n%s", actual, expected)
  4598  	}
  4599  }
  4600  
  4601  func TestContextRefresh_vars(t *testing.T) {
  4602  	p := testProvider("aws")
  4603  	m := testModule(t, "refresh-vars")
  4604  	ctx := testContext(t, &ContextOpts{
  4605  		Module: m,
  4606  		Providers: map[string]ResourceProviderFactory{
  4607  			"aws": testProviderFuncFixed(p),
  4608  		},
  4609  		State: &State{
  4610  
  4611  			Modules: []*ModuleState{
  4612  				&ModuleState{
  4613  					Path: rootModulePath,
  4614  					Resources: map[string]*ResourceState{
  4615  						"aws_instance.web": &ResourceState{
  4616  							Type: "aws_instance",
  4617  							Primary: &InstanceState{
  4618  								ID: "foo",
  4619  							},
  4620  						},
  4621  					},
  4622  				},
  4623  			},
  4624  		},
  4625  	})
  4626  
  4627  	p.RefreshFn = nil
  4628  	p.RefreshReturn = &InstanceState{
  4629  		ID: "foo",
  4630  	}
  4631  
  4632  	s, err := ctx.Refresh()
  4633  	if err != nil {
  4634  		t.Fatalf("err: %s", err)
  4635  	}
  4636  	mod := s.RootModule()
  4637  	if !p.RefreshCalled {
  4638  		t.Fatal("refresh should be called")
  4639  	}
  4640  	if p.RefreshState.ID != "foo" {
  4641  		t.Fatalf("bad: %#v", p.RefreshState)
  4642  	}
  4643  	if !reflect.DeepEqual(mod.Resources["aws_instance.web"].Primary, p.RefreshReturn) {
  4644  		t.Fatalf("bad: %#v", mod.Resources["aws_instance.web"])
  4645  	}
  4646  
  4647  	for _, r := range mod.Resources {
  4648  		if r.Type == "" {
  4649  			t.Fatalf("no type: %#v", r)
  4650  		}
  4651  	}
  4652  }
  4653  
  4654  func testContext(t *testing.T, opts *ContextOpts) *Context {
  4655  	return NewContext(opts)
  4656  }
  4657  
  4658  func testApplyFn(
  4659  	info *InstanceInfo,
  4660  	s *InstanceState,
  4661  	d *InstanceDiff) (*InstanceState, error) {
  4662  	if d.Destroy {
  4663  		return nil, nil
  4664  	}
  4665  
  4666  	id := "foo"
  4667  	if idAttr, ok := d.Attributes["id"]; ok && !idAttr.NewComputed {
  4668  		id = idAttr.New
  4669  	}
  4670  
  4671  	result := &InstanceState{
  4672  		ID: id,
  4673  	}
  4674  
  4675  	if d != nil {
  4676  		result = result.MergeDiff(d)
  4677  	}
  4678  	return result, nil
  4679  }
  4680  
  4681  func testDiffFn(
  4682  	info *InstanceInfo,
  4683  	s *InstanceState,
  4684  	c *ResourceConfig) (*InstanceDiff, error) {
  4685  	var diff InstanceDiff
  4686  	diff.Attributes = make(map[string]*ResourceAttrDiff)
  4687  
  4688  	for k, v := range c.Raw {
  4689  		if _, ok := v.(string); !ok {
  4690  			continue
  4691  		}
  4692  
  4693  		if k == "nil" {
  4694  			return nil, nil
  4695  		}
  4696  
  4697  		// This key is used for other purposes
  4698  		if k == "compute_value" {
  4699  			continue
  4700  		}
  4701  
  4702  		if k == "compute" {
  4703  			attrDiff := &ResourceAttrDiff{
  4704  				Old:         "",
  4705  				New:         "",
  4706  				NewComputed: true,
  4707  			}
  4708  
  4709  			if cv, ok := c.Config["compute_value"]; ok {
  4710  				if cv.(string) == "1" {
  4711  					attrDiff.NewComputed = false
  4712  					attrDiff.New = fmt.Sprintf("computed_%s", v.(string))
  4713  				}
  4714  			}
  4715  
  4716  			diff.Attributes[v.(string)] = attrDiff
  4717  			continue
  4718  		}
  4719  
  4720  		// If this key is not computed, then look it up in the
  4721  		// cleaned config.
  4722  		found := false
  4723  		for _, ck := range c.ComputedKeys {
  4724  			if ck == k {
  4725  				found = true
  4726  				break
  4727  			}
  4728  		}
  4729  		if !found {
  4730  			v = c.Config[k]
  4731  		}
  4732  
  4733  		attrDiff := &ResourceAttrDiff{
  4734  			Old: "",
  4735  			New: v.(string),
  4736  		}
  4737  
  4738  		if k == "require_new" {
  4739  			attrDiff.RequiresNew = true
  4740  		}
  4741  		diff.Attributes[k] = attrDiff
  4742  	}
  4743  
  4744  	for _, k := range c.ComputedKeys {
  4745  		diff.Attributes[k] = &ResourceAttrDiff{
  4746  			Old:         "",
  4747  			NewComputed: true,
  4748  		}
  4749  	}
  4750  
  4751  	for k, v := range diff.Attributes {
  4752  		if v.NewComputed {
  4753  			continue
  4754  		}
  4755  
  4756  		old, ok := s.Attributes[k]
  4757  		if !ok {
  4758  			continue
  4759  		}
  4760  		if old == v.New {
  4761  			delete(diff.Attributes, k)
  4762  		}
  4763  	}
  4764  
  4765  	if !diff.Empty() {
  4766  		diff.Attributes["type"] = &ResourceAttrDiff{
  4767  			Old: "",
  4768  			New: info.Type,
  4769  		}
  4770  	}
  4771  
  4772  	return &diff, nil
  4773  }
  4774  
  4775  func testProvider(prefix string) *MockResourceProvider {
  4776  	p := new(MockResourceProvider)
  4777  	p.RefreshFn = func(info *InstanceInfo, s *InstanceState) (*InstanceState, error) {
  4778  		return s, nil
  4779  	}
  4780  	p.ResourcesReturn = []ResourceType{
  4781  		ResourceType{
  4782  			Name: fmt.Sprintf("%s_instance", prefix),
  4783  		},
  4784  	}
  4785  
  4786  	return p
  4787  }
  4788  
  4789  func testProvisioner() *MockResourceProvisioner {
  4790  	p := new(MockResourceProvisioner)
  4791  	return p
  4792  }
  4793  
  4794  const testContextGraph = `
  4795  root: root
  4796  aws_instance.bar
  4797    aws_instance.bar -> provider.aws
  4798  aws_instance.foo
  4799    aws_instance.foo -> provider.aws
  4800  provider.aws
  4801  root
  4802    root -> aws_instance.bar
  4803    root -> aws_instance.foo
  4804  `
  4805  
  4806  const testContextRefreshModuleStr = `
  4807  aws_instance.web: (1 tainted)
  4808    ID = <not created>
  4809    Tainted ID 1 = bar
  4810  
  4811  module.child:
  4812    aws_instance.web:
  4813      ID = new
  4814  `
  4815  
  4816  const testContextRefreshOutputPartialStr = `
  4817  <no state>
  4818  `
  4819  
  4820  const testContextRefreshTaintedStr = `
  4821  aws_instance.web: (1 tainted)
  4822    ID = <not created>
  4823    Tainted ID 1 = foo
  4824  `