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