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