github.com/bengesoff/terraform@v0.3.1-0.20141018223233-b25a53629922/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_createBeforeDestroy(t *testing.T) {
   917  	m := testModule(t, "apply-good-create-before")
   918  	p := testProvider("aws")
   919  	p.ApplyFn = testApplyFn
   920  	p.DiffFn = testDiffFn
   921  	state := &State{
   922  		Modules: []*ModuleState{
   923  			&ModuleState{
   924  				Path: rootModulePath,
   925  				Resources: map[string]*ResourceState{
   926  					"aws_instance.bar": &ResourceState{
   927  						Type: "aws_instance",
   928  						Primary: &InstanceState{
   929  							ID: "bar",
   930  							Attributes: map[string]string{
   931  								"require_new": "abc",
   932  							},
   933  						},
   934  					},
   935  				},
   936  			},
   937  		},
   938  	}
   939  	ctx := testContext(t, &ContextOpts{
   940  		Module: m,
   941  		Providers: map[string]ResourceProviderFactory{
   942  			"aws": testProviderFuncFixed(p),
   943  		},
   944  		State: state,
   945  	})
   946  
   947  	if _, err := ctx.Plan(nil); err != nil {
   948  		t.Fatalf("err: %s", err)
   949  	}
   950  
   951  	state, err := ctx.Apply()
   952  	if err != nil {
   953  		t.Fatalf("err: %s", err)
   954  	}
   955  
   956  	mod := state.RootModule()
   957  	if len(mod.Resources) != 1 {
   958  		t.Fatalf("bad: %#v", mod.Resources)
   959  	}
   960  
   961  	actual := strings.TrimSpace(state.String())
   962  	expected := strings.TrimSpace(testTerraformApplyCreateBeforeStr)
   963  	if actual != expected {
   964  		t.Fatalf("bad: \n%s", actual)
   965  	}
   966  }
   967  
   968  func TestContextApply_Minimal(t *testing.T) {
   969  	m := testModule(t, "apply-minimal")
   970  	p := testProvider("aws")
   971  	p.ApplyFn = testApplyFn
   972  	p.DiffFn = testDiffFn
   973  	ctx := testContext(t, &ContextOpts{
   974  		Module: m,
   975  		Providers: map[string]ResourceProviderFactory{
   976  			"aws": testProviderFuncFixed(p),
   977  		},
   978  	})
   979  
   980  	if _, err := ctx.Plan(nil); err != nil {
   981  		t.Fatalf("err: %s", err)
   982  	}
   983  
   984  	state, err := ctx.Apply()
   985  	if err != nil {
   986  		t.Fatalf("err: %s", err)
   987  	}
   988  
   989  	actual := strings.TrimSpace(state.String())
   990  	expected := strings.TrimSpace(testTerraformApplyMinimalStr)
   991  	if actual != expected {
   992  		t.Fatalf("bad: \n%s", actual)
   993  	}
   994  }
   995  
   996  func TestContextApply_badDiff(t *testing.T) {
   997  	m := testModule(t, "apply-good")
   998  	p := testProvider("aws")
   999  	p.ApplyFn = testApplyFn
  1000  	p.DiffFn = testDiffFn
  1001  	ctx := testContext(t, &ContextOpts{
  1002  		Module: m,
  1003  		Providers: map[string]ResourceProviderFactory{
  1004  			"aws": testProviderFuncFixed(p),
  1005  		},
  1006  	})
  1007  
  1008  	if _, err := ctx.Plan(nil); err != nil {
  1009  		t.Fatalf("err: %s", err)
  1010  	}
  1011  
  1012  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  1013  		return &InstanceDiff{
  1014  			Attributes: map[string]*ResourceAttrDiff{
  1015  				"newp": nil,
  1016  			},
  1017  		}, nil
  1018  	}
  1019  
  1020  	if _, err := ctx.Apply(); err == nil {
  1021  		t.Fatal("should error")
  1022  	}
  1023  }
  1024  
  1025  func TestContextApply_cancel(t *testing.T) {
  1026  	stopped := false
  1027  
  1028  	m := testModule(t, "apply-cancel")
  1029  	p := testProvider("aws")
  1030  	ctx := testContext(t, &ContextOpts{
  1031  		Module: m,
  1032  		Providers: map[string]ResourceProviderFactory{
  1033  			"aws": testProviderFuncFixed(p),
  1034  		},
  1035  	})
  1036  
  1037  	p.ApplyFn = func(*InstanceInfo, *InstanceState, *InstanceDiff) (*InstanceState, error) {
  1038  		if !stopped {
  1039  			stopped = true
  1040  			go ctx.Stop()
  1041  
  1042  			for {
  1043  				if ctx.sh.Stopped() {
  1044  					break
  1045  				}
  1046  			}
  1047  		}
  1048  
  1049  		return &InstanceState{
  1050  			ID: "foo",
  1051  			Attributes: map[string]string{
  1052  				"num": "2",
  1053  			},
  1054  		}, nil
  1055  	}
  1056  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  1057  		return &InstanceDiff{
  1058  			Attributes: map[string]*ResourceAttrDiff{
  1059  				"num": &ResourceAttrDiff{
  1060  					New: "bar",
  1061  				},
  1062  			},
  1063  		}, nil
  1064  	}
  1065  
  1066  	if _, err := ctx.Plan(nil); err != nil {
  1067  		t.Fatalf("err: %s", err)
  1068  	}
  1069  
  1070  	// Start the Apply in a goroutine
  1071  	stateCh := make(chan *State)
  1072  	go func() {
  1073  		state, err := ctx.Apply()
  1074  		if err != nil {
  1075  			panic(err)
  1076  		}
  1077  
  1078  		stateCh <- state
  1079  	}()
  1080  
  1081  	state := <-stateCh
  1082  
  1083  	mod := state.RootModule()
  1084  	if len(mod.Resources) != 1 {
  1085  		t.Fatalf("bad: %#v", mod.Resources)
  1086  	}
  1087  
  1088  	actual := strings.TrimSpace(state.String())
  1089  	expected := strings.TrimSpace(testTerraformApplyCancelStr)
  1090  	if actual != expected {
  1091  		t.Fatalf("bad: \n%s", actual)
  1092  	}
  1093  }
  1094  
  1095  func TestContextApply_compute(t *testing.T) {
  1096  	m := testModule(t, "apply-compute")
  1097  	p := testProvider("aws")
  1098  	p.ApplyFn = testApplyFn
  1099  	p.DiffFn = testDiffFn
  1100  	ctx := testContext(t, &ContextOpts{
  1101  		Module: m,
  1102  		Providers: map[string]ResourceProviderFactory{
  1103  			"aws": testProviderFuncFixed(p),
  1104  		},
  1105  	})
  1106  
  1107  	if _, err := ctx.Plan(nil); err != nil {
  1108  		t.Fatalf("err: %s", err)
  1109  	}
  1110  
  1111  	ctx.variables = map[string]string{"value": "1"}
  1112  
  1113  	state, err := ctx.Apply()
  1114  	if err != nil {
  1115  		t.Fatalf("err: %s", err)
  1116  	}
  1117  
  1118  	actual := strings.TrimSpace(state.String())
  1119  	expected := strings.TrimSpace(testTerraformApplyComputeStr)
  1120  	if actual != expected {
  1121  		t.Fatalf("bad: \n%s", actual)
  1122  	}
  1123  }
  1124  
  1125  func TestContextApply_countDecrease(t *testing.T) {
  1126  	m := testModule(t, "apply-count-dec")
  1127  	p := testProvider("aws")
  1128  	p.DiffFn = testDiffFn
  1129  	s := &State{
  1130  		Modules: []*ModuleState{
  1131  			&ModuleState{
  1132  				Path: rootModulePath,
  1133  				Resources: map[string]*ResourceState{
  1134  					"aws_instance.foo.0": &ResourceState{
  1135  						Type: "aws_instance",
  1136  						Primary: &InstanceState{
  1137  							ID: "bar",
  1138  							Attributes: map[string]string{
  1139  								"foo":  "foo",
  1140  								"type": "aws_instance",
  1141  							},
  1142  						},
  1143  					},
  1144  					"aws_instance.foo.1": &ResourceState{
  1145  						Type: "aws_instance",
  1146  						Primary: &InstanceState{
  1147  							ID: "bar",
  1148  							Attributes: map[string]string{
  1149  								"foo":  "foo",
  1150  								"type": "aws_instance",
  1151  							},
  1152  						},
  1153  					},
  1154  					"aws_instance.foo.2": &ResourceState{
  1155  						Type: "aws_instance",
  1156  						Primary: &InstanceState{
  1157  							ID: "bar",
  1158  							Attributes: map[string]string{
  1159  								"foo":  "foo",
  1160  								"type": "aws_instance",
  1161  							},
  1162  						},
  1163  					},
  1164  				},
  1165  			},
  1166  		},
  1167  	}
  1168  	ctx := testContext(t, &ContextOpts{
  1169  		Module: m,
  1170  		Providers: map[string]ResourceProviderFactory{
  1171  			"aws": testProviderFuncFixed(p),
  1172  		},
  1173  		State: s,
  1174  	})
  1175  
  1176  	if _, err := ctx.Plan(nil); err != nil {
  1177  		t.Fatalf("err: %s", err)
  1178  	}
  1179  
  1180  	state, err := ctx.Apply()
  1181  	if err != nil {
  1182  		t.Fatalf("err: %s", err)
  1183  	}
  1184  
  1185  	actual := strings.TrimSpace(state.String())
  1186  	expected := strings.TrimSpace(testTerraformApplyCountDecStr)
  1187  	if actual != expected {
  1188  		t.Fatalf("bad: \n%s", actual)
  1189  	}
  1190  }
  1191  
  1192  func TestContextApply_countDecreaseToOne(t *testing.T) {
  1193  	m := testModule(t, "apply-count-dec-one")
  1194  	p := testProvider("aws")
  1195  	p.DiffFn = testDiffFn
  1196  	s := &State{
  1197  		Modules: []*ModuleState{
  1198  			&ModuleState{
  1199  				Path: rootModulePath,
  1200  				Resources: map[string]*ResourceState{
  1201  					"aws_instance.foo.0": &ResourceState{
  1202  						Type: "aws_instance",
  1203  						Primary: &InstanceState{
  1204  							ID: "bar",
  1205  							Attributes: map[string]string{
  1206  								"foo":  "foo",
  1207  								"type": "aws_instance",
  1208  							},
  1209  						},
  1210  					},
  1211  					"aws_instance.foo.1": &ResourceState{
  1212  						Type: "aws_instance",
  1213  						Primary: &InstanceState{
  1214  							ID: "bar",
  1215  						},
  1216  					},
  1217  					"aws_instance.foo.2": &ResourceState{
  1218  						Type: "aws_instance",
  1219  						Primary: &InstanceState{
  1220  							ID: "bar",
  1221  						},
  1222  					},
  1223  				},
  1224  			},
  1225  		},
  1226  	}
  1227  	ctx := testContext(t, &ContextOpts{
  1228  		Module: m,
  1229  		Providers: map[string]ResourceProviderFactory{
  1230  			"aws": testProviderFuncFixed(p),
  1231  		},
  1232  		State: s,
  1233  	})
  1234  
  1235  	if _, err := ctx.Plan(nil); err != nil {
  1236  		t.Fatalf("err: %s", err)
  1237  	}
  1238  
  1239  	state, err := ctx.Apply()
  1240  	if err != nil {
  1241  		t.Fatalf("err: %s", err)
  1242  	}
  1243  
  1244  	actual := strings.TrimSpace(state.String())
  1245  	expected := strings.TrimSpace(testTerraformApplyCountDecToOneStr)
  1246  	if actual != expected {
  1247  		t.Fatalf("bad: \n%s", actual)
  1248  	}
  1249  }
  1250  
  1251  func TestContextApply_countTainted(t *testing.T) {
  1252  	m := testModule(t, "apply-count-tainted")
  1253  	p := testProvider("aws")
  1254  	p.DiffFn = testDiffFn
  1255  	s := &State{
  1256  		Modules: []*ModuleState{
  1257  			&ModuleState{
  1258  				Path: rootModulePath,
  1259  				Resources: map[string]*ResourceState{
  1260  					"aws_instance.foo.0": &ResourceState{
  1261  						Type: "aws_instance",
  1262  						Tainted: []*InstanceState{
  1263  							&InstanceState{
  1264  								ID: "bar",
  1265  								Attributes: map[string]string{
  1266  									"foo":  "foo",
  1267  									"type": "aws_instance",
  1268  								},
  1269  							},
  1270  						},
  1271  					},
  1272  				},
  1273  			},
  1274  		},
  1275  	}
  1276  	ctx := testContext(t, &ContextOpts{
  1277  		Module: m,
  1278  		Providers: map[string]ResourceProviderFactory{
  1279  			"aws": testProviderFuncFixed(p),
  1280  		},
  1281  		State: s,
  1282  	})
  1283  
  1284  	if _, err := ctx.Plan(nil); err != nil {
  1285  		t.Fatalf("err: %s", err)
  1286  	}
  1287  
  1288  	state, err := ctx.Apply()
  1289  	if err != nil {
  1290  		t.Fatalf("err: %s", err)
  1291  	}
  1292  
  1293  	actual := strings.TrimSpace(state.String())
  1294  	expected := strings.TrimSpace(testTerraformApplyCountTaintedStr)
  1295  	if actual != expected {
  1296  		t.Fatalf("bad: \n%s", actual)
  1297  	}
  1298  }
  1299  
  1300  func TestContextApply_countVariable(t *testing.T) {
  1301  	m := testModule(t, "apply-count-variable")
  1302  	p := testProvider("aws")
  1303  	p.ApplyFn = testApplyFn
  1304  	p.DiffFn = testDiffFn
  1305  	ctx := testContext(t, &ContextOpts{
  1306  		Module: m,
  1307  		Providers: map[string]ResourceProviderFactory{
  1308  			"aws": testProviderFuncFixed(p),
  1309  		},
  1310  	})
  1311  
  1312  	if _, err := ctx.Plan(nil); err != nil {
  1313  		t.Fatalf("err: %s", err)
  1314  	}
  1315  
  1316  	state, err := ctx.Apply()
  1317  	if err != nil {
  1318  		t.Fatalf("err: %s", err)
  1319  	}
  1320  
  1321  	actual := strings.TrimSpace(state.String())
  1322  	expected := strings.TrimSpace(testTerraformApplyCountVariableStr)
  1323  	if actual != expected {
  1324  		t.Fatalf("bad: \n%s", actual)
  1325  	}
  1326  }
  1327  
  1328  func TestContextApply_module(t *testing.T) {
  1329  	m := testModule(t, "apply-module")
  1330  	p := testProvider("aws")
  1331  	p.ApplyFn = testApplyFn
  1332  	p.DiffFn = testDiffFn
  1333  	ctx := testContext(t, &ContextOpts{
  1334  		Module: m,
  1335  		Providers: map[string]ResourceProviderFactory{
  1336  			"aws": testProviderFuncFixed(p),
  1337  		},
  1338  	})
  1339  
  1340  	if _, err := ctx.Plan(nil); err != nil {
  1341  		t.Fatalf("err: %s", err)
  1342  	}
  1343  
  1344  	state, err := ctx.Apply()
  1345  	if err != nil {
  1346  		t.Fatalf("err: %s", err)
  1347  	}
  1348  
  1349  	actual := strings.TrimSpace(state.String())
  1350  	expected := strings.TrimSpace(testTerraformApplyModuleStr)
  1351  	if actual != expected {
  1352  		t.Fatalf("bad: \n%s", actual)
  1353  	}
  1354  }
  1355  
  1356  func TestContextApply_nilDiff(t *testing.T) {
  1357  	m := testModule(t, "apply-good")
  1358  	p := testProvider("aws")
  1359  	p.ApplyFn = testApplyFn
  1360  	p.DiffFn = testDiffFn
  1361  	ctx := testContext(t, &ContextOpts{
  1362  		Module: m,
  1363  		Providers: map[string]ResourceProviderFactory{
  1364  			"aws": testProviderFuncFixed(p),
  1365  		},
  1366  	})
  1367  
  1368  	if _, err := ctx.Plan(nil); err != nil {
  1369  		t.Fatalf("err: %s", err)
  1370  	}
  1371  
  1372  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  1373  		return nil, nil
  1374  	}
  1375  
  1376  	if _, err := ctx.Apply(); err == nil {
  1377  		t.Fatal("should error")
  1378  	}
  1379  }
  1380  
  1381  func TestContextApply_Provisioner_compute(t *testing.T) {
  1382  	m := testModule(t, "apply-provisioner-compute")
  1383  	p := testProvider("aws")
  1384  	pr := testProvisioner()
  1385  	p.ApplyFn = testApplyFn
  1386  	p.DiffFn = testDiffFn
  1387  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  1388  		val, ok := c.Config["foo"]
  1389  		if !ok || val != "computed_dynamical" {
  1390  			t.Fatalf("bad value for foo: %v %#v", val, c)
  1391  		}
  1392  
  1393  		return nil
  1394  	}
  1395  	ctx := testContext(t, &ContextOpts{
  1396  		Module: m,
  1397  		Providers: map[string]ResourceProviderFactory{
  1398  			"aws": testProviderFuncFixed(p),
  1399  		},
  1400  		Provisioners: map[string]ResourceProvisionerFactory{
  1401  			"shell": testProvisionerFuncFixed(pr),
  1402  		},
  1403  		Variables: map[string]string{
  1404  			"value": "1",
  1405  		},
  1406  	})
  1407  
  1408  	if _, err := ctx.Plan(nil); err != nil {
  1409  		t.Fatalf("err: %s", err)
  1410  	}
  1411  
  1412  	state, err := ctx.Apply()
  1413  	if err != nil {
  1414  		t.Fatalf("err: %s", err)
  1415  	}
  1416  
  1417  	actual := strings.TrimSpace(state.String())
  1418  	expected := strings.TrimSpace(testTerraformApplyProvisionerStr)
  1419  	if actual != expected {
  1420  		t.Fatalf("bad: \n%s", actual)
  1421  	}
  1422  
  1423  	// Verify apply was invoked
  1424  	if !pr.ApplyCalled {
  1425  		t.Fatalf("provisioner not invoked")
  1426  	}
  1427  }
  1428  
  1429  func TestContextApply_provisionerCreateFail(t *testing.T) {
  1430  	m := testModule(t, "apply-provisioner-fail-create")
  1431  	p := testProvider("aws")
  1432  	pr := testProvisioner()
  1433  	p.DiffFn = testDiffFn
  1434  
  1435  	p.ApplyFn = func(
  1436  		info *InstanceInfo,
  1437  		is *InstanceState,
  1438  		id *InstanceDiff) (*InstanceState, error) {
  1439  		is.ID = "foo"
  1440  		return is, fmt.Errorf("error")
  1441  	}
  1442  
  1443  	ctx := testContext(t, &ContextOpts{
  1444  		Module: m,
  1445  		Providers: map[string]ResourceProviderFactory{
  1446  			"aws": testProviderFuncFixed(p),
  1447  		},
  1448  		Provisioners: map[string]ResourceProvisionerFactory{
  1449  			"shell": testProvisionerFuncFixed(pr),
  1450  		},
  1451  	})
  1452  
  1453  	if _, err := ctx.Plan(nil); err != nil {
  1454  		t.Fatalf("err: %s", err)
  1455  	}
  1456  
  1457  	state, err := ctx.Apply()
  1458  	if err == nil {
  1459  		t.Fatal("should error")
  1460  	}
  1461  
  1462  	actual := strings.TrimSpace(state.String())
  1463  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailCreateStr)
  1464  	if actual != expected {
  1465  		t.Fatalf("bad: \n%s", actual)
  1466  	}
  1467  }
  1468  
  1469  func TestContextApply_provisionerCreateFailNoId(t *testing.T) {
  1470  	m := testModule(t, "apply-provisioner-fail-create")
  1471  	p := testProvider("aws")
  1472  	pr := testProvisioner()
  1473  	p.DiffFn = testDiffFn
  1474  
  1475  	p.ApplyFn = func(
  1476  		info *InstanceInfo,
  1477  		is *InstanceState,
  1478  		id *InstanceDiff) (*InstanceState, error) {
  1479  		return nil, fmt.Errorf("error")
  1480  	}
  1481  
  1482  	ctx := testContext(t, &ContextOpts{
  1483  		Module: m,
  1484  		Providers: map[string]ResourceProviderFactory{
  1485  			"aws": testProviderFuncFixed(p),
  1486  		},
  1487  		Provisioners: map[string]ResourceProvisionerFactory{
  1488  			"shell": testProvisionerFuncFixed(pr),
  1489  		},
  1490  	})
  1491  
  1492  	if _, err := ctx.Plan(nil); err != nil {
  1493  		t.Fatalf("err: %s", err)
  1494  	}
  1495  
  1496  	state, err := ctx.Apply()
  1497  	if err == nil {
  1498  		t.Fatal("should error")
  1499  	}
  1500  
  1501  	actual := strings.TrimSpace(state.String())
  1502  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailCreateNoIdStr)
  1503  	if actual != expected {
  1504  		t.Fatalf("bad: \n%s", actual)
  1505  	}
  1506  }
  1507  
  1508  func TestContextApply_provisionerFail(t *testing.T) {
  1509  	m := testModule(t, "apply-provisioner-fail")
  1510  	p := testProvider("aws")
  1511  	pr := testProvisioner()
  1512  	p.ApplyFn = testApplyFn
  1513  	p.DiffFn = testDiffFn
  1514  
  1515  	pr.ApplyFn = func(*InstanceState, *ResourceConfig) error {
  1516  		return fmt.Errorf("EXPLOSION")
  1517  	}
  1518  
  1519  	ctx := testContext(t, &ContextOpts{
  1520  		Module: m,
  1521  		Providers: map[string]ResourceProviderFactory{
  1522  			"aws": testProviderFuncFixed(p),
  1523  		},
  1524  		Provisioners: map[string]ResourceProvisionerFactory{
  1525  			"shell": testProvisionerFuncFixed(pr),
  1526  		},
  1527  		Variables: map[string]string{
  1528  			"value": "1",
  1529  		},
  1530  	})
  1531  
  1532  	if _, err := ctx.Plan(nil); err != nil {
  1533  		t.Fatalf("err: %s", err)
  1534  	}
  1535  
  1536  	state, err := ctx.Apply()
  1537  	if err == nil {
  1538  		t.Fatal("should error")
  1539  	}
  1540  
  1541  	actual := strings.TrimSpace(state.String())
  1542  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailStr)
  1543  	if actual != expected {
  1544  		t.Fatalf("bad: \n%s", actual)
  1545  	}
  1546  }
  1547  
  1548  func TestContextApply_provisionerFail_createBeforeDestroy(t *testing.T) {
  1549  	m := testModule(t, "apply-provisioner-fail-create-before")
  1550  	p := testProvider("aws")
  1551  	pr := testProvisioner()
  1552  	p.ApplyFn = testApplyFn
  1553  	p.DiffFn = testDiffFn
  1554  	pr.ApplyFn = func(*InstanceState, *ResourceConfig) error {
  1555  		return fmt.Errorf("EXPLOSION")
  1556  	}
  1557  
  1558  	state := &State{
  1559  		Modules: []*ModuleState{
  1560  			&ModuleState{
  1561  				Path: rootModulePath,
  1562  				Resources: map[string]*ResourceState{
  1563  					"aws_instance.bar": &ResourceState{
  1564  						Type: "aws_instance",
  1565  						Primary: &InstanceState{
  1566  							ID: "bar",
  1567  							Attributes: map[string]string{
  1568  								"require_new": "abc",
  1569  							},
  1570  						},
  1571  					},
  1572  				},
  1573  			},
  1574  		},
  1575  	}
  1576  	ctx := testContext(t, &ContextOpts{
  1577  		Module: m,
  1578  		Providers: map[string]ResourceProviderFactory{
  1579  			"aws": testProviderFuncFixed(p),
  1580  		},
  1581  		Provisioners: map[string]ResourceProvisionerFactory{
  1582  			"shell": testProvisionerFuncFixed(pr),
  1583  		},
  1584  		State: state,
  1585  	})
  1586  
  1587  	if _, err := ctx.Plan(nil); err != nil {
  1588  		t.Fatalf("err: %s", err)
  1589  	}
  1590  
  1591  	state, err := ctx.Apply()
  1592  	if err == nil {
  1593  		t.Fatal("should error")
  1594  	}
  1595  
  1596  	actual := strings.TrimSpace(state.String())
  1597  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailCreateBeforeDestroyStr)
  1598  	if actual != expected {
  1599  		t.Fatalf("bad: \n%s", actual)
  1600  	}
  1601  }
  1602  
  1603  func TestContextApply_error_createBeforeDestroy(t *testing.T) {
  1604  	m := testModule(t, "apply-error-create-before")
  1605  	p := testProvider("aws")
  1606  	state := &State{
  1607  		Modules: []*ModuleState{
  1608  			&ModuleState{
  1609  				Path: rootModulePath,
  1610  				Resources: map[string]*ResourceState{
  1611  					"aws_instance.bar": &ResourceState{
  1612  						Type: "aws_instance",
  1613  						Primary: &InstanceState{
  1614  							ID: "bar",
  1615  							Attributes: map[string]string{
  1616  								"require_new": "abc",
  1617  							},
  1618  						},
  1619  					},
  1620  				},
  1621  			},
  1622  		},
  1623  	}
  1624  	ctx := testContext(t, &ContextOpts{
  1625  		Module: m,
  1626  		Providers: map[string]ResourceProviderFactory{
  1627  			"aws": testProviderFuncFixed(p),
  1628  		},
  1629  		State: state,
  1630  	})
  1631  	p.ApplyFn = func(info *InstanceInfo, is *InstanceState, id *InstanceDiff) (*InstanceState, error) {
  1632  		return nil, fmt.Errorf("error")
  1633  	}
  1634  	p.DiffFn = testDiffFn
  1635  
  1636  	if _, err := ctx.Plan(nil); err != nil {
  1637  		t.Fatalf("err: %s", err)
  1638  	}
  1639  
  1640  	state, err := ctx.Apply()
  1641  	if err == nil {
  1642  		t.Fatal("should have error")
  1643  	}
  1644  
  1645  	actual := strings.TrimSpace(state.String())
  1646  	expected := strings.TrimSpace(testTerraformApplyErrorCreateBeforeDestroyStr)
  1647  	if actual != expected {
  1648  		t.Fatalf("bad: \n%s\n\n\n%s", actual, expected)
  1649  	}
  1650  }
  1651  
  1652  func TestContextApply_errorDestroy_createBeforeDestroy(t *testing.T) {
  1653  	m := testModule(t, "apply-error-create-before")
  1654  	p := testProvider("aws")
  1655  	state := &State{
  1656  		Modules: []*ModuleState{
  1657  			&ModuleState{
  1658  				Path: rootModulePath,
  1659  				Resources: map[string]*ResourceState{
  1660  					"aws_instance.bar": &ResourceState{
  1661  						Type: "aws_instance",
  1662  						Primary: &InstanceState{
  1663  							ID: "bar",
  1664  							Attributes: map[string]string{
  1665  								"require_new": "abc",
  1666  							},
  1667  						},
  1668  					},
  1669  				},
  1670  			},
  1671  		},
  1672  	}
  1673  	ctx := testContext(t, &ContextOpts{
  1674  		Module: m,
  1675  		Providers: map[string]ResourceProviderFactory{
  1676  			"aws": testProviderFuncFixed(p),
  1677  		},
  1678  		State: state,
  1679  	})
  1680  	p.ApplyFn = func(info *InstanceInfo, is *InstanceState, id *InstanceDiff) (*InstanceState, error) {
  1681  		// Fail the destroy!
  1682  		if id.Destroy {
  1683  			return is, fmt.Errorf("error")
  1684  		}
  1685  
  1686  		// Create should work
  1687  		is = &InstanceState{
  1688  			ID: "foo",
  1689  		}
  1690  		return is, nil
  1691  	}
  1692  	p.DiffFn = testDiffFn
  1693  
  1694  	if _, err := ctx.Plan(nil); err != nil {
  1695  		t.Fatalf("err: %s", err)
  1696  	}
  1697  
  1698  	state, err := ctx.Apply()
  1699  	if err == nil {
  1700  		t.Fatal("should have error")
  1701  	}
  1702  
  1703  	actual := strings.TrimSpace(state.String())
  1704  	expected := strings.TrimSpace(testTerraformApplyErrorDestroyCreateBeforeDestroyStr)
  1705  	if actual != expected {
  1706  		t.Fatalf("bad: actual:\n%s\n\nexpected:\n%s", actual, expected)
  1707  	}
  1708  }
  1709  
  1710  func TestContextApply_provisionerResourceRef(t *testing.T) {
  1711  	m := testModule(t, "apply-provisioner-resource-ref")
  1712  	p := testProvider("aws")
  1713  	pr := testProvisioner()
  1714  	p.ApplyFn = testApplyFn
  1715  	p.DiffFn = testDiffFn
  1716  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  1717  		val, ok := c.Config["foo"]
  1718  		if !ok || val != "2" {
  1719  			t.Fatalf("bad value for foo: %v %#v", val, c)
  1720  		}
  1721  
  1722  		return nil
  1723  	}
  1724  
  1725  	ctx := testContext(t, &ContextOpts{
  1726  		Module: m,
  1727  		Providers: map[string]ResourceProviderFactory{
  1728  			"aws": testProviderFuncFixed(p),
  1729  		},
  1730  		Provisioners: map[string]ResourceProvisionerFactory{
  1731  			"shell": testProvisionerFuncFixed(pr),
  1732  		},
  1733  	})
  1734  
  1735  	if _, err := ctx.Plan(nil); err != nil {
  1736  		t.Fatalf("err: %s", err)
  1737  	}
  1738  
  1739  	state, err := ctx.Apply()
  1740  	if err != nil {
  1741  		t.Fatalf("err: %s", err)
  1742  	}
  1743  
  1744  	actual := strings.TrimSpace(state.String())
  1745  	expected := strings.TrimSpace(testTerraformApplyProvisionerResourceRefStr)
  1746  	if actual != expected {
  1747  		t.Fatalf("bad: \n%s", actual)
  1748  	}
  1749  
  1750  	// Verify apply was invoked
  1751  	if !pr.ApplyCalled {
  1752  		t.Fatalf("provisioner not invoked")
  1753  	}
  1754  }
  1755  
  1756  // Provisioner should NOT run on a diff, only create
  1757  func TestContextApply_Provisioner_Diff(t *testing.T) {
  1758  	m := testModule(t, "apply-provisioner-diff")
  1759  	p := testProvider("aws")
  1760  	pr := testProvisioner()
  1761  	p.ApplyFn = testApplyFn
  1762  	p.DiffFn = testDiffFn
  1763  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  1764  		return nil
  1765  	}
  1766  	ctx := testContext(t, &ContextOpts{
  1767  		Module: m,
  1768  		Providers: map[string]ResourceProviderFactory{
  1769  			"aws": testProviderFuncFixed(p),
  1770  		},
  1771  		Provisioners: map[string]ResourceProvisionerFactory{
  1772  			"shell": testProvisionerFuncFixed(pr),
  1773  		},
  1774  	})
  1775  
  1776  	if _, err := ctx.Plan(nil); err != nil {
  1777  		t.Fatalf("err: %s", err)
  1778  	}
  1779  
  1780  	state, err := ctx.Apply()
  1781  	if err != nil {
  1782  		t.Fatalf("err: %s", err)
  1783  	}
  1784  
  1785  	actual := strings.TrimSpace(state.String())
  1786  	expected := strings.TrimSpace(testTerraformApplyProvisionerDiffStr)
  1787  	if actual != expected {
  1788  		t.Fatalf("bad: \n%s", actual)
  1789  	}
  1790  
  1791  	// Verify apply was invoked
  1792  	if !pr.ApplyCalled {
  1793  		t.Fatalf("provisioner not invoked")
  1794  	}
  1795  	pr.ApplyCalled = false
  1796  
  1797  	// Change the state to force a diff
  1798  	mod := state.RootModule()
  1799  	mod.Resources["aws_instance.bar"].Primary.Attributes["foo"] = "baz"
  1800  
  1801  	// Re-create context with state
  1802  	ctx = testContext(t, &ContextOpts{
  1803  		Module: m,
  1804  		Providers: map[string]ResourceProviderFactory{
  1805  			"aws": testProviderFuncFixed(p),
  1806  		},
  1807  		Provisioners: map[string]ResourceProvisionerFactory{
  1808  			"shell": testProvisionerFuncFixed(pr),
  1809  		},
  1810  		State: state,
  1811  	})
  1812  
  1813  	if _, err := ctx.Plan(nil); err != nil {
  1814  		t.Fatalf("err: %s", err)
  1815  	}
  1816  
  1817  	state2, err := ctx.Apply()
  1818  	if err != nil {
  1819  		t.Fatalf("err: %s", err)
  1820  	}
  1821  
  1822  	actual = strings.TrimSpace(state2.String())
  1823  	if actual != expected {
  1824  		t.Fatalf("bad: \n%s", actual)
  1825  	}
  1826  
  1827  	// Verify apply was NOT invoked
  1828  	if pr.ApplyCalled {
  1829  		t.Fatalf("provisioner invoked")
  1830  	}
  1831  }
  1832  
  1833  func TestContextApply_outputDiffVars(t *testing.T) {
  1834  	m := testModule(t, "apply-good")
  1835  	p := testProvider("aws")
  1836  	s := &State{
  1837  		Modules: []*ModuleState{
  1838  			&ModuleState{
  1839  				Path: rootModulePath,
  1840  				Resources: map[string]*ResourceState{
  1841  					"aws_instance.baz": &ResourceState{
  1842  						Type: "aws_instance",
  1843  						Primary: &InstanceState{
  1844  							ID: "bar",
  1845  						},
  1846  					},
  1847  				},
  1848  			},
  1849  		},
  1850  	}
  1851  	ctx := testContext(t, &ContextOpts{
  1852  		Module: m,
  1853  		Providers: map[string]ResourceProviderFactory{
  1854  			"aws": testProviderFuncFixed(p),
  1855  		},
  1856  		State: s,
  1857  	})
  1858  
  1859  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  1860  		for k, ad := range d.Attributes {
  1861  			if ad.NewComputed {
  1862  				return nil, fmt.Errorf("%s: computed", k)
  1863  			}
  1864  		}
  1865  
  1866  		result := s.MergeDiff(d)
  1867  		result.ID = "foo"
  1868  		return result, nil
  1869  	}
  1870  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  1871  		return &InstanceDiff{
  1872  			Attributes: map[string]*ResourceAttrDiff{
  1873  				"foo": &ResourceAttrDiff{
  1874  					NewComputed: true,
  1875  					Type:        DiffAttrOutput,
  1876  				},
  1877  				"bar": &ResourceAttrDiff{
  1878  					New: "baz",
  1879  				},
  1880  			},
  1881  		}, nil
  1882  	}
  1883  
  1884  	if _, err := ctx.Plan(nil); err != nil {
  1885  		t.Fatalf("err: %s", err)
  1886  	}
  1887  	if _, err := ctx.Apply(); err != nil {
  1888  		t.Fatalf("err: %s", err)
  1889  	}
  1890  }
  1891  
  1892  func TestContextApply_Provisioner_ConnInfo(t *testing.T) {
  1893  	m := testModule(t, "apply-provisioner-conninfo")
  1894  	p := testProvider("aws")
  1895  	pr := testProvisioner()
  1896  
  1897  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  1898  		if s.Ephemeral.ConnInfo == nil {
  1899  			t.Fatalf("ConnInfo not initialized")
  1900  		}
  1901  
  1902  		result, _ := testApplyFn(info, s, d)
  1903  		result.Ephemeral.ConnInfo = map[string]string{
  1904  			"type": "ssh",
  1905  			"host": "127.0.0.1",
  1906  			"port": "22",
  1907  		}
  1908  		return result, nil
  1909  	}
  1910  	p.DiffFn = testDiffFn
  1911  
  1912  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  1913  		conn := rs.Ephemeral.ConnInfo
  1914  		if conn["type"] != "telnet" {
  1915  			t.Fatalf("Bad: %#v", conn)
  1916  		}
  1917  		if conn["host"] != "127.0.0.1" {
  1918  			t.Fatalf("Bad: %#v", conn)
  1919  		}
  1920  		if conn["port"] != "2222" {
  1921  			t.Fatalf("Bad: %#v", conn)
  1922  		}
  1923  		if conn["user"] != "superuser" {
  1924  			t.Fatalf("Bad: %#v", conn)
  1925  		}
  1926  		if conn["pass"] != "test" {
  1927  			t.Fatalf("Bad: %#v", conn)
  1928  		}
  1929  
  1930  		return nil
  1931  	}
  1932  
  1933  	ctx := testContext(t, &ContextOpts{
  1934  		Module: m,
  1935  		Providers: map[string]ResourceProviderFactory{
  1936  			"aws": testProviderFuncFixed(p),
  1937  		},
  1938  		Provisioners: map[string]ResourceProvisionerFactory{
  1939  			"shell": testProvisionerFuncFixed(pr),
  1940  		},
  1941  		Variables: map[string]string{
  1942  			"value": "1",
  1943  			"pass":  "test",
  1944  		},
  1945  	})
  1946  
  1947  	if _, err := ctx.Plan(nil); err != nil {
  1948  		t.Fatalf("err: %s", err)
  1949  	}
  1950  
  1951  	state, err := ctx.Apply()
  1952  	if err != nil {
  1953  		t.Fatalf("err: %s", err)
  1954  	}
  1955  
  1956  	actual := strings.TrimSpace(state.String())
  1957  	expected := strings.TrimSpace(testTerraformApplyProvisionerStr)
  1958  	if actual != expected {
  1959  		t.Fatalf("bad: \n%s", actual)
  1960  	}
  1961  
  1962  	// Verify apply was invoked
  1963  	if !pr.ApplyCalled {
  1964  		t.Fatalf("provisioner not invoked")
  1965  	}
  1966  }
  1967  
  1968  func TestContextApply_destroy(t *testing.T) {
  1969  	m := testModule(t, "apply-destroy")
  1970  	h := new(HookRecordApplyOrder)
  1971  	p := testProvider("aws")
  1972  	p.ApplyFn = testApplyFn
  1973  	p.DiffFn = testDiffFn
  1974  	ctx := testContext(t, &ContextOpts{
  1975  		Module: m,
  1976  		Hooks:  []Hook{h},
  1977  		Providers: map[string]ResourceProviderFactory{
  1978  			"aws": testProviderFuncFixed(p),
  1979  		},
  1980  	})
  1981  
  1982  	// First plan and apply a create operation
  1983  	if _, err := ctx.Plan(nil); err != nil {
  1984  		t.Fatalf("err: %s", err)
  1985  	}
  1986  
  1987  	if _, err := ctx.Apply(); err != nil {
  1988  		t.Fatalf("err: %s", err)
  1989  	}
  1990  
  1991  	// Next, plan and apply a destroy operation
  1992  	if _, err := ctx.Plan(&PlanOpts{Destroy: true}); err != nil {
  1993  		t.Fatalf("err: %s", err)
  1994  	}
  1995  
  1996  	h.Active = true
  1997  
  1998  	state, err := ctx.Apply()
  1999  	if err != nil {
  2000  		t.Fatalf("err: %s", err)
  2001  	}
  2002  
  2003  	// Test that things were destroyed
  2004  	actual := strings.TrimSpace(state.String())
  2005  	expected := strings.TrimSpace(testTerraformApplyDestroyStr)
  2006  	if actual != expected {
  2007  		t.Fatalf("bad: \n%s", actual)
  2008  	}
  2009  
  2010  	// Test that things were destroyed _in the right order_
  2011  	expected2 := []string{"aws_instance.bar", "aws_instance.foo"}
  2012  	actual2 := h.IDs
  2013  	if !reflect.DeepEqual(actual2, expected2) {
  2014  		t.Fatalf("bad: %#v", actual2)
  2015  	}
  2016  }
  2017  
  2018  func TestContextApply_destroyOutputs(t *testing.T) {
  2019  	m := testModule(t, "apply-destroy-outputs")
  2020  	h := new(HookRecordApplyOrder)
  2021  	p := testProvider("aws")
  2022  	p.ApplyFn = testApplyFn
  2023  	p.DiffFn = testDiffFn
  2024  	ctx := testContext(t, &ContextOpts{
  2025  		Module: m,
  2026  		Hooks:  []Hook{h},
  2027  		Providers: map[string]ResourceProviderFactory{
  2028  			"aws": testProviderFuncFixed(p),
  2029  		},
  2030  	})
  2031  
  2032  	// First plan and apply a create operation
  2033  	if _, err := ctx.Plan(nil); err != nil {
  2034  		t.Fatalf("err: %s", err)
  2035  	}
  2036  
  2037  	if _, err := ctx.Apply(); err != nil {
  2038  		t.Fatalf("err: %s", err)
  2039  	}
  2040  
  2041  	// Next, plan and apply a destroy operation
  2042  	if _, err := ctx.Plan(&PlanOpts{Destroy: true}); err != nil {
  2043  		t.Fatalf("err: %s", err)
  2044  	}
  2045  
  2046  	h.Active = true
  2047  
  2048  	state, err := ctx.Apply()
  2049  	if err != nil {
  2050  		t.Fatalf("err: %s", err)
  2051  	}
  2052  
  2053  	mod := state.RootModule()
  2054  	if len(mod.Resources) > 0 {
  2055  		t.Fatalf("bad: %#v", mod)
  2056  	}
  2057  }
  2058  
  2059  func TestContextApply_destroyOrphan(t *testing.T) {
  2060  	m := testModule(t, "apply-error")
  2061  	p := testProvider("aws")
  2062  	s := &State{
  2063  		Modules: []*ModuleState{
  2064  			&ModuleState{
  2065  				Path: rootModulePath,
  2066  				Resources: map[string]*ResourceState{
  2067  					"aws_instance.baz": &ResourceState{
  2068  						Type: "aws_instance",
  2069  						Primary: &InstanceState{
  2070  							ID: "bar",
  2071  						},
  2072  					},
  2073  				},
  2074  			},
  2075  		},
  2076  	}
  2077  	ctx := testContext(t, &ContextOpts{
  2078  		Module: m,
  2079  		Providers: map[string]ResourceProviderFactory{
  2080  			"aws": testProviderFuncFixed(p),
  2081  		},
  2082  		State: s,
  2083  	})
  2084  
  2085  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  2086  		if d.Destroy {
  2087  			return nil, nil
  2088  		}
  2089  
  2090  		result := s.MergeDiff(d)
  2091  		result.ID = "foo"
  2092  		return result, nil
  2093  	}
  2094  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  2095  		return &InstanceDiff{
  2096  			Attributes: map[string]*ResourceAttrDiff{
  2097  				"num": &ResourceAttrDiff{
  2098  					New: "bar",
  2099  				},
  2100  			},
  2101  		}, nil
  2102  	}
  2103  
  2104  	if _, err := ctx.Plan(nil); err != nil {
  2105  		t.Fatalf("err: %s", err)
  2106  	}
  2107  
  2108  	state, err := ctx.Apply()
  2109  	if err != nil {
  2110  		t.Fatalf("err: %s", err)
  2111  	}
  2112  
  2113  	mod := state.RootModule()
  2114  	if _, ok := mod.Resources["aws_instance.baz"]; ok {
  2115  		t.Fatalf("bad: %#v", mod.Resources)
  2116  	}
  2117  }
  2118  
  2119  func TestContextApply_destroyTaintedProvisioner(t *testing.T) {
  2120  	m := testModule(t, "apply-destroy-provisioner")
  2121  	p := testProvider("aws")
  2122  	pr := testProvisioner()
  2123  	p.ApplyFn = testApplyFn
  2124  	p.DiffFn = testDiffFn
  2125  
  2126  	called := false
  2127  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  2128  		called = true
  2129  		return nil
  2130  	}
  2131  
  2132  	s := &State{
  2133  		Modules: []*ModuleState{
  2134  			&ModuleState{
  2135  				Path: rootModulePath,
  2136  				Resources: map[string]*ResourceState{
  2137  					"aws_instance.foo": &ResourceState{
  2138  						Type: "aws_instance",
  2139  						Tainted: []*InstanceState{
  2140  							&InstanceState{
  2141  								ID: "bar",
  2142  								Attributes: map[string]string{
  2143  									"id": "bar",
  2144  								},
  2145  							},
  2146  						},
  2147  					},
  2148  				},
  2149  			},
  2150  		},
  2151  	}
  2152  
  2153  	ctx := testContext(t, &ContextOpts{
  2154  		Module: m,
  2155  		Providers: map[string]ResourceProviderFactory{
  2156  			"aws": testProviderFuncFixed(p),
  2157  		},
  2158  		Provisioners: map[string]ResourceProvisionerFactory{
  2159  			"shell": testProvisionerFuncFixed(pr),
  2160  		},
  2161  		State: s,
  2162  	})
  2163  
  2164  	if _, err := ctx.Plan(&PlanOpts{Destroy: true}); err != nil {
  2165  		t.Fatalf("err: %s", err)
  2166  	}
  2167  
  2168  	state, err := ctx.Apply()
  2169  	if err != nil {
  2170  		t.Fatalf("err: %s", err)
  2171  	}
  2172  
  2173  	if called {
  2174  		t.Fatal("provisioner should not be called")
  2175  	}
  2176  
  2177  	actual := strings.TrimSpace(state.String())
  2178  	expected := strings.TrimSpace("<no state>")
  2179  	if actual != expected {
  2180  		t.Fatalf("bad: \n%s", actual)
  2181  	}
  2182  }
  2183  
  2184  func TestContextApply_error(t *testing.T) {
  2185  	errored := false
  2186  
  2187  	m := testModule(t, "apply-error")
  2188  	p := testProvider("aws")
  2189  	ctx := testContext(t, &ContextOpts{
  2190  		Module: m,
  2191  		Providers: map[string]ResourceProviderFactory{
  2192  			"aws": testProviderFuncFixed(p),
  2193  		},
  2194  	})
  2195  
  2196  	p.ApplyFn = func(*InstanceInfo, *InstanceState, *InstanceDiff) (*InstanceState, error) {
  2197  		if errored {
  2198  			state := &InstanceState{
  2199  				ID: "bar",
  2200  			}
  2201  			return state, fmt.Errorf("error")
  2202  		}
  2203  		errored = true
  2204  
  2205  		return &InstanceState{
  2206  			ID: "foo",
  2207  			Attributes: map[string]string{
  2208  				"num": "2",
  2209  			},
  2210  		}, nil
  2211  	}
  2212  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  2213  		return &InstanceDiff{
  2214  			Attributes: map[string]*ResourceAttrDiff{
  2215  				"num": &ResourceAttrDiff{
  2216  					New: "bar",
  2217  				},
  2218  			},
  2219  		}, nil
  2220  	}
  2221  
  2222  	if _, err := ctx.Plan(nil); err != nil {
  2223  		t.Fatalf("err: %s", err)
  2224  	}
  2225  
  2226  	state, err := ctx.Apply()
  2227  	if err == nil {
  2228  		t.Fatal("should have error")
  2229  	}
  2230  
  2231  	actual := strings.TrimSpace(state.String())
  2232  	expected := strings.TrimSpace(testTerraformApplyErrorStr)
  2233  	if actual != expected {
  2234  		t.Fatalf("bad: \n%s", actual)
  2235  	}
  2236  }
  2237  
  2238  func TestContextApply_errorPartial(t *testing.T) {
  2239  	errored := false
  2240  
  2241  	m := testModule(t, "apply-error")
  2242  	p := testProvider("aws")
  2243  	s := &State{
  2244  		Modules: []*ModuleState{
  2245  			&ModuleState{
  2246  				Path: rootModulePath,
  2247  				Resources: map[string]*ResourceState{
  2248  					"aws_instance.bar": &ResourceState{
  2249  						Type: "aws_instance",
  2250  						Primary: &InstanceState{
  2251  							ID: "bar",
  2252  						},
  2253  					},
  2254  				},
  2255  			},
  2256  		},
  2257  	}
  2258  	ctx := testContext(t, &ContextOpts{
  2259  		Module: m,
  2260  		Providers: map[string]ResourceProviderFactory{
  2261  			"aws": testProviderFuncFixed(p),
  2262  		},
  2263  		State: s,
  2264  	})
  2265  
  2266  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  2267  		if errored {
  2268  			return s, fmt.Errorf("error")
  2269  		}
  2270  		errored = true
  2271  
  2272  		return &InstanceState{
  2273  			ID: "foo",
  2274  			Attributes: map[string]string{
  2275  				"num": "2",
  2276  			},
  2277  		}, nil
  2278  	}
  2279  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  2280  		return &InstanceDiff{
  2281  			Attributes: map[string]*ResourceAttrDiff{
  2282  				"num": &ResourceAttrDiff{
  2283  					New: "bar",
  2284  				},
  2285  			},
  2286  		}, nil
  2287  	}
  2288  
  2289  	if _, err := ctx.Plan(nil); err != nil {
  2290  		t.Fatalf("err: %s", err)
  2291  	}
  2292  
  2293  	state, err := ctx.Apply()
  2294  	if err == nil {
  2295  		t.Fatal("should have error")
  2296  	}
  2297  
  2298  	mod := state.RootModule()
  2299  	if len(mod.Resources) != 2 {
  2300  		t.Fatalf("bad: %#v", mod.Resources)
  2301  	}
  2302  
  2303  	actual := strings.TrimSpace(state.String())
  2304  	expected := strings.TrimSpace(testTerraformApplyErrorPartialStr)
  2305  	if actual != expected {
  2306  		t.Fatalf("bad: \n%s", actual)
  2307  	}
  2308  }
  2309  
  2310  func TestContextApply_hook(t *testing.T) {
  2311  	m := testModule(t, "apply-good")
  2312  	h := new(MockHook)
  2313  	p := testProvider("aws")
  2314  	p.ApplyFn = testApplyFn
  2315  	p.DiffFn = testDiffFn
  2316  	ctx := testContext(t, &ContextOpts{
  2317  		Module: m,
  2318  		Hooks:  []Hook{h},
  2319  		Providers: map[string]ResourceProviderFactory{
  2320  			"aws": testProviderFuncFixed(p),
  2321  		},
  2322  	})
  2323  
  2324  	if _, err := ctx.Plan(nil); err != nil {
  2325  		t.Fatalf("err: %s", err)
  2326  	}
  2327  
  2328  	if _, err := ctx.Apply(); err != nil {
  2329  		t.Fatalf("err: %s", err)
  2330  	}
  2331  
  2332  	if !h.PreApplyCalled {
  2333  		t.Fatal("should be called")
  2334  	}
  2335  	if !h.PostApplyCalled {
  2336  		t.Fatal("should be called")
  2337  	}
  2338  }
  2339  
  2340  func TestContextApply_idAttr(t *testing.T) {
  2341  	m := testModule(t, "apply-idattr")
  2342  	p := testProvider("aws")
  2343  	ctx := testContext(t, &ContextOpts{
  2344  		Module: m,
  2345  		Providers: map[string]ResourceProviderFactory{
  2346  			"aws": testProviderFuncFixed(p),
  2347  		},
  2348  	})
  2349  
  2350  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  2351  		result := s.MergeDiff(d)
  2352  		result.ID = "foo"
  2353  		result.Attributes = map[string]string{
  2354  			"id": "bar",
  2355  		}
  2356  
  2357  		return result, nil
  2358  	}
  2359  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  2360  		return &InstanceDiff{
  2361  			Attributes: map[string]*ResourceAttrDiff{
  2362  				"num": &ResourceAttrDiff{
  2363  					New: "bar",
  2364  				},
  2365  			},
  2366  		}, nil
  2367  	}
  2368  
  2369  	if _, err := ctx.Plan(nil); err != nil {
  2370  		t.Fatalf("err: %s", err)
  2371  	}
  2372  
  2373  	state, err := ctx.Apply()
  2374  	if err != nil {
  2375  		t.Fatalf("err: %s", err)
  2376  	}
  2377  
  2378  	mod := state.RootModule()
  2379  	rs, ok := mod.Resources["aws_instance.foo"]
  2380  	if !ok {
  2381  		t.Fatal("not in state")
  2382  	}
  2383  	if rs.Primary.ID != "foo" {
  2384  		t.Fatalf("bad: %#v", rs.Primary.ID)
  2385  	}
  2386  	if rs.Primary.Attributes["id"] != "foo" {
  2387  		t.Fatalf("bad: %#v", rs.Primary.Attributes)
  2388  	}
  2389  }
  2390  
  2391  func TestContextApply_output(t *testing.T) {
  2392  	m := testModule(t, "apply-output")
  2393  	p := testProvider("aws")
  2394  	p.ApplyFn = testApplyFn
  2395  	p.DiffFn = testDiffFn
  2396  	ctx := testContext(t, &ContextOpts{
  2397  		Module: m,
  2398  		Providers: map[string]ResourceProviderFactory{
  2399  			"aws": testProviderFuncFixed(p),
  2400  		},
  2401  	})
  2402  
  2403  	if _, err := ctx.Plan(nil); err != nil {
  2404  		t.Fatalf("err: %s", err)
  2405  	}
  2406  
  2407  	state, err := ctx.Apply()
  2408  	if err != nil {
  2409  		t.Fatalf("err: %s", err)
  2410  	}
  2411  
  2412  	actual := strings.TrimSpace(state.String())
  2413  	expected := strings.TrimSpace(testTerraformApplyOutputStr)
  2414  	if actual != expected {
  2415  		t.Fatalf("bad: \n%s", actual)
  2416  	}
  2417  }
  2418  
  2419  func TestContextApply_outputMulti(t *testing.T) {
  2420  	m := testModule(t, "apply-output-multi")
  2421  	p := testProvider("aws")
  2422  	p.ApplyFn = testApplyFn
  2423  	p.DiffFn = testDiffFn
  2424  	ctx := testContext(t, &ContextOpts{
  2425  		Module: m,
  2426  		Providers: map[string]ResourceProviderFactory{
  2427  			"aws": testProviderFuncFixed(p),
  2428  		},
  2429  	})
  2430  
  2431  	if _, err := ctx.Plan(nil); err != nil {
  2432  		t.Fatalf("err: %s", err)
  2433  	}
  2434  
  2435  	state, err := ctx.Apply()
  2436  	if err != nil {
  2437  		t.Fatalf("err: %s", err)
  2438  	}
  2439  
  2440  	actual := strings.TrimSpace(state.String())
  2441  	expected := strings.TrimSpace(testTerraformApplyOutputMultiStr)
  2442  	if actual != expected {
  2443  		t.Fatalf("bad: \n%s", actual)
  2444  	}
  2445  }
  2446  
  2447  func TestContextApply_outputMultiIndex(t *testing.T) {
  2448  	m := testModule(t, "apply-output-multi-index")
  2449  	p := testProvider("aws")
  2450  	p.ApplyFn = testApplyFn
  2451  	p.DiffFn = testDiffFn
  2452  	ctx := testContext(t, &ContextOpts{
  2453  		Module: m,
  2454  		Providers: map[string]ResourceProviderFactory{
  2455  			"aws": testProviderFuncFixed(p),
  2456  		},
  2457  	})
  2458  
  2459  	if _, err := ctx.Plan(nil); err != nil {
  2460  		t.Fatalf("err: %s", err)
  2461  	}
  2462  
  2463  	state, err := ctx.Apply()
  2464  	if err != nil {
  2465  		t.Fatalf("err: %s", err)
  2466  	}
  2467  
  2468  	actual := strings.TrimSpace(state.String())
  2469  	expected := strings.TrimSpace(testTerraformApplyOutputMultiIndexStr)
  2470  	if actual != expected {
  2471  		t.Fatalf("bad: \n%s", actual)
  2472  	}
  2473  }
  2474  
  2475  func TestContextApply_taint(t *testing.T) {
  2476  	m := testModule(t, "apply-taint")
  2477  	p := testProvider("aws")
  2478  	p.ApplyFn = testApplyFn
  2479  	p.DiffFn = testDiffFn
  2480  	s := &State{
  2481  		Modules: []*ModuleState{
  2482  			&ModuleState{
  2483  				Path: rootModulePath,
  2484  				Resources: map[string]*ResourceState{
  2485  					"aws_instance.bar": &ResourceState{
  2486  						Type: "aws_instance",
  2487  						Tainted: []*InstanceState{
  2488  							&InstanceState{
  2489  								ID: "baz",
  2490  								Attributes: map[string]string{
  2491  									"num":  "2",
  2492  									"type": "aws_instance",
  2493  								},
  2494  							},
  2495  						},
  2496  					},
  2497  				},
  2498  			},
  2499  		},
  2500  	}
  2501  	ctx := testContext(t, &ContextOpts{
  2502  		Module: m,
  2503  		Providers: map[string]ResourceProviderFactory{
  2504  			"aws": testProviderFuncFixed(p),
  2505  		},
  2506  		State: s,
  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(testTerraformApplyTaintStr)
  2520  	if actual != expected {
  2521  		t.Fatalf("bad:\n%s", actual)
  2522  	}
  2523  }
  2524  
  2525  func TestContextApply_unknownAttribute(t *testing.T) {
  2526  	m := testModule(t, "apply-unknown")
  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.Fatal("should error")
  2544  	}
  2545  
  2546  	actual := strings.TrimSpace(state.String())
  2547  	expected := strings.TrimSpace(testTerraformApplyUnknownAttrStr)
  2548  	if actual != expected {
  2549  		t.Fatalf("bad: \n%s", actual)
  2550  	}
  2551  }
  2552  
  2553  func TestContextApply_vars(t *testing.T) {
  2554  	m := testModule(t, "apply-vars")
  2555  	p := testProvider("aws")
  2556  	p.ApplyFn = testApplyFn
  2557  	p.DiffFn = testDiffFn
  2558  	ctx := testContext(t, &ContextOpts{
  2559  		Module: m,
  2560  		Providers: map[string]ResourceProviderFactory{
  2561  			"aws": testProviderFuncFixed(p),
  2562  		},
  2563  		Variables: map[string]string{
  2564  			"foo":            "us-west-2",
  2565  			"amis.us-east-1": "override",
  2566  		},
  2567  	})
  2568  
  2569  	w, e := ctx.Validate()
  2570  	if len(w) > 0 {
  2571  		t.Fatalf("bad: %#v", w)
  2572  	}
  2573  	if len(e) > 0 {
  2574  		t.Fatalf("bad: %s", e)
  2575  	}
  2576  
  2577  	if _, err := ctx.Plan(nil); err != nil {
  2578  		t.Fatalf("err: %s", err)
  2579  	}
  2580  
  2581  	state, err := ctx.Apply()
  2582  	if err != nil {
  2583  		t.Fatalf("err: %s", err)
  2584  	}
  2585  
  2586  	actual := strings.TrimSpace(state.String())
  2587  	expected := strings.TrimSpace(testTerraformApplyVarsStr)
  2588  	if actual != expected {
  2589  		t.Fatalf("bad: \n%s", actual)
  2590  	}
  2591  }
  2592  
  2593  func TestContextApply_createBefore_depends(t *testing.T) {
  2594  	m := testModule(t, "apply-depends-create-before")
  2595  	h := new(HookRecordApplyOrder)
  2596  	p := testProvider("aws")
  2597  	p.ApplyFn = testApplyFn
  2598  	p.DiffFn = testDiffFn
  2599  	state := &State{
  2600  		Modules: []*ModuleState{
  2601  			&ModuleState{
  2602  				Path: rootModulePath,
  2603  				Resources: map[string]*ResourceState{
  2604  					"aws_instance.web": &ResourceState{
  2605  						Type: "aws_instance",
  2606  						Primary: &InstanceState{
  2607  							ID: "bar",
  2608  							Attributes: map[string]string{
  2609  								"require_new": "ami-old",
  2610  							},
  2611  						},
  2612  					},
  2613  					"aws_instance.lb": &ResourceState{
  2614  						Type: "aws_instance",
  2615  						Primary: &InstanceState{
  2616  							ID: "baz",
  2617  							Attributes: map[string]string{
  2618  								"instance": "bar",
  2619  							},
  2620  						},
  2621  					},
  2622  				},
  2623  			},
  2624  		},
  2625  	}
  2626  	ctx := testContext(t, &ContextOpts{
  2627  		Module: m,
  2628  		Hooks:  []Hook{h},
  2629  		Providers: map[string]ResourceProviderFactory{
  2630  			"aws": testProviderFuncFixed(p),
  2631  		},
  2632  		State: state,
  2633  	})
  2634  
  2635  	if _, err := ctx.Plan(nil); err != nil {
  2636  		t.Fatalf("err: %s", err)
  2637  	}
  2638  
  2639  	h.Active = true
  2640  	state, err := ctx.Apply()
  2641  	if err != nil {
  2642  		t.Fatalf("err: %s", err)
  2643  	}
  2644  
  2645  	mod := state.RootModule()
  2646  	if len(mod.Resources) < 2 {
  2647  		t.Fatalf("bad: %#v", mod.Resources)
  2648  	}
  2649  
  2650  	actual := strings.TrimSpace(state.String())
  2651  	expected := strings.TrimSpace(testTerraformApplyDependsCreateBeforeStr)
  2652  	if actual != expected {
  2653  		t.Fatalf("bad: \n%s\n%s", actual, expected)
  2654  	}
  2655  
  2656  	// Test that things were managed _in the right order_
  2657  	order := h.States
  2658  	diffs := h.Diffs
  2659  	if order[0].ID != "bar" || diffs[0].Destroy {
  2660  		t.Fatalf("should create new instance first: %#v", order)
  2661  	}
  2662  
  2663  	if order[1].ID != "baz" {
  2664  		t.Fatalf("update must happen after create: %#v", order)
  2665  	}
  2666  
  2667  	if order[2].ID != "bar" || !diffs[2].Destroy {
  2668  		t.Fatalf("destroy must happen after update: %#v", order)
  2669  	}
  2670  }
  2671  
  2672  func TestContextPlan(t *testing.T) {
  2673  	m := testModule(t, "plan-good")
  2674  	p := testProvider("aws")
  2675  	p.DiffFn = testDiffFn
  2676  	ctx := testContext(t, &ContextOpts{
  2677  		Module: m,
  2678  		Providers: map[string]ResourceProviderFactory{
  2679  			"aws": testProviderFuncFixed(p),
  2680  		},
  2681  	})
  2682  
  2683  	plan, err := ctx.Plan(nil)
  2684  	if err != nil {
  2685  		t.Fatalf("err: %s", err)
  2686  	}
  2687  
  2688  	if len(plan.Diff.RootModule().Resources) < 2 {
  2689  		t.Fatalf("bad: %#v", plan.Diff.RootModule().Resources)
  2690  	}
  2691  
  2692  	actual := strings.TrimSpace(plan.String())
  2693  	expected := strings.TrimSpace(testTerraformPlanStr)
  2694  	if actual != expected {
  2695  		t.Fatalf("bad:\n%s", actual)
  2696  	}
  2697  }
  2698  
  2699  func TestContextPlan_minimal(t *testing.T) {
  2700  	m := testModule(t, "plan-empty")
  2701  	p := testProvider("aws")
  2702  	p.DiffFn = testDiffFn
  2703  	ctx := testContext(t, &ContextOpts{
  2704  		Module: m,
  2705  		Providers: map[string]ResourceProviderFactory{
  2706  			"aws": testProviderFuncFixed(p),
  2707  		},
  2708  	})
  2709  
  2710  	plan, err := ctx.Plan(nil)
  2711  	if err != nil {
  2712  		t.Fatalf("err: %s", err)
  2713  	}
  2714  
  2715  	actual := strings.TrimSpace(plan.String())
  2716  	expected := strings.TrimSpace(testTerraformPlanEmptyStr)
  2717  	if actual != expected {
  2718  		t.Fatalf("bad:\n%s", actual)
  2719  	}
  2720  }
  2721  
  2722  func TestContextPlan_modules(t *testing.T) {
  2723  	m := testModule(t, "plan-modules")
  2724  	p := testProvider("aws")
  2725  	p.DiffFn = testDiffFn
  2726  	ctx := testContext(t, &ContextOpts{
  2727  		Module: m,
  2728  		Providers: map[string]ResourceProviderFactory{
  2729  			"aws": testProviderFuncFixed(p),
  2730  		},
  2731  	})
  2732  
  2733  	plan, err := ctx.Plan(nil)
  2734  	if err != nil {
  2735  		t.Fatalf("err: %s", err)
  2736  	}
  2737  
  2738  	actual := strings.TrimSpace(plan.String())
  2739  	expected := strings.TrimSpace(testTerraformPlanModulesStr)
  2740  	if actual != expected {
  2741  		t.Fatalf("bad:\n%s", actual)
  2742  	}
  2743  }
  2744  
  2745  func TestContextPlan_moduleInput(t *testing.T) {
  2746  	m := testModule(t, "plan-module-input")
  2747  	p := testProvider("aws")
  2748  	p.DiffFn = testDiffFn
  2749  	ctx := testContext(t, &ContextOpts{
  2750  		Module: m,
  2751  		Providers: map[string]ResourceProviderFactory{
  2752  			"aws": testProviderFuncFixed(p),
  2753  		},
  2754  	})
  2755  
  2756  	plan, err := ctx.Plan(nil)
  2757  	if err != nil {
  2758  		t.Fatalf("err: %s", err)
  2759  	}
  2760  
  2761  	actual := strings.TrimSpace(plan.String())
  2762  	expected := strings.TrimSpace(testTerraformPlanModuleInputStr)
  2763  	if actual != expected {
  2764  		t.Fatalf("bad:\n%s", actual)
  2765  	}
  2766  }
  2767  
  2768  func TestContextPlan_moduleInputComputed(t *testing.T) {
  2769  	m := testModule(t, "plan-module-input-computed")
  2770  	p := testProvider("aws")
  2771  	p.DiffFn = testDiffFn
  2772  	ctx := testContext(t, &ContextOpts{
  2773  		Module: m,
  2774  		Providers: map[string]ResourceProviderFactory{
  2775  			"aws": testProviderFuncFixed(p),
  2776  		},
  2777  	})
  2778  
  2779  	plan, err := ctx.Plan(nil)
  2780  	if err != nil {
  2781  		t.Fatalf("err: %s", err)
  2782  	}
  2783  
  2784  	actual := strings.TrimSpace(plan.String())
  2785  	expected := strings.TrimSpace(testTerraformPlanModuleInputComputedStr)
  2786  	if actual != expected {
  2787  		t.Fatalf("bad:\n%s", actual)
  2788  	}
  2789  }
  2790  
  2791  func TestContextPlan_moduleInputFromVar(t *testing.T) {
  2792  	m := testModule(t, "plan-module-input-var")
  2793  	p := testProvider("aws")
  2794  	p.DiffFn = testDiffFn
  2795  	ctx := testContext(t, &ContextOpts{
  2796  		Module: m,
  2797  		Providers: map[string]ResourceProviderFactory{
  2798  			"aws": testProviderFuncFixed(p),
  2799  		},
  2800  		Variables: map[string]string{
  2801  			"foo": "52",
  2802  		},
  2803  	})
  2804  
  2805  	plan, err := ctx.Plan(nil)
  2806  	if err != nil {
  2807  		t.Fatalf("err: %s", err)
  2808  	}
  2809  
  2810  	actual := strings.TrimSpace(plan.String())
  2811  	expected := strings.TrimSpace(testTerraformPlanModuleInputVarStr)
  2812  	if actual != expected {
  2813  		t.Fatalf("bad:\n%s", actual)
  2814  	}
  2815  }
  2816  func TestContextPlan_moduleOrphans(t *testing.T) {
  2817  	m := testModule(t, "plan-modules-remove")
  2818  	p := testProvider("aws")
  2819  	p.DiffFn = testDiffFn
  2820  	s := &State{
  2821  		Modules: []*ModuleState{
  2822  			&ModuleState{
  2823  				Path: []string{"root", "child"},
  2824  				Resources: map[string]*ResourceState{
  2825  					"aws_instance.foo": &ResourceState{
  2826  						Type: "aws_instance",
  2827  						Primary: &InstanceState{
  2828  							ID: "baz",
  2829  						},
  2830  					},
  2831  				},
  2832  			},
  2833  		},
  2834  	}
  2835  	ctx := testContext(t, &ContextOpts{
  2836  		Module: m,
  2837  		Providers: map[string]ResourceProviderFactory{
  2838  			"aws": testProviderFuncFixed(p),
  2839  		},
  2840  		State: s,
  2841  	})
  2842  
  2843  	plan, err := ctx.Plan(nil)
  2844  	if err != nil {
  2845  		t.Fatalf("err: %s", err)
  2846  	}
  2847  
  2848  	actual := strings.TrimSpace(plan.String())
  2849  	expected := strings.TrimSpace(testTerraformPlanModuleOrphansStr)
  2850  	if actual != expected {
  2851  		t.Fatalf("bad:\n%s", actual)
  2852  	}
  2853  }
  2854  
  2855  func TestContextPlan_moduleProviderInherit(t *testing.T) {
  2856  	var l sync.Mutex
  2857  	var calls []string
  2858  
  2859  	m := testModule(t, "plan-module-provider-inherit")
  2860  	ctx := testContext(t, &ContextOpts{
  2861  		Module: m,
  2862  		Providers: map[string]ResourceProviderFactory{
  2863  			"aws": func() (ResourceProvider, error) {
  2864  				l.Lock()
  2865  				defer l.Unlock()
  2866  
  2867  				p := testProvider("aws")
  2868  				p.ConfigureFn = func(c *ResourceConfig) error {
  2869  					if v, ok := c.Get("from"); !ok || v.(string) != "root" {
  2870  						return fmt.Errorf("bad")
  2871  					}
  2872  
  2873  					return nil
  2874  				}
  2875  				p.DiffFn = func(
  2876  					info *InstanceInfo,
  2877  					state *InstanceState,
  2878  					c *ResourceConfig) (*InstanceDiff, error) {
  2879  					v, _ := c.Get("from")
  2880  					calls = append(calls, v.(string))
  2881  					return testDiffFn(info, state, c)
  2882  				}
  2883  				return p, nil
  2884  			},
  2885  		},
  2886  	})
  2887  
  2888  	_, err := ctx.Plan(nil)
  2889  	if err != nil {
  2890  		t.Fatalf("err: %s", err)
  2891  	}
  2892  
  2893  	actual := calls
  2894  	sort.Strings(actual)
  2895  	expected := []string{"child", "root"}
  2896  	if !reflect.DeepEqual(actual, expected) {
  2897  		t.Fatalf("bad: %#v", actual)
  2898  	}
  2899  }
  2900  
  2901  func TestContextPlan_moduleProviderDefaults(t *testing.T) {
  2902  	var l sync.Mutex
  2903  	var calls []string
  2904  	toCount := 0
  2905  
  2906  	m := testModule(t, "plan-module-provider-defaults")
  2907  	ctx := testContext(t, &ContextOpts{
  2908  		Module: m,
  2909  		Providers: map[string]ResourceProviderFactory{
  2910  			"aws": func() (ResourceProvider, error) {
  2911  				l.Lock()
  2912  				defer l.Unlock()
  2913  
  2914  				p := testProvider("aws")
  2915  				p.ConfigureFn = func(c *ResourceConfig) error {
  2916  					if v, ok := c.Get("from"); !ok || v.(string) != "root" {
  2917  						return fmt.Errorf("bad")
  2918  					}
  2919  					if v, ok := c.Get("to"); ok && v.(string) == "child" {
  2920  						toCount++
  2921  					}
  2922  
  2923  					return nil
  2924  				}
  2925  				p.DiffFn = func(
  2926  					info *InstanceInfo,
  2927  					state *InstanceState,
  2928  					c *ResourceConfig) (*InstanceDiff, error) {
  2929  					v, _ := c.Get("from")
  2930  					calls = append(calls, v.(string))
  2931  					return testDiffFn(info, state, c)
  2932  				}
  2933  				return p, nil
  2934  			},
  2935  		},
  2936  	})
  2937  
  2938  	_, err := ctx.Plan(nil)
  2939  	if err != nil {
  2940  		t.Fatalf("err: %s", err)
  2941  	}
  2942  
  2943  	if toCount != 1 {
  2944  		t.Fatal("provider in child didn't set proper config")
  2945  	}
  2946  
  2947  	actual := calls
  2948  	sort.Strings(actual)
  2949  	expected := []string{"child", "root"}
  2950  	if !reflect.DeepEqual(actual, expected) {
  2951  		t.Fatalf("bad: %#v", actual)
  2952  	}
  2953  }
  2954  
  2955  func TestContextPlan_moduleProviderDefaultsVar(t *testing.T) {
  2956  	var l sync.Mutex
  2957  	var calls []string
  2958  
  2959  	m := testModule(t, "plan-module-provider-defaults-var")
  2960  	ctx := testContext(t, &ContextOpts{
  2961  		Module: m,
  2962  		Providers: map[string]ResourceProviderFactory{
  2963  			"aws": func() (ResourceProvider, error) {
  2964  				l.Lock()
  2965  				defer l.Unlock()
  2966  
  2967  				p := testProvider("aws")
  2968  				p.ConfigureFn = func(c *ResourceConfig) error {
  2969  					var buf bytes.Buffer
  2970  					if v, ok := c.Get("from"); ok {
  2971  						buf.WriteString(v.(string) + "\n")
  2972  					}
  2973  					if v, ok := c.Get("to"); ok {
  2974  						buf.WriteString(v.(string) + "\n")
  2975  					}
  2976  
  2977  					calls = append(calls, buf.String())
  2978  					return nil
  2979  				}
  2980  				p.DiffFn = testDiffFn
  2981  				return p, nil
  2982  			},
  2983  		},
  2984  		Variables: map[string]string{
  2985  			"foo": "root",
  2986  		},
  2987  	})
  2988  
  2989  	_, err := ctx.Plan(nil)
  2990  	if err != nil {
  2991  		t.Fatalf("err: %s", err)
  2992  	}
  2993  
  2994  	expected := []string{
  2995  		"root\n",
  2996  		"root\nchild\n",
  2997  	}
  2998  	if !reflect.DeepEqual(calls, expected) {
  2999  		t.Fatalf("BAD: %#v", calls)
  3000  	}
  3001  }
  3002  
  3003  func TestContextPlan_moduleVar(t *testing.T) {
  3004  	m := testModule(t, "plan-module-var")
  3005  	p := testProvider("aws")
  3006  	p.DiffFn = testDiffFn
  3007  	ctx := testContext(t, &ContextOpts{
  3008  		Module: m,
  3009  		Providers: map[string]ResourceProviderFactory{
  3010  			"aws": testProviderFuncFixed(p),
  3011  		},
  3012  	})
  3013  
  3014  	plan, err := ctx.Plan(nil)
  3015  	if err != nil {
  3016  		t.Fatalf("err: %s", err)
  3017  	}
  3018  
  3019  	actual := strings.TrimSpace(plan.String())
  3020  	expected := strings.TrimSpace(testTerraformPlanModuleVarStr)
  3021  	if actual != expected {
  3022  		t.Fatalf("bad:\n%s", actual)
  3023  	}
  3024  }
  3025  
  3026  func TestContextPlan_moduleVarComputed(t *testing.T) {
  3027  	m := testModule(t, "plan-module-var-computed")
  3028  	p := testProvider("aws")
  3029  	p.DiffFn = testDiffFn
  3030  	ctx := testContext(t, &ContextOpts{
  3031  		Module: m,
  3032  		Providers: map[string]ResourceProviderFactory{
  3033  			"aws": testProviderFuncFixed(p),
  3034  		},
  3035  	})
  3036  
  3037  	plan, err := ctx.Plan(nil)
  3038  	if err != nil {
  3039  		t.Fatalf("err: %s", err)
  3040  	}
  3041  
  3042  	actual := strings.TrimSpace(plan.String())
  3043  	expected := strings.TrimSpace(testTerraformPlanModuleVarComputedStr)
  3044  	if actual != expected {
  3045  		t.Fatalf("bad:\n%s", actual)
  3046  	}
  3047  }
  3048  
  3049  func TestContextPlan_nil(t *testing.T) {
  3050  	m := testModule(t, "plan-nil")
  3051  	p := testProvider("aws")
  3052  	p.DiffFn = testDiffFn
  3053  	ctx := testContext(t, &ContextOpts{
  3054  		Module: m,
  3055  		Providers: map[string]ResourceProviderFactory{
  3056  			"aws": testProviderFuncFixed(p),
  3057  		},
  3058  		State: &State{
  3059  			Modules: []*ModuleState{
  3060  				&ModuleState{
  3061  					Path: rootModulePath,
  3062  					Resources: map[string]*ResourceState{
  3063  						"aws_instance.foo": &ResourceState{
  3064  							Type: "aws_instance",
  3065  							Primary: &InstanceState{
  3066  								ID: "bar",
  3067  							},
  3068  						},
  3069  					},
  3070  				},
  3071  			},
  3072  		},
  3073  	})
  3074  
  3075  	plan, err := ctx.Plan(nil)
  3076  	if err != nil {
  3077  		t.Fatalf("err: %s", err)
  3078  	}
  3079  	if len(plan.Diff.RootModule().Resources) != 0 {
  3080  		t.Fatalf("bad: %#v", plan.Diff.RootModule().Resources)
  3081  	}
  3082  }
  3083  
  3084  func TestContextPlan_computed(t *testing.T) {
  3085  	m := testModule(t, "plan-computed")
  3086  	p := testProvider("aws")
  3087  	p.DiffFn = testDiffFn
  3088  	ctx := testContext(t, &ContextOpts{
  3089  		Module: m,
  3090  		Providers: map[string]ResourceProviderFactory{
  3091  			"aws": testProviderFuncFixed(p),
  3092  		},
  3093  	})
  3094  
  3095  	plan, err := ctx.Plan(nil)
  3096  	if err != nil {
  3097  		t.Fatalf("err: %s", err)
  3098  	}
  3099  
  3100  	actual := strings.TrimSpace(plan.String())
  3101  	expected := strings.TrimSpace(testTerraformPlanComputedStr)
  3102  	if actual != expected {
  3103  		t.Fatalf("bad:\n%s", actual)
  3104  	}
  3105  }
  3106  
  3107  func TestContextPlan_computedList(t *testing.T) {
  3108  	m := testModule(t, "plan-computed-list")
  3109  	p := testProvider("aws")
  3110  	p.DiffFn = testDiffFn
  3111  	ctx := testContext(t, &ContextOpts{
  3112  		Module: m,
  3113  		Providers: map[string]ResourceProviderFactory{
  3114  			"aws": testProviderFuncFixed(p),
  3115  		},
  3116  	})
  3117  
  3118  	plan, err := ctx.Plan(nil)
  3119  	if err != nil {
  3120  		t.Fatalf("err: %s", err)
  3121  	}
  3122  
  3123  	actual := strings.TrimSpace(plan.String())
  3124  	expected := strings.TrimSpace(testTerraformPlanComputedListStr)
  3125  	if actual != expected {
  3126  		t.Fatalf("bad:\n%s", actual)
  3127  	}
  3128  }
  3129  
  3130  func TestContextPlan_count(t *testing.T) {
  3131  	m := testModule(t, "plan-count")
  3132  	p := testProvider("aws")
  3133  	p.DiffFn = testDiffFn
  3134  	ctx := testContext(t, &ContextOpts{
  3135  		Module: m,
  3136  		Providers: map[string]ResourceProviderFactory{
  3137  			"aws": testProviderFuncFixed(p),
  3138  		},
  3139  	})
  3140  
  3141  	plan, err := ctx.Plan(nil)
  3142  	if err != nil {
  3143  		t.Fatalf("err: %s", err)
  3144  	}
  3145  
  3146  	if len(plan.Diff.RootModule().Resources) < 6 {
  3147  		t.Fatalf("bad: %#v", plan.Diff.RootModule().Resources)
  3148  	}
  3149  
  3150  	actual := strings.TrimSpace(plan.String())
  3151  	expected := strings.TrimSpace(testTerraformPlanCountStr)
  3152  	if actual != expected {
  3153  		t.Fatalf("bad:\n%s", actual)
  3154  	}
  3155  }
  3156  
  3157  func TestContextPlan_countComputed(t *testing.T) {
  3158  	m := testModule(t, "plan-count-computed")
  3159  	p := testProvider("aws")
  3160  	p.DiffFn = testDiffFn
  3161  	ctx := testContext(t, &ContextOpts{
  3162  		Module: m,
  3163  		Providers: map[string]ResourceProviderFactory{
  3164  			"aws": testProviderFuncFixed(p),
  3165  		},
  3166  	})
  3167  
  3168  	_, err := ctx.Plan(nil)
  3169  	if err == nil {
  3170  		t.Fatal("should error")
  3171  	}
  3172  }
  3173  
  3174  func TestContextPlan_countIndex(t *testing.T) {
  3175  	m := testModule(t, "plan-count-index")
  3176  	p := testProvider("aws")
  3177  	p.DiffFn = testDiffFn
  3178  	ctx := testContext(t, &ContextOpts{
  3179  		Module: m,
  3180  		Providers: map[string]ResourceProviderFactory{
  3181  			"aws": testProviderFuncFixed(p),
  3182  		},
  3183  	})
  3184  
  3185  	plan, err := ctx.Plan(nil)
  3186  	if err != nil {
  3187  		t.Fatalf("err: %s", err)
  3188  	}
  3189  
  3190  	actual := strings.TrimSpace(plan.String())
  3191  	expected := strings.TrimSpace(testTerraformPlanCountIndexStr)
  3192  	if actual != expected {
  3193  		t.Fatalf("bad:\n%s", actual)
  3194  	}
  3195  }
  3196  
  3197  func TestContextPlan_countIndexZero(t *testing.T) {
  3198  	m := testModule(t, "plan-count-index-zero")
  3199  	p := testProvider("aws")
  3200  	p.DiffFn = testDiffFn
  3201  	ctx := testContext(t, &ContextOpts{
  3202  		Module: m,
  3203  		Providers: map[string]ResourceProviderFactory{
  3204  			"aws": testProviderFuncFixed(p),
  3205  		},
  3206  	})
  3207  
  3208  	plan, err := ctx.Plan(nil)
  3209  	if err != nil {
  3210  		t.Fatalf("err: %s", err)
  3211  	}
  3212  
  3213  	actual := strings.TrimSpace(plan.String())
  3214  	expected := strings.TrimSpace(testTerraformPlanCountIndexZeroStr)
  3215  	if actual != expected {
  3216  		t.Fatalf("bad:\n%s", actual)
  3217  	}
  3218  }
  3219  
  3220  func TestContextPlan_countVar(t *testing.T) {
  3221  	m := testModule(t, "plan-count-var")
  3222  	p := testProvider("aws")
  3223  	p.DiffFn = testDiffFn
  3224  	ctx := testContext(t, &ContextOpts{
  3225  		Module: m,
  3226  		Providers: map[string]ResourceProviderFactory{
  3227  			"aws": testProviderFuncFixed(p),
  3228  		},
  3229  		Variables: map[string]string{
  3230  			"count": "3",
  3231  		},
  3232  	})
  3233  
  3234  	plan, err := ctx.Plan(nil)
  3235  	if err != nil {
  3236  		t.Fatalf("err: %s", err)
  3237  	}
  3238  
  3239  	actual := strings.TrimSpace(plan.String())
  3240  	expected := strings.TrimSpace(testTerraformPlanCountVarStr)
  3241  	if actual != expected {
  3242  		t.Fatalf("bad:\n%s", actual)
  3243  	}
  3244  }
  3245  
  3246  func TestContextPlan_countZero(t *testing.T) {
  3247  	m := testModule(t, "plan-count-zero")
  3248  	p := testProvider("aws")
  3249  	p.DiffFn = testDiffFn
  3250  	ctx := testContext(t, &ContextOpts{
  3251  		Module: m,
  3252  		Providers: map[string]ResourceProviderFactory{
  3253  			"aws": testProviderFuncFixed(p),
  3254  		},
  3255  	})
  3256  
  3257  	plan, err := ctx.Plan(nil)
  3258  	if err != nil {
  3259  		t.Fatalf("err: %s", err)
  3260  	}
  3261  
  3262  	actual := strings.TrimSpace(plan.String())
  3263  	expected := strings.TrimSpace(testTerraformPlanCountZeroStr)
  3264  	if actual != expected {
  3265  		t.Fatalf("bad:\n%s", actual)
  3266  	}
  3267  }
  3268  
  3269  func TestContextPlan_countOneIndex(t *testing.T) {
  3270  	m := testModule(t, "plan-count-one-index")
  3271  	p := testProvider("aws")
  3272  	p.DiffFn = testDiffFn
  3273  	ctx := testContext(t, &ContextOpts{
  3274  		Module: m,
  3275  		Providers: map[string]ResourceProviderFactory{
  3276  			"aws": testProviderFuncFixed(p),
  3277  		},
  3278  	})
  3279  
  3280  	plan, err := ctx.Plan(nil)
  3281  	if err != nil {
  3282  		t.Fatalf("err: %s", err)
  3283  	}
  3284  
  3285  	actual := strings.TrimSpace(plan.String())
  3286  	expected := strings.TrimSpace(testTerraformPlanCountOneIndexStr)
  3287  	if actual != expected {
  3288  		t.Fatalf("bad:\n%s", actual)
  3289  	}
  3290  }
  3291  
  3292  func TestContextPlan_countDecreaseToOne(t *testing.T) {
  3293  	m := testModule(t, "plan-count-dec")
  3294  	p := testProvider("aws")
  3295  	p.DiffFn = testDiffFn
  3296  	s := &State{
  3297  		Modules: []*ModuleState{
  3298  			&ModuleState{
  3299  				Path: rootModulePath,
  3300  				Resources: map[string]*ResourceState{
  3301  					"aws_instance.foo.0": &ResourceState{
  3302  						Type: "aws_instance",
  3303  						Primary: &InstanceState{
  3304  							ID: "bar",
  3305  							Attributes: map[string]string{
  3306  								"foo":  "foo",
  3307  								"type": "aws_instance",
  3308  							},
  3309  						},
  3310  					},
  3311  					"aws_instance.foo.1": &ResourceState{
  3312  						Type: "aws_instance",
  3313  						Primary: &InstanceState{
  3314  							ID: "bar",
  3315  						},
  3316  					},
  3317  					"aws_instance.foo.2": &ResourceState{
  3318  						Type: "aws_instance",
  3319  						Primary: &InstanceState{
  3320  							ID: "bar",
  3321  						},
  3322  					},
  3323  				},
  3324  			},
  3325  		},
  3326  	}
  3327  	ctx := testContext(t, &ContextOpts{
  3328  		Module: m,
  3329  		Providers: map[string]ResourceProviderFactory{
  3330  			"aws": testProviderFuncFixed(p),
  3331  		},
  3332  		State: s,
  3333  	})
  3334  
  3335  	plan, err := ctx.Plan(nil)
  3336  	if err != nil {
  3337  		t.Fatalf("err: %s", err)
  3338  	}
  3339  
  3340  	actual := strings.TrimSpace(plan.String())
  3341  	expected := strings.TrimSpace(testTerraformPlanCountDecreaseStr)
  3342  	if actual != expected {
  3343  		t.Fatalf("bad:\n%s", actual)
  3344  	}
  3345  }
  3346  
  3347  func TestContextPlan_countIncreaseFromNotSet(t *testing.T) {
  3348  	m := testModule(t, "plan-count-inc")
  3349  	p := testProvider("aws")
  3350  	p.DiffFn = testDiffFn
  3351  	s := &State{
  3352  		Modules: []*ModuleState{
  3353  			&ModuleState{
  3354  				Path: rootModulePath,
  3355  				Resources: map[string]*ResourceState{
  3356  					"aws_instance.foo": &ResourceState{
  3357  						Type: "aws_instance",
  3358  						Primary: &InstanceState{
  3359  							ID: "bar",
  3360  							Attributes: map[string]string{
  3361  								"foo":  "foo",
  3362  								"type": "aws_instance",
  3363  							},
  3364  						},
  3365  					},
  3366  				},
  3367  			},
  3368  		},
  3369  	}
  3370  	ctx := testContext(t, &ContextOpts{
  3371  		Module: m,
  3372  		Providers: map[string]ResourceProviderFactory{
  3373  			"aws": testProviderFuncFixed(p),
  3374  		},
  3375  		State: s,
  3376  	})
  3377  
  3378  	plan, err := ctx.Plan(nil)
  3379  	if err != nil {
  3380  		t.Fatalf("err: %s", err)
  3381  	}
  3382  
  3383  	actual := strings.TrimSpace(plan.String())
  3384  	expected := strings.TrimSpace(testTerraformPlanCountIncreaseStr)
  3385  	if actual != expected {
  3386  		t.Fatalf("bad:\n%s", actual)
  3387  	}
  3388  }
  3389  
  3390  func TestContextPlan_countIncreaseFromOne(t *testing.T) {
  3391  	m := testModule(t, "plan-count-inc")
  3392  	p := testProvider("aws")
  3393  	p.DiffFn = testDiffFn
  3394  	s := &State{
  3395  		Modules: []*ModuleState{
  3396  			&ModuleState{
  3397  				Path: rootModulePath,
  3398  				Resources: map[string]*ResourceState{
  3399  					"aws_instance.foo.0": &ResourceState{
  3400  						Type: "aws_instance",
  3401  						Primary: &InstanceState{
  3402  							ID: "bar",
  3403  							Attributes: map[string]string{
  3404  								"foo":  "foo",
  3405  								"type": "aws_instance",
  3406  							},
  3407  						},
  3408  					},
  3409  				},
  3410  			},
  3411  		},
  3412  	}
  3413  	ctx := testContext(t, &ContextOpts{
  3414  		Module: m,
  3415  		Providers: map[string]ResourceProviderFactory{
  3416  			"aws": testProviderFuncFixed(p),
  3417  		},
  3418  		State: s,
  3419  	})
  3420  
  3421  	plan, err := ctx.Plan(nil)
  3422  	if err != nil {
  3423  		t.Fatalf("err: %s", err)
  3424  	}
  3425  
  3426  	actual := strings.TrimSpace(plan.String())
  3427  	expected := strings.TrimSpace(testTerraformPlanCountIncreaseFromOneStr)
  3428  	if actual != expected {
  3429  		t.Fatalf("bad:\n%s", actual)
  3430  	}
  3431  }
  3432  
  3433  func TestContextPlan_destroy(t *testing.T) {
  3434  	m := testModule(t, "plan-destroy")
  3435  	p := testProvider("aws")
  3436  	p.DiffFn = testDiffFn
  3437  	s := &State{
  3438  		Modules: []*ModuleState{
  3439  			&ModuleState{
  3440  				Path: rootModulePath,
  3441  				Resources: map[string]*ResourceState{
  3442  					"aws_instance.one": &ResourceState{
  3443  						Type: "aws_instance",
  3444  						Primary: &InstanceState{
  3445  							ID: "bar",
  3446  						},
  3447  					},
  3448  					"aws_instance.two": &ResourceState{
  3449  						Type: "aws_instance",
  3450  						Primary: &InstanceState{
  3451  							ID: "baz",
  3452  						},
  3453  					},
  3454  				},
  3455  			},
  3456  		},
  3457  	}
  3458  	ctx := testContext(t, &ContextOpts{
  3459  		Module: m,
  3460  		Providers: map[string]ResourceProviderFactory{
  3461  			"aws": testProviderFuncFixed(p),
  3462  		},
  3463  		State: s,
  3464  	})
  3465  
  3466  	plan, err := ctx.Plan(&PlanOpts{Destroy: true})
  3467  	if err != nil {
  3468  		t.Fatalf("err: %s", err)
  3469  	}
  3470  
  3471  	if len(plan.Diff.RootModule().Resources) != 2 {
  3472  		t.Fatalf("bad: %#v", plan.Diff.RootModule().Resources)
  3473  	}
  3474  
  3475  	actual := strings.TrimSpace(plan.String())
  3476  	expected := strings.TrimSpace(testTerraformPlanDestroyStr)
  3477  	if actual != expected {
  3478  		t.Fatalf("bad:\n%s", actual)
  3479  	}
  3480  }
  3481  
  3482  func TestContextPlan_moduleDestroy(t *testing.T) {
  3483  	m := testModule(t, "plan-module-destroy")
  3484  	p := testProvider("aws")
  3485  	p.DiffFn = testDiffFn
  3486  	s := &State{
  3487  		Modules: []*ModuleState{
  3488  			&ModuleState{
  3489  				Path: rootModulePath,
  3490  				Resources: map[string]*ResourceState{
  3491  					"aws_instance.foo": &ResourceState{
  3492  						Type: "aws_instance",
  3493  						Primary: &InstanceState{
  3494  							ID: "bar",
  3495  						},
  3496  					},
  3497  				},
  3498  			},
  3499  			&ModuleState{
  3500  				Path: []string{"root", "child"},
  3501  				Resources: map[string]*ResourceState{
  3502  					"aws_instance.foo": &ResourceState{
  3503  						Type: "aws_instance",
  3504  						Primary: &InstanceState{
  3505  							ID: "bar",
  3506  						},
  3507  					},
  3508  				},
  3509  			},
  3510  		},
  3511  	}
  3512  	ctx := testContext(t, &ContextOpts{
  3513  		Module: m,
  3514  		Providers: map[string]ResourceProviderFactory{
  3515  			"aws": testProviderFuncFixed(p),
  3516  		},
  3517  		State: s,
  3518  	})
  3519  
  3520  	plan, err := ctx.Plan(&PlanOpts{Destroy: true})
  3521  	if err != nil {
  3522  		t.Fatalf("err: %s", err)
  3523  	}
  3524  
  3525  	actual := strings.TrimSpace(plan.String())
  3526  	expected := strings.TrimSpace(testTerraformPlanModuleDestroyStr)
  3527  	if actual != expected {
  3528  		t.Fatalf("bad:\n%s", actual)
  3529  	}
  3530  }
  3531  
  3532  func TestContextPlan_pathVar(t *testing.T) {
  3533  	cwd, err := os.Getwd()
  3534  	if err != nil {
  3535  		t.Fatalf("err: %s", err)
  3536  	}
  3537  
  3538  	m := testModule(t, "plan-path-var")
  3539  	p := testProvider("aws")
  3540  	p.DiffFn = testDiffFn
  3541  	ctx := testContext(t, &ContextOpts{
  3542  		Module: m,
  3543  		Providers: map[string]ResourceProviderFactory{
  3544  			"aws": testProviderFuncFixed(p),
  3545  		},
  3546  	})
  3547  
  3548  	plan, err := ctx.Plan(nil)
  3549  	if err != nil {
  3550  		t.Fatalf("err: %s", err)
  3551  	}
  3552  
  3553  	actual := strings.TrimSpace(plan.String())
  3554  	expected := strings.TrimSpace(testTerraformPlanPathVarStr)
  3555  
  3556  	// Warning: this ordering REALLY matters for this test. The
  3557  	// order is: cwd, module, root.
  3558  	expected = fmt.Sprintf(
  3559  		expected,
  3560  		cwd,
  3561  		m.Config().Dir,
  3562  		m.Config().Dir)
  3563  
  3564  	if actual != expected {
  3565  		t.Fatalf("bad:\n%s\n\nexpected:\n\n%s", actual, expected)
  3566  	}
  3567  }
  3568  
  3569  func TestContextPlan_diffVar(t *testing.T) {
  3570  	m := testModule(t, "plan-diffvar")
  3571  	p := testProvider("aws")
  3572  	s := &State{
  3573  		Modules: []*ModuleState{
  3574  			&ModuleState{
  3575  				Path: rootModulePath,
  3576  				Resources: map[string]*ResourceState{
  3577  					"aws_instance.foo": &ResourceState{
  3578  						Primary: &InstanceState{
  3579  							ID: "bar",
  3580  							Attributes: map[string]string{
  3581  								"num": "2",
  3582  							},
  3583  						},
  3584  					},
  3585  				},
  3586  			},
  3587  		},
  3588  	}
  3589  	ctx := testContext(t, &ContextOpts{
  3590  		Module: m,
  3591  		Providers: map[string]ResourceProviderFactory{
  3592  			"aws": testProviderFuncFixed(p),
  3593  		},
  3594  		State: s,
  3595  	})
  3596  
  3597  	p.DiffFn = func(
  3598  		info *InstanceInfo,
  3599  		s *InstanceState,
  3600  		c *ResourceConfig) (*InstanceDiff, error) {
  3601  		if s.ID != "bar" {
  3602  			return testDiffFn(info, s, c)
  3603  		}
  3604  
  3605  		return &InstanceDiff{
  3606  			Attributes: map[string]*ResourceAttrDiff{
  3607  				"num": &ResourceAttrDiff{
  3608  					Old: "2",
  3609  					New: "3",
  3610  				},
  3611  			},
  3612  		}, nil
  3613  	}
  3614  
  3615  	plan, err := ctx.Plan(nil)
  3616  	if err != nil {
  3617  		t.Fatalf("err: %s", err)
  3618  	}
  3619  
  3620  	actual := strings.TrimSpace(plan.String())
  3621  	expected := strings.TrimSpace(testTerraformPlanDiffVarStr)
  3622  	if actual != expected {
  3623  		t.Fatalf("actual:\n%s\n\nexpected:\n%s", actual, expected)
  3624  	}
  3625  }
  3626  
  3627  func TestContextPlan_hook(t *testing.T) {
  3628  	m := testModule(t, "plan-good")
  3629  	h := new(MockHook)
  3630  	p := testProvider("aws")
  3631  	p.DiffFn = testDiffFn
  3632  	ctx := testContext(t, &ContextOpts{
  3633  		Module: m,
  3634  		Hooks:  []Hook{h},
  3635  		Providers: map[string]ResourceProviderFactory{
  3636  			"aws": testProviderFuncFixed(p),
  3637  		},
  3638  	})
  3639  
  3640  	_, err := ctx.Plan(nil)
  3641  	if err != nil {
  3642  		t.Fatalf("err: %s", err)
  3643  	}
  3644  
  3645  	if !h.PreDiffCalled {
  3646  		t.Fatal("should be called")
  3647  	}
  3648  	if !h.PostDiffCalled {
  3649  		t.Fatal("should be called")
  3650  	}
  3651  }
  3652  
  3653  func TestContextPlan_orphan(t *testing.T) {
  3654  	m := testModule(t, "plan-orphan")
  3655  	p := testProvider("aws")
  3656  	p.DiffFn = testDiffFn
  3657  	s := &State{
  3658  		Modules: []*ModuleState{
  3659  			&ModuleState{
  3660  				Path: rootModulePath,
  3661  				Resources: map[string]*ResourceState{
  3662  					"aws_instance.baz": &ResourceState{
  3663  						Type: "aws_instance",
  3664  						Primary: &InstanceState{
  3665  							ID: "bar",
  3666  						},
  3667  					},
  3668  				},
  3669  			},
  3670  		},
  3671  	}
  3672  	ctx := testContext(t, &ContextOpts{
  3673  		Module: m,
  3674  		Providers: map[string]ResourceProviderFactory{
  3675  			"aws": testProviderFuncFixed(p),
  3676  		},
  3677  		State: s,
  3678  	})
  3679  
  3680  	plan, err := ctx.Plan(nil)
  3681  	if err != nil {
  3682  		t.Fatalf("err: %s", err)
  3683  	}
  3684  
  3685  	actual := strings.TrimSpace(plan.String())
  3686  	expected := strings.TrimSpace(testTerraformPlanOrphanStr)
  3687  	if actual != expected {
  3688  		t.Fatalf("bad:\n%s", actual)
  3689  	}
  3690  }
  3691  
  3692  func TestContextPlan_state(t *testing.T) {
  3693  	m := testModule(t, "plan-good")
  3694  	p := testProvider("aws")
  3695  	p.DiffFn = testDiffFn
  3696  	s := &State{
  3697  		Modules: []*ModuleState{
  3698  			&ModuleState{
  3699  				Path: rootModulePath,
  3700  				Resources: map[string]*ResourceState{
  3701  					"aws_instance.foo": &ResourceState{
  3702  						Primary: &InstanceState{
  3703  							ID: "bar",
  3704  						},
  3705  					},
  3706  				},
  3707  			},
  3708  		},
  3709  	}
  3710  	ctx := testContext(t, &ContextOpts{
  3711  		Module: m,
  3712  		Providers: map[string]ResourceProviderFactory{
  3713  			"aws": testProviderFuncFixed(p),
  3714  		},
  3715  		State: s,
  3716  	})
  3717  
  3718  	plan, err := ctx.Plan(nil)
  3719  	if err != nil {
  3720  		t.Fatalf("err: %s", err)
  3721  	}
  3722  
  3723  	if len(plan.Diff.RootModule().Resources) < 2 {
  3724  		t.Fatalf("bad: %#v", plan.Diff.RootModule().Resources)
  3725  	}
  3726  
  3727  	actual := strings.TrimSpace(plan.String())
  3728  	expected := strings.TrimSpace(testTerraformPlanStateStr)
  3729  	if actual != expected {
  3730  		t.Fatalf("bad:\n%s\n\nexpected:\n\n%s", actual, expected)
  3731  	}
  3732  }
  3733  
  3734  func TestContextPlan_taint(t *testing.T) {
  3735  	m := testModule(t, "plan-taint")
  3736  	p := testProvider("aws")
  3737  	p.DiffFn = testDiffFn
  3738  	s := &State{
  3739  		Modules: []*ModuleState{
  3740  			&ModuleState{
  3741  				Path: rootModulePath,
  3742  				Resources: map[string]*ResourceState{
  3743  					"aws_instance.foo": &ResourceState{
  3744  						Type: "aws_instance",
  3745  						Primary: &InstanceState{
  3746  							ID:         "bar",
  3747  							Attributes: map[string]string{"num": "2"},
  3748  						},
  3749  					},
  3750  					"aws_instance.bar": &ResourceState{
  3751  						Type: "aws_instance",
  3752  						Tainted: []*InstanceState{
  3753  							&InstanceState{
  3754  								ID: "baz",
  3755  							},
  3756  						},
  3757  					},
  3758  				},
  3759  			},
  3760  		},
  3761  	}
  3762  	ctx := testContext(t, &ContextOpts{
  3763  		Module: m,
  3764  		Providers: map[string]ResourceProviderFactory{
  3765  			"aws": testProviderFuncFixed(p),
  3766  		},
  3767  		State: s,
  3768  	})
  3769  
  3770  	plan, err := ctx.Plan(nil)
  3771  	if err != nil {
  3772  		t.Fatalf("err: %s", err)
  3773  	}
  3774  
  3775  	actual := strings.TrimSpace(plan.String())
  3776  	expected := strings.TrimSpace(testTerraformPlanTaintStr)
  3777  	if actual != expected {
  3778  		t.Fatalf("bad:\n%s", actual)
  3779  	}
  3780  }
  3781  
  3782  func TestContextPlan_multiple_taint(t *testing.T) {
  3783  	m := testModule(t, "plan-taint")
  3784  	p := testProvider("aws")
  3785  	p.DiffFn = testDiffFn
  3786  	s := &State{
  3787  		Modules: []*ModuleState{
  3788  			&ModuleState{
  3789  				Path: rootModulePath,
  3790  				Resources: map[string]*ResourceState{
  3791  					"aws_instance.foo": &ResourceState{
  3792  						Type: "aws_instance",
  3793  						Primary: &InstanceState{
  3794  							ID:         "bar",
  3795  							Attributes: map[string]string{"num": "2"},
  3796  						},
  3797  					},
  3798  					"aws_instance.bar": &ResourceState{
  3799  						Type: "aws_instance",
  3800  						Tainted: []*InstanceState{
  3801  							&InstanceState{
  3802  								ID: "baz",
  3803  							},
  3804  							&InstanceState{
  3805  								ID: "zip",
  3806  							},
  3807  						},
  3808  					},
  3809  				},
  3810  			},
  3811  		},
  3812  	}
  3813  	ctx := testContext(t, &ContextOpts{
  3814  		Module: m,
  3815  		Providers: map[string]ResourceProviderFactory{
  3816  			"aws": testProviderFuncFixed(p),
  3817  		},
  3818  		State: s,
  3819  	})
  3820  
  3821  	plan, err := ctx.Plan(nil)
  3822  	if err != nil {
  3823  		t.Fatalf("err: %s", err)
  3824  	}
  3825  
  3826  	actual := strings.TrimSpace(plan.String())
  3827  	expected := strings.TrimSpace(testTerraformPlanMultipleTaintStr)
  3828  	if actual != expected {
  3829  		t.Fatalf("bad:\n%s", actual)
  3830  	}
  3831  }
  3832  
  3833  func TestContextPlan_provider(t *testing.T) {
  3834  	m := testModule(t, "plan-provider")
  3835  	p := testProvider("aws")
  3836  	p.DiffFn = testDiffFn
  3837  
  3838  	var value interface{}
  3839  	p.ConfigureFn = func(c *ResourceConfig) error {
  3840  		value, _ = c.Get("foo")
  3841  		return nil
  3842  	}
  3843  
  3844  	ctx := testContext(t, &ContextOpts{
  3845  		Module: m,
  3846  		Providers: map[string]ResourceProviderFactory{
  3847  			"aws": testProviderFuncFixed(p),
  3848  		},
  3849  		Variables: map[string]string{
  3850  			"foo": "bar",
  3851  		},
  3852  	})
  3853  
  3854  	if _, err := ctx.Plan(nil); err != nil {
  3855  		t.Fatalf("err: %s", err)
  3856  	}
  3857  
  3858  	if value != "bar" {
  3859  		t.Fatalf("bad: %#v", value)
  3860  	}
  3861  }
  3862  
  3863  func TestContextPlan_varMultiCountOne(t *testing.T) {
  3864  	m := testModule(t, "plan-var-multi-count-one")
  3865  	p := testProvider("aws")
  3866  	p.DiffFn = testDiffFn
  3867  	ctx := testContext(t, &ContextOpts{
  3868  		Module: m,
  3869  		Providers: map[string]ResourceProviderFactory{
  3870  			"aws": testProviderFuncFixed(p),
  3871  		},
  3872  	})
  3873  
  3874  	plan, err := ctx.Plan(nil)
  3875  	if err != nil {
  3876  		t.Fatalf("err: %s", err)
  3877  	}
  3878  
  3879  	actual := strings.TrimSpace(plan.String())
  3880  	expected := strings.TrimSpace(testTerraformPlanVarMultiCountOneStr)
  3881  	if actual != expected {
  3882  		t.Fatalf("bad:\n%s", actual)
  3883  	}
  3884  }
  3885  
  3886  func TestContextRefresh(t *testing.T) {
  3887  	p := testProvider("aws")
  3888  	m := testModule(t, "refresh-basic")
  3889  	ctx := testContext(t, &ContextOpts{
  3890  		Module: m,
  3891  		Providers: map[string]ResourceProviderFactory{
  3892  			"aws": testProviderFuncFixed(p),
  3893  		},
  3894  		State: &State{
  3895  			Modules: []*ModuleState{
  3896  				&ModuleState{
  3897  					Path: rootModulePath,
  3898  					Resources: map[string]*ResourceState{
  3899  						"aws_instance.web": &ResourceState{
  3900  							Type: "aws_instance",
  3901  							Primary: &InstanceState{
  3902  								ID: "foo",
  3903  							},
  3904  						},
  3905  					},
  3906  				},
  3907  			},
  3908  		},
  3909  	})
  3910  
  3911  	p.RefreshFn = nil
  3912  	p.RefreshReturn = &InstanceState{
  3913  		ID: "foo",
  3914  	}
  3915  
  3916  	s, err := ctx.Refresh()
  3917  	mod := s.RootModule()
  3918  	if err != nil {
  3919  		t.Fatalf("err: %s", err)
  3920  	}
  3921  	if !p.RefreshCalled {
  3922  		t.Fatal("refresh should be called")
  3923  	}
  3924  	if p.RefreshState.ID != "foo" {
  3925  		t.Fatalf("bad: %#v", p.RefreshState)
  3926  	}
  3927  	if !reflect.DeepEqual(mod.Resources["aws_instance.web"].Primary, p.RefreshReturn) {
  3928  		t.Fatalf("bad: %#v %#v", mod.Resources["aws_instance.web"], p.RefreshReturn)
  3929  	}
  3930  
  3931  	for _, r := range mod.Resources {
  3932  		if r.Type == "" {
  3933  			t.Fatalf("no type: %#v", r)
  3934  		}
  3935  	}
  3936  }
  3937  
  3938  func TestContextRefresh_delete(t *testing.T) {
  3939  	p := testProvider("aws")
  3940  	m := testModule(t, "refresh-basic")
  3941  	ctx := testContext(t, &ContextOpts{
  3942  		Module: m,
  3943  		Providers: map[string]ResourceProviderFactory{
  3944  			"aws": testProviderFuncFixed(p),
  3945  		},
  3946  		State: &State{
  3947  			Modules: []*ModuleState{
  3948  				&ModuleState{
  3949  					Path: rootModulePath,
  3950  					Resources: map[string]*ResourceState{
  3951  						"aws_instance.web": &ResourceState{
  3952  							Type: "aws_instance",
  3953  							Primary: &InstanceState{
  3954  								ID: "foo",
  3955  							},
  3956  						},
  3957  					},
  3958  				},
  3959  			},
  3960  		},
  3961  	})
  3962  
  3963  	p.RefreshFn = nil
  3964  	p.RefreshReturn = nil
  3965  
  3966  	s, err := ctx.Refresh()
  3967  	if err != nil {
  3968  		t.Fatalf("err: %s", err)
  3969  	}
  3970  
  3971  	mod := s.RootModule()
  3972  	if len(mod.Resources) > 0 {
  3973  		t.Fatal("resources should be empty")
  3974  	}
  3975  }
  3976  
  3977  func TestContextRefresh_ignoreUncreated(t *testing.T) {
  3978  	p := testProvider("aws")
  3979  	m := testModule(t, "refresh-basic")
  3980  	ctx := testContext(t, &ContextOpts{
  3981  		Module: m,
  3982  		Providers: map[string]ResourceProviderFactory{
  3983  			"aws": testProviderFuncFixed(p),
  3984  		},
  3985  		State: nil,
  3986  	})
  3987  
  3988  	p.RefreshFn = nil
  3989  	p.RefreshReturn = &InstanceState{
  3990  		ID: "foo",
  3991  	}
  3992  
  3993  	_, err := ctx.Refresh()
  3994  	if err != nil {
  3995  		t.Fatalf("err: %s", err)
  3996  	}
  3997  	if p.RefreshCalled {
  3998  		t.Fatal("refresh should not be called")
  3999  	}
  4000  }
  4001  
  4002  func TestContextRefresh_hook(t *testing.T) {
  4003  	h := new(MockHook)
  4004  	p := testProvider("aws")
  4005  	m := testModule(t, "refresh-basic")
  4006  	ctx := testContext(t, &ContextOpts{
  4007  		Module: m,
  4008  		Hooks:  []Hook{h},
  4009  		Providers: map[string]ResourceProviderFactory{
  4010  			"aws": testProviderFuncFixed(p),
  4011  		},
  4012  		State: &State{
  4013  			Modules: []*ModuleState{
  4014  				&ModuleState{
  4015  					Path: rootModulePath,
  4016  					Resources: map[string]*ResourceState{
  4017  						"aws_instance.web": &ResourceState{
  4018  							Type: "aws_instance",
  4019  							Primary: &InstanceState{
  4020  								ID: "foo",
  4021  							},
  4022  						},
  4023  					},
  4024  				},
  4025  			},
  4026  		},
  4027  	})
  4028  
  4029  	if _, err := ctx.Refresh(); err != nil {
  4030  		t.Fatalf("err: %s", err)
  4031  	}
  4032  	if !h.PreRefreshCalled {
  4033  		t.Fatal("should be called")
  4034  	}
  4035  	/*
  4036  		TODO(mitchcellh): remove when we add InstanceInfo param
  4037  		if h.PreRefreshState.Type != "aws_instance" {
  4038  			t.Fatalf("bad: %#v", h.PreRefreshState)
  4039  		}
  4040  	*/
  4041  	if !h.PostRefreshCalled {
  4042  		t.Fatal("should be called")
  4043  	}
  4044  	/*
  4045  		TODO(mitchcellh): remove when we add InstanceInfo param
  4046  		if h.PostRefreshState.Type != "aws_instance" {
  4047  			t.Fatalf("bad: %#v", h.PostRefreshState)
  4048  		}
  4049  	*/
  4050  }
  4051  
  4052  func TestContextRefresh_modules(t *testing.T) {
  4053  	p := testProvider("aws")
  4054  	m := testModule(t, "refresh-modules")
  4055  	state := &State{
  4056  		Modules: []*ModuleState{
  4057  			&ModuleState{
  4058  				Path: rootModulePath,
  4059  				Resources: map[string]*ResourceState{
  4060  					"aws_instance.web": &ResourceState{
  4061  						Type: "aws_instance",
  4062  						Tainted: []*InstanceState{
  4063  							&InstanceState{
  4064  								ID: "bar",
  4065  							},
  4066  						},
  4067  					},
  4068  				},
  4069  			},
  4070  
  4071  			&ModuleState{
  4072  				Path: []string{"root", "child"},
  4073  				Resources: map[string]*ResourceState{
  4074  					"aws_instance.web": &ResourceState{
  4075  						Type: "aws_instance",
  4076  						Primary: &InstanceState{
  4077  							ID: "baz",
  4078  						},
  4079  					},
  4080  				},
  4081  			},
  4082  		},
  4083  	}
  4084  	ctx := testContext(t, &ContextOpts{
  4085  		Module: m,
  4086  		Providers: map[string]ResourceProviderFactory{
  4087  			"aws": testProviderFuncFixed(p),
  4088  		},
  4089  		State: state,
  4090  	})
  4091  
  4092  	p.RefreshFn = func(info *InstanceInfo, s *InstanceState) (*InstanceState, error) {
  4093  		if s.ID != "baz" {
  4094  			return s, nil
  4095  		}
  4096  
  4097  		s.ID = "new"
  4098  		return s, nil
  4099  	}
  4100  
  4101  	s, err := ctx.Refresh()
  4102  	if err != nil {
  4103  		t.Fatalf("err: %s", err)
  4104  	}
  4105  
  4106  	actual := strings.TrimSpace(s.String())
  4107  	expected := strings.TrimSpace(testContextRefreshModuleStr)
  4108  	if actual != expected {
  4109  		t.Fatalf("bad:\n\n%s\n\n%s", actual, expected)
  4110  	}
  4111  }
  4112  
  4113  // GH-70
  4114  func TestContextRefresh_noState(t *testing.T) {
  4115  	p := testProvider("aws")
  4116  	m := testModule(t, "refresh-no-state")
  4117  	ctx := testContext(t, &ContextOpts{
  4118  		Module: m,
  4119  		Providers: map[string]ResourceProviderFactory{
  4120  			"aws": testProviderFuncFixed(p),
  4121  		},
  4122  	})
  4123  
  4124  	p.RefreshFn = nil
  4125  	p.RefreshReturn = &InstanceState{
  4126  		ID: "foo",
  4127  	}
  4128  
  4129  	if _, err := ctx.Refresh(); err != nil {
  4130  		t.Fatalf("err: %s", err)
  4131  	}
  4132  }
  4133  
  4134  func TestContextRefresh_state(t *testing.T) {
  4135  	p := testProvider("aws")
  4136  	m := testModule(t, "refresh-basic")
  4137  	state := &State{
  4138  		Modules: []*ModuleState{
  4139  			&ModuleState{
  4140  				Path: rootModulePath,
  4141  				Resources: map[string]*ResourceState{
  4142  					"aws_instance.web": &ResourceState{
  4143  						Primary: &InstanceState{
  4144  							ID: "bar",
  4145  						},
  4146  					},
  4147  				},
  4148  			},
  4149  		},
  4150  	}
  4151  	ctx := testContext(t, &ContextOpts{
  4152  		Module: m,
  4153  		Providers: map[string]ResourceProviderFactory{
  4154  			"aws": testProviderFuncFixed(p),
  4155  		},
  4156  		State: state,
  4157  	})
  4158  
  4159  	p.RefreshFn = nil
  4160  	p.RefreshReturn = &InstanceState{
  4161  		ID: "foo",
  4162  	}
  4163  
  4164  	s, err := ctx.Refresh()
  4165  	if err != nil {
  4166  		t.Fatalf("err: %s", err)
  4167  	}
  4168  	originalMod := state.RootModule()
  4169  	mod := s.RootModule()
  4170  	if !p.RefreshCalled {
  4171  		t.Fatal("refresh should be called")
  4172  	}
  4173  	if !reflect.DeepEqual(p.RefreshState, originalMod.Resources["aws_instance.web"].Primary) {
  4174  		t.Fatalf("bad: %#v %#v", p.RefreshState, originalMod.Resources["aws_instance.web"].Primary)
  4175  	}
  4176  	if !reflect.DeepEqual(mod.Resources["aws_instance.web"].Primary, p.RefreshReturn) {
  4177  		t.Fatalf("bad: %#v", mod.Resources)
  4178  	}
  4179  }
  4180  
  4181  func TestContextRefresh_tainted(t *testing.T) {
  4182  	p := testProvider("aws")
  4183  	m := testModule(t, "refresh-basic")
  4184  	state := &State{
  4185  		Modules: []*ModuleState{
  4186  			&ModuleState{
  4187  				Path: rootModulePath,
  4188  				Resources: map[string]*ResourceState{
  4189  					"aws_instance.web": &ResourceState{
  4190  						Type: "aws_instance",
  4191  						Tainted: []*InstanceState{
  4192  							&InstanceState{
  4193  								ID: "bar",
  4194  							},
  4195  						},
  4196  					},
  4197  				},
  4198  			},
  4199  		},
  4200  	}
  4201  	ctx := testContext(t, &ContextOpts{
  4202  		Module: m,
  4203  		Providers: map[string]ResourceProviderFactory{
  4204  			"aws": testProviderFuncFixed(p),
  4205  		},
  4206  		State: state,
  4207  	})
  4208  
  4209  	p.RefreshFn = nil
  4210  	p.RefreshReturn = &InstanceState{
  4211  		ID: "foo",
  4212  	}
  4213  
  4214  	s, err := ctx.Refresh()
  4215  	if err != nil {
  4216  		t.Fatalf("err: %s", err)
  4217  	}
  4218  	if !p.RefreshCalled {
  4219  		t.Fatal("refresh should be called")
  4220  	}
  4221  
  4222  	actual := strings.TrimSpace(s.String())
  4223  	expected := strings.TrimSpace(testContextRefreshTaintedStr)
  4224  	if actual != expected {
  4225  		t.Fatalf("bad:\n\n%s\n\n%s", actual, expected)
  4226  	}
  4227  }
  4228  
  4229  func TestContextRefresh_vars(t *testing.T) {
  4230  	p := testProvider("aws")
  4231  	m := testModule(t, "refresh-vars")
  4232  	ctx := testContext(t, &ContextOpts{
  4233  		Module: m,
  4234  		Providers: map[string]ResourceProviderFactory{
  4235  			"aws": testProviderFuncFixed(p),
  4236  		},
  4237  		State: &State{
  4238  
  4239  			Modules: []*ModuleState{
  4240  				&ModuleState{
  4241  					Path: rootModulePath,
  4242  					Resources: map[string]*ResourceState{
  4243  						"aws_instance.web": &ResourceState{
  4244  							Type: "aws_instance",
  4245  							Primary: &InstanceState{
  4246  								ID: "foo",
  4247  							},
  4248  						},
  4249  					},
  4250  				},
  4251  			},
  4252  		},
  4253  	})
  4254  
  4255  	p.RefreshFn = nil
  4256  	p.RefreshReturn = &InstanceState{
  4257  		ID: "foo",
  4258  	}
  4259  
  4260  	s, err := ctx.Refresh()
  4261  	if err != nil {
  4262  		t.Fatalf("err: %s", err)
  4263  	}
  4264  	mod := s.RootModule()
  4265  	if !p.RefreshCalled {
  4266  		t.Fatal("refresh should be called")
  4267  	}
  4268  	if p.RefreshState.ID != "foo" {
  4269  		t.Fatalf("bad: %#v", p.RefreshState)
  4270  	}
  4271  	if !reflect.DeepEqual(mod.Resources["aws_instance.web"].Primary, p.RefreshReturn) {
  4272  		t.Fatalf("bad: %#v", mod.Resources["aws_instance.web"])
  4273  	}
  4274  
  4275  	for _, r := range mod.Resources {
  4276  		if r.Type == "" {
  4277  			t.Fatalf("no type: %#v", r)
  4278  		}
  4279  	}
  4280  }
  4281  
  4282  func testContext(t *testing.T, opts *ContextOpts) *Context {
  4283  	return NewContext(opts)
  4284  }
  4285  
  4286  func testApplyFn(
  4287  	info *InstanceInfo,
  4288  	s *InstanceState,
  4289  	d *InstanceDiff) (*InstanceState, error) {
  4290  	if d.Destroy {
  4291  		return nil, nil
  4292  	}
  4293  
  4294  	id := "foo"
  4295  	if idAttr, ok := d.Attributes["id"]; ok && !idAttr.NewComputed {
  4296  		id = idAttr.New
  4297  	}
  4298  
  4299  	result := &InstanceState{
  4300  		ID: id,
  4301  	}
  4302  
  4303  	if d != nil {
  4304  		result = result.MergeDiff(d)
  4305  	}
  4306  	return result, nil
  4307  }
  4308  
  4309  func testDiffFn(
  4310  	info *InstanceInfo,
  4311  	s *InstanceState,
  4312  	c *ResourceConfig) (*InstanceDiff, error) {
  4313  	var diff InstanceDiff
  4314  	diff.Attributes = make(map[string]*ResourceAttrDiff)
  4315  
  4316  	for k, v := range c.Raw {
  4317  		if _, ok := v.(string); !ok {
  4318  			continue
  4319  		}
  4320  
  4321  		if k == "nil" {
  4322  			return nil, nil
  4323  		}
  4324  
  4325  		// This key is used for other purposes
  4326  		if k == "compute_value" {
  4327  			continue
  4328  		}
  4329  
  4330  		if k == "compute" {
  4331  			attrDiff := &ResourceAttrDiff{
  4332  				Old:         "",
  4333  				New:         "",
  4334  				NewComputed: true,
  4335  			}
  4336  
  4337  			if cv, ok := c.Config["compute_value"]; ok {
  4338  				if cv.(string) == "1" {
  4339  					attrDiff.NewComputed = false
  4340  					attrDiff.New = fmt.Sprintf("computed_%s", v.(string))
  4341  				}
  4342  			}
  4343  
  4344  			diff.Attributes[v.(string)] = attrDiff
  4345  			continue
  4346  		}
  4347  
  4348  		// If this key is not computed, then look it up in the
  4349  		// cleaned config.
  4350  		found := false
  4351  		for _, ck := range c.ComputedKeys {
  4352  			if ck == k {
  4353  				found = true
  4354  				break
  4355  			}
  4356  		}
  4357  		if !found {
  4358  			v = c.Config[k]
  4359  		}
  4360  
  4361  		attrDiff := &ResourceAttrDiff{
  4362  			Old: "",
  4363  			New: v.(string),
  4364  		}
  4365  
  4366  		if k == "require_new" {
  4367  			attrDiff.RequiresNew = true
  4368  		}
  4369  		diff.Attributes[k] = attrDiff
  4370  	}
  4371  
  4372  	for _, k := range c.ComputedKeys {
  4373  		diff.Attributes[k] = &ResourceAttrDiff{
  4374  			Old:         "",
  4375  			NewComputed: true,
  4376  		}
  4377  	}
  4378  
  4379  	for k, v := range diff.Attributes {
  4380  		if v.NewComputed {
  4381  			continue
  4382  		}
  4383  
  4384  		old, ok := s.Attributes[k]
  4385  		if !ok {
  4386  			continue
  4387  		}
  4388  		if old == v.New {
  4389  			delete(diff.Attributes, k)
  4390  		}
  4391  	}
  4392  
  4393  	if !diff.Empty() {
  4394  		diff.Attributes["type"] = &ResourceAttrDiff{
  4395  			Old: "",
  4396  			New: info.Type,
  4397  		}
  4398  	}
  4399  
  4400  	return &diff, nil
  4401  }
  4402  
  4403  func testProvider(prefix string) *MockResourceProvider {
  4404  	p := new(MockResourceProvider)
  4405  	p.RefreshFn = func(info *InstanceInfo, s *InstanceState) (*InstanceState, error) {
  4406  		return s, nil
  4407  	}
  4408  	p.ResourcesReturn = []ResourceType{
  4409  		ResourceType{
  4410  			Name: fmt.Sprintf("%s_instance", prefix),
  4411  		},
  4412  	}
  4413  
  4414  	return p
  4415  }
  4416  
  4417  func testProvisioner() *MockResourceProvisioner {
  4418  	p := new(MockResourceProvisioner)
  4419  	return p
  4420  }
  4421  
  4422  const testContextGraph = `
  4423  root: root
  4424  aws_instance.bar
  4425    aws_instance.bar -> provider.aws
  4426  aws_instance.foo
  4427    aws_instance.foo -> provider.aws
  4428  provider.aws
  4429  root
  4430    root -> aws_instance.bar
  4431    root -> aws_instance.foo
  4432  `
  4433  
  4434  const testContextRefreshModuleStr = `
  4435  aws_instance.web: (1 tainted)
  4436    ID = <not created>
  4437    Tainted ID 1 = bar
  4438  
  4439  module.child:
  4440    aws_instance.web:
  4441      ID = new
  4442  `
  4443  
  4444  const testContextRefreshTaintedStr = `
  4445  aws_instance.web: (1 tainted)
  4446    ID = <not created>
  4447    Tainted ID 1 = foo
  4448  `