github.com/markdia/terraform@v0.5.1-0.20150508012022-f1ae920aa970/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  // GH-1835
  1159  func TestContext2Plan_moduleDestroyCycle(t *testing.T) {
  1160  	m := testModule(t, "plan-module-destroy-gh-1835")
  1161  	p := testProvider("aws")
  1162  	p.DiffFn = testDiffFn
  1163  	s := &State{
  1164  		Modules: []*ModuleState{
  1165  			&ModuleState{
  1166  				Path: []string{"root", "a_module"},
  1167  				Resources: map[string]*ResourceState{
  1168  					"aws_instance.a": &ResourceState{
  1169  						Type: "aws_instance",
  1170  						Primary: &InstanceState{
  1171  							ID: "a",
  1172  						},
  1173  					},
  1174  				},
  1175  			},
  1176  			&ModuleState{
  1177  				Path: []string{"root", "b_module"},
  1178  				Resources: map[string]*ResourceState{
  1179  					"aws_instance.b": &ResourceState{
  1180  						Type: "aws_instance",
  1181  						Primary: &InstanceState{
  1182  							ID: "b",
  1183  						},
  1184  					},
  1185  				},
  1186  			},
  1187  		},
  1188  	}
  1189  	ctx := testContext2(t, &ContextOpts{
  1190  		Module: m,
  1191  		Providers: map[string]ResourceProviderFactory{
  1192  			"aws": testProviderFuncFixed(p),
  1193  		},
  1194  		State:   s,
  1195  		Destroy: true,
  1196  	})
  1197  
  1198  	plan, err := ctx.Plan()
  1199  	if err != nil {
  1200  		t.Fatalf("err: %s", err)
  1201  	}
  1202  
  1203  	actual := strings.TrimSpace(plan.String())
  1204  	expected := strings.TrimSpace(testTerraformPlanModuleDestroyCycleStr)
  1205  	if actual != expected {
  1206  		t.Fatalf("bad:\n%s", actual)
  1207  	}
  1208  }
  1209  
  1210  func TestContext2Plan_moduleDestroyMultivar(t *testing.T) {
  1211  	m := testModule(t, "plan-module-destroy-multivar")
  1212  	p := testProvider("aws")
  1213  	p.DiffFn = testDiffFn
  1214  	s := &State{
  1215  		Modules: []*ModuleState{
  1216  			&ModuleState{
  1217  				Path:      rootModulePath,
  1218  				Resources: map[string]*ResourceState{},
  1219  			},
  1220  			&ModuleState{
  1221  				Path: []string{"root", "child"},
  1222  				Resources: map[string]*ResourceState{
  1223  					"aws_instance.foo.0": &ResourceState{
  1224  						Type: "aws_instance",
  1225  						Primary: &InstanceState{
  1226  							ID: "bar0",
  1227  						},
  1228  					},
  1229  					"aws_instance.foo.1": &ResourceState{
  1230  						Type: "aws_instance",
  1231  						Primary: &InstanceState{
  1232  							ID: "bar1",
  1233  						},
  1234  					},
  1235  				},
  1236  			},
  1237  		},
  1238  	}
  1239  	ctx := testContext2(t, &ContextOpts{
  1240  		Module: m,
  1241  		Providers: map[string]ResourceProviderFactory{
  1242  			"aws": testProviderFuncFixed(p),
  1243  		},
  1244  		State:   s,
  1245  		Destroy: true,
  1246  	})
  1247  
  1248  	plan, err := ctx.Plan()
  1249  	if err != nil {
  1250  		t.Fatalf("err: %s", err)
  1251  	}
  1252  
  1253  	actual := strings.TrimSpace(plan.String())
  1254  	expected := strings.TrimSpace(testTerraformPlanModuleDestroyMultivarStr)
  1255  	if actual != expected {
  1256  		t.Fatalf("bad:\n%s", actual)
  1257  	}
  1258  }
  1259  
  1260  func TestContext2Plan_pathVar(t *testing.T) {
  1261  	cwd, err := os.Getwd()
  1262  	if err != nil {
  1263  		t.Fatalf("err: %s", err)
  1264  	}
  1265  
  1266  	m := testModule(t, "plan-path-var")
  1267  	p := testProvider("aws")
  1268  	p.DiffFn = testDiffFn
  1269  	ctx := testContext2(t, &ContextOpts{
  1270  		Module: m,
  1271  		Providers: map[string]ResourceProviderFactory{
  1272  			"aws": testProviderFuncFixed(p),
  1273  		},
  1274  	})
  1275  
  1276  	plan, err := ctx.Plan()
  1277  	if err != nil {
  1278  		t.Fatalf("err: %s", err)
  1279  	}
  1280  
  1281  	actual := strings.TrimSpace(plan.String())
  1282  	expected := strings.TrimSpace(testTerraformPlanPathVarStr)
  1283  
  1284  	// Warning: this ordering REALLY matters for this test. The
  1285  	// order is: cwd, module, root.
  1286  	expected = fmt.Sprintf(
  1287  		expected,
  1288  		cwd,
  1289  		m.Config().Dir,
  1290  		m.Config().Dir)
  1291  
  1292  	if actual != expected {
  1293  		t.Fatalf("bad:\n%s\n\nexpected:\n\n%s", actual, expected)
  1294  	}
  1295  }
  1296  
  1297  func TestContext2Plan_diffVar(t *testing.T) {
  1298  	m := testModule(t, "plan-diffvar")
  1299  	p := testProvider("aws")
  1300  	s := &State{
  1301  		Modules: []*ModuleState{
  1302  			&ModuleState{
  1303  				Path: rootModulePath,
  1304  				Resources: map[string]*ResourceState{
  1305  					"aws_instance.foo": &ResourceState{
  1306  						Primary: &InstanceState{
  1307  							ID: "bar",
  1308  							Attributes: map[string]string{
  1309  								"num": "2",
  1310  							},
  1311  						},
  1312  					},
  1313  				},
  1314  			},
  1315  		},
  1316  	}
  1317  	ctx := testContext2(t, &ContextOpts{
  1318  		Module: m,
  1319  		Providers: map[string]ResourceProviderFactory{
  1320  			"aws": testProviderFuncFixed(p),
  1321  		},
  1322  		State: s,
  1323  	})
  1324  
  1325  	p.DiffFn = func(
  1326  		info *InstanceInfo,
  1327  		s *InstanceState,
  1328  		c *ResourceConfig) (*InstanceDiff, error) {
  1329  		if s.ID != "bar" {
  1330  			return testDiffFn(info, s, c)
  1331  		}
  1332  
  1333  		return &InstanceDiff{
  1334  			Attributes: map[string]*ResourceAttrDiff{
  1335  				"num": &ResourceAttrDiff{
  1336  					Old: "2",
  1337  					New: "3",
  1338  				},
  1339  			},
  1340  		}, nil
  1341  	}
  1342  
  1343  	plan, err := ctx.Plan()
  1344  	if err != nil {
  1345  		t.Fatalf("err: %s", err)
  1346  	}
  1347  
  1348  	actual := strings.TrimSpace(plan.String())
  1349  	expected := strings.TrimSpace(testTerraformPlanDiffVarStr)
  1350  	if actual != expected {
  1351  		t.Fatalf("actual:\n%s\n\nexpected:\n%s", actual, expected)
  1352  	}
  1353  }
  1354  
  1355  func TestContext2Plan_hook(t *testing.T) {
  1356  	m := testModule(t, "plan-good")
  1357  	h := new(MockHook)
  1358  	p := testProvider("aws")
  1359  	p.DiffFn = testDiffFn
  1360  	ctx := testContext2(t, &ContextOpts{
  1361  		Module: m,
  1362  		Hooks:  []Hook{h},
  1363  		Providers: map[string]ResourceProviderFactory{
  1364  			"aws": testProviderFuncFixed(p),
  1365  		},
  1366  	})
  1367  
  1368  	_, err := ctx.Plan()
  1369  	if err != nil {
  1370  		t.Fatalf("err: %s", err)
  1371  	}
  1372  
  1373  	if !h.PreDiffCalled {
  1374  		t.Fatal("should be called")
  1375  	}
  1376  	if !h.PostDiffCalled {
  1377  		t.Fatal("should be called")
  1378  	}
  1379  }
  1380  
  1381  func TestContext2Plan_orphan(t *testing.T) {
  1382  	m := testModule(t, "plan-orphan")
  1383  	p := testProvider("aws")
  1384  	p.DiffFn = testDiffFn
  1385  	s := &State{
  1386  		Modules: []*ModuleState{
  1387  			&ModuleState{
  1388  				Path: rootModulePath,
  1389  				Resources: map[string]*ResourceState{
  1390  					"aws_instance.baz": &ResourceState{
  1391  						Type: "aws_instance",
  1392  						Primary: &InstanceState{
  1393  							ID: "bar",
  1394  						},
  1395  					},
  1396  				},
  1397  			},
  1398  		},
  1399  	}
  1400  	ctx := testContext2(t, &ContextOpts{
  1401  		Module: m,
  1402  		Providers: map[string]ResourceProviderFactory{
  1403  			"aws": testProviderFuncFixed(p),
  1404  		},
  1405  		State: s,
  1406  	})
  1407  
  1408  	plan, err := ctx.Plan()
  1409  	if err != nil {
  1410  		t.Fatalf("err: %s", err)
  1411  	}
  1412  
  1413  	actual := strings.TrimSpace(plan.String())
  1414  	expected := strings.TrimSpace(testTerraformPlanOrphanStr)
  1415  	if actual != expected {
  1416  		t.Fatalf("bad:\n%s", actual)
  1417  	}
  1418  }
  1419  
  1420  func TestContext2Plan_state(t *testing.T) {
  1421  	m := testModule(t, "plan-good")
  1422  	p := testProvider("aws")
  1423  	p.DiffFn = testDiffFn
  1424  	s := &State{
  1425  		Modules: []*ModuleState{
  1426  			&ModuleState{
  1427  				Path: rootModulePath,
  1428  				Resources: map[string]*ResourceState{
  1429  					"aws_instance.foo": &ResourceState{
  1430  						Primary: &InstanceState{
  1431  							ID: "bar",
  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  	if len(plan.Diff.RootModule().Resources) < 2 {
  1452  		t.Fatalf("bad: %#v", plan.Diff.RootModule().Resources)
  1453  	}
  1454  
  1455  	actual := strings.TrimSpace(plan.String())
  1456  	expected := strings.TrimSpace(testTerraformPlanStateStr)
  1457  	if actual != expected {
  1458  		t.Fatalf("bad:\n%s\n\nexpected:\n\n%s", actual, expected)
  1459  	}
  1460  }
  1461  
  1462  func TestContext2Plan_taint(t *testing.T) {
  1463  	m := testModule(t, "plan-taint")
  1464  	p := testProvider("aws")
  1465  	p.DiffFn = testDiffFn
  1466  	s := &State{
  1467  		Modules: []*ModuleState{
  1468  			&ModuleState{
  1469  				Path: rootModulePath,
  1470  				Resources: map[string]*ResourceState{
  1471  					"aws_instance.foo": &ResourceState{
  1472  						Type: "aws_instance",
  1473  						Primary: &InstanceState{
  1474  							ID:         "bar",
  1475  							Attributes: map[string]string{"num": "2"},
  1476  						},
  1477  					},
  1478  					"aws_instance.bar": &ResourceState{
  1479  						Type: "aws_instance",
  1480  						Tainted: []*InstanceState{
  1481  							&InstanceState{
  1482  								ID: "baz",
  1483  							},
  1484  						},
  1485  					},
  1486  				},
  1487  			},
  1488  		},
  1489  	}
  1490  	ctx := testContext2(t, &ContextOpts{
  1491  		Module: m,
  1492  		Providers: map[string]ResourceProviderFactory{
  1493  			"aws": testProviderFuncFixed(p),
  1494  		},
  1495  		State: s,
  1496  	})
  1497  
  1498  	plan, err := ctx.Plan()
  1499  	if err != nil {
  1500  		t.Fatalf("err: %s", err)
  1501  	}
  1502  
  1503  	actual := strings.TrimSpace(plan.String())
  1504  	expected := strings.TrimSpace(testTerraformPlanTaintStr)
  1505  	if actual != expected {
  1506  		t.Fatalf("bad:\n%s", actual)
  1507  	}
  1508  }
  1509  
  1510  func TestContext2Plan_multiple_taint(t *testing.T) {
  1511  	m := testModule(t, "plan-taint")
  1512  	p := testProvider("aws")
  1513  	p.DiffFn = testDiffFn
  1514  	s := &State{
  1515  		Modules: []*ModuleState{
  1516  			&ModuleState{
  1517  				Path: rootModulePath,
  1518  				Resources: map[string]*ResourceState{
  1519  					"aws_instance.foo": &ResourceState{
  1520  						Type: "aws_instance",
  1521  						Primary: &InstanceState{
  1522  							ID:         "bar",
  1523  							Attributes: map[string]string{"num": "2"},
  1524  						},
  1525  					},
  1526  					"aws_instance.bar": &ResourceState{
  1527  						Type: "aws_instance",
  1528  						Tainted: []*InstanceState{
  1529  							&InstanceState{
  1530  								ID: "baz",
  1531  							},
  1532  							&InstanceState{
  1533  								ID: "zip",
  1534  							},
  1535  						},
  1536  					},
  1537  				},
  1538  			},
  1539  		},
  1540  	}
  1541  	ctx := testContext2(t, &ContextOpts{
  1542  		Module: m,
  1543  		Providers: map[string]ResourceProviderFactory{
  1544  			"aws": testProviderFuncFixed(p),
  1545  		},
  1546  		State: s,
  1547  	})
  1548  
  1549  	plan, err := ctx.Plan()
  1550  	if err != nil {
  1551  		t.Fatalf("err: %s", err)
  1552  	}
  1553  
  1554  	actual := strings.TrimSpace(plan.String())
  1555  	expected := strings.TrimSpace(testTerraformPlanMultipleTaintStr)
  1556  	if actual != expected {
  1557  		t.Fatalf("bad:\n%s", actual)
  1558  	}
  1559  }
  1560  
  1561  func TestContext2Plan_targeted(t *testing.T) {
  1562  	m := testModule(t, "plan-targeted")
  1563  	p := testProvider("aws")
  1564  	p.DiffFn = testDiffFn
  1565  	ctx := testContext2(t, &ContextOpts{
  1566  		Module: m,
  1567  		Providers: map[string]ResourceProviderFactory{
  1568  			"aws": testProviderFuncFixed(p),
  1569  		},
  1570  		Targets: []string{"aws_instance.foo"},
  1571  	})
  1572  
  1573  	plan, err := ctx.Plan()
  1574  	if err != nil {
  1575  		t.Fatalf("err: %s", err)
  1576  	}
  1577  
  1578  	actual := strings.TrimSpace(plan.String())
  1579  	expected := strings.TrimSpace(`
  1580  DIFF:
  1581  
  1582  CREATE: aws_instance.foo
  1583    num:  "" => "2"
  1584    type: "" => "aws_instance"
  1585  
  1586  STATE:
  1587  
  1588  <no state>
  1589  	`)
  1590  	if actual != expected {
  1591  		t.Fatalf("expected:\n%s\n\ngot:\n%s", expected, actual)
  1592  	}
  1593  }
  1594  
  1595  func TestContext2Plan_provider(t *testing.T) {
  1596  	m := testModule(t, "plan-provider")
  1597  	p := testProvider("aws")
  1598  	p.DiffFn = testDiffFn
  1599  
  1600  	var value interface{}
  1601  	p.ConfigureFn = func(c *ResourceConfig) error {
  1602  		value, _ = c.Get("foo")
  1603  		return nil
  1604  	}
  1605  
  1606  	ctx := testContext2(t, &ContextOpts{
  1607  		Module: m,
  1608  		Providers: map[string]ResourceProviderFactory{
  1609  			"aws": testProviderFuncFixed(p),
  1610  		},
  1611  		Variables: map[string]string{
  1612  			"foo": "bar",
  1613  		},
  1614  	})
  1615  
  1616  	if _, err := ctx.Plan(); err != nil {
  1617  		t.Fatalf("err: %s", err)
  1618  	}
  1619  
  1620  	if value != "bar" {
  1621  		t.Fatalf("bad: %#v", value)
  1622  	}
  1623  }
  1624  
  1625  func TestContext2Plan_varMultiCountOne(t *testing.T) {
  1626  	m := testModule(t, "plan-var-multi-count-one")
  1627  	p := testProvider("aws")
  1628  	p.DiffFn = testDiffFn
  1629  	ctx := testContext2(t, &ContextOpts{
  1630  		Module: m,
  1631  		Providers: map[string]ResourceProviderFactory{
  1632  			"aws": testProviderFuncFixed(p),
  1633  		},
  1634  	})
  1635  
  1636  	plan, err := ctx.Plan()
  1637  	if err != nil {
  1638  		t.Fatalf("err: %s", err)
  1639  	}
  1640  
  1641  	actual := strings.TrimSpace(plan.String())
  1642  	expected := strings.TrimSpace(testTerraformPlanVarMultiCountOneStr)
  1643  	if actual != expected {
  1644  		t.Fatalf("bad:\n%s", actual)
  1645  	}
  1646  }
  1647  
  1648  func TestContext2Plan_varListErr(t *testing.T) {
  1649  	m := testModule(t, "plan-var-list-err")
  1650  	p := testProvider("aws")
  1651  	ctx := testContext2(t, &ContextOpts{
  1652  		Module: m,
  1653  		Providers: map[string]ResourceProviderFactory{
  1654  			"aws": testProviderFuncFixed(p),
  1655  		},
  1656  	})
  1657  
  1658  	_, err := ctx.Plan()
  1659  	if err == nil {
  1660  		t.Fatal("should error")
  1661  	}
  1662  }
  1663  
  1664  func TestContext2Refresh(t *testing.T) {
  1665  	p := testProvider("aws")
  1666  	m := testModule(t, "refresh-basic")
  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_instance.web": &ResourceState{
  1678  							Type: "aws_instance",
  1679  							Primary: &InstanceState{
  1680  								ID: "foo",
  1681  							},
  1682  						},
  1683  					},
  1684  				},
  1685  			},
  1686  		},
  1687  	})
  1688  
  1689  	p.RefreshFn = nil
  1690  	p.RefreshReturn = &InstanceState{
  1691  		ID: "foo",
  1692  	}
  1693  
  1694  	s, err := ctx.Refresh()
  1695  	mod := s.RootModule()
  1696  	if err != nil {
  1697  		t.Fatalf("err: %s", err)
  1698  	}
  1699  	if !p.RefreshCalled {
  1700  		t.Fatal("refresh should be called")
  1701  	}
  1702  	if p.RefreshState.ID != "foo" {
  1703  		t.Fatalf("bad: %#v", p.RefreshState)
  1704  	}
  1705  	if !reflect.DeepEqual(mod.Resources["aws_instance.web"].Primary, p.RefreshReturn) {
  1706  		t.Fatalf("bad: %#v %#v", mod.Resources["aws_instance.web"], p.RefreshReturn)
  1707  	}
  1708  
  1709  	for _, r := range mod.Resources {
  1710  		if r.Type == "" {
  1711  			t.Fatalf("no type: %#v", r)
  1712  		}
  1713  	}
  1714  }
  1715  
  1716  func TestContext2Refresh_targeted(t *testing.T) {
  1717  	p := testProvider("aws")
  1718  	m := testModule(t, "refresh-targeted")
  1719  	ctx := testContext2(t, &ContextOpts{
  1720  		Module: m,
  1721  		Providers: map[string]ResourceProviderFactory{
  1722  			"aws": testProviderFuncFixed(p),
  1723  		},
  1724  		State: &State{
  1725  			Modules: []*ModuleState{
  1726  				&ModuleState{
  1727  					Path: rootModulePath,
  1728  					Resources: map[string]*ResourceState{
  1729  						"aws_vpc.metoo":      resourceState("aws_vpc", "vpc-abc123"),
  1730  						"aws_instance.notme": resourceState("aws_instance", "i-bcd345"),
  1731  						"aws_instance.me":    resourceState("aws_instance", "i-abc123"),
  1732  						"aws_elb.meneither":  resourceState("aws_elb", "lb-abc123"),
  1733  					},
  1734  				},
  1735  			},
  1736  		},
  1737  		Targets: []string{"aws_instance.me"},
  1738  	})
  1739  
  1740  	refreshedResources := make([]string, 0, 2)
  1741  	p.RefreshFn = func(i *InstanceInfo, is *InstanceState) (*InstanceState, error) {
  1742  		refreshedResources = append(refreshedResources, i.Id)
  1743  		return is, nil
  1744  	}
  1745  
  1746  	_, err := ctx.Refresh()
  1747  	if err != nil {
  1748  		t.Fatalf("err: %s", err)
  1749  	}
  1750  
  1751  	expected := []string{"aws_vpc.metoo", "aws_instance.me"}
  1752  	if !reflect.DeepEqual(refreshedResources, expected) {
  1753  		t.Fatalf("expected: %#v, got: %#v", expected, refreshedResources)
  1754  	}
  1755  }
  1756  
  1757  func TestContext2Refresh_targetedCount(t *testing.T) {
  1758  	p := testProvider("aws")
  1759  	m := testModule(t, "refresh-targeted-count")
  1760  	ctx := testContext2(t, &ContextOpts{
  1761  		Module: m,
  1762  		Providers: map[string]ResourceProviderFactory{
  1763  			"aws": testProviderFuncFixed(p),
  1764  		},
  1765  		State: &State{
  1766  			Modules: []*ModuleState{
  1767  				&ModuleState{
  1768  					Path: rootModulePath,
  1769  					Resources: map[string]*ResourceState{
  1770  						"aws_vpc.metoo":      resourceState("aws_vpc", "vpc-abc123"),
  1771  						"aws_instance.notme": resourceState("aws_instance", "i-bcd345"),
  1772  						"aws_instance.me.0":  resourceState("aws_instance", "i-abc123"),
  1773  						"aws_instance.me.1":  resourceState("aws_instance", "i-cde567"),
  1774  						"aws_instance.me.2":  resourceState("aws_instance", "i-cde789"),
  1775  						"aws_elb.meneither":  resourceState("aws_elb", "lb-abc123"),
  1776  					},
  1777  				},
  1778  			},
  1779  		},
  1780  		Targets: []string{"aws_instance.me"},
  1781  	})
  1782  
  1783  	refreshedResources := make([]string, 0, 2)
  1784  	p.RefreshFn = func(i *InstanceInfo, is *InstanceState) (*InstanceState, error) {
  1785  		refreshedResources = append(refreshedResources, i.Id)
  1786  		return is, nil
  1787  	}
  1788  
  1789  	_, err := ctx.Refresh()
  1790  	if err != nil {
  1791  		t.Fatalf("err: %s", err)
  1792  	}
  1793  
  1794  	// Target didn't specify index, so we should get all our instances
  1795  	expected := []string{
  1796  		"aws_vpc.metoo",
  1797  		"aws_instance.me.0",
  1798  		"aws_instance.me.1",
  1799  		"aws_instance.me.2",
  1800  	}
  1801  	sort.Strings(expected)
  1802  	sort.Strings(refreshedResources)
  1803  	if !reflect.DeepEqual(refreshedResources, expected) {
  1804  		t.Fatalf("expected: %#v, got: %#v", expected, refreshedResources)
  1805  	}
  1806  }
  1807  
  1808  func TestContext2Refresh_targetedCountIndex(t *testing.T) {
  1809  	p := testProvider("aws")
  1810  	m := testModule(t, "refresh-targeted-count")
  1811  	ctx := testContext2(t, &ContextOpts{
  1812  		Module: m,
  1813  		Providers: map[string]ResourceProviderFactory{
  1814  			"aws": testProviderFuncFixed(p),
  1815  		},
  1816  		State: &State{
  1817  			Modules: []*ModuleState{
  1818  				&ModuleState{
  1819  					Path: rootModulePath,
  1820  					Resources: map[string]*ResourceState{
  1821  						"aws_vpc.metoo":      resourceState("aws_vpc", "vpc-abc123"),
  1822  						"aws_instance.notme": resourceState("aws_instance", "i-bcd345"),
  1823  						"aws_instance.me.0":  resourceState("aws_instance", "i-abc123"),
  1824  						"aws_instance.me.1":  resourceState("aws_instance", "i-cde567"),
  1825  						"aws_instance.me.2":  resourceState("aws_instance", "i-cde789"),
  1826  						"aws_elb.meneither":  resourceState("aws_elb", "lb-abc123"),
  1827  					},
  1828  				},
  1829  			},
  1830  		},
  1831  		Targets: []string{"aws_instance.me[0]"},
  1832  	})
  1833  
  1834  	refreshedResources := make([]string, 0, 2)
  1835  	p.RefreshFn = func(i *InstanceInfo, is *InstanceState) (*InstanceState, error) {
  1836  		refreshedResources = append(refreshedResources, i.Id)
  1837  		return is, nil
  1838  	}
  1839  
  1840  	_, err := ctx.Refresh()
  1841  	if err != nil {
  1842  		t.Fatalf("err: %s", err)
  1843  	}
  1844  
  1845  	expected := []string{"aws_vpc.metoo", "aws_instance.me.0"}
  1846  	if !reflect.DeepEqual(refreshedResources, expected) {
  1847  		t.Fatalf("expected: %#v, got: %#v", expected, refreshedResources)
  1848  	}
  1849  }
  1850  
  1851  func TestContext2Refresh_delete(t *testing.T) {
  1852  	p := testProvider("aws")
  1853  	m := testModule(t, "refresh-basic")
  1854  	ctx := testContext2(t, &ContextOpts{
  1855  		Module: m,
  1856  		Providers: map[string]ResourceProviderFactory{
  1857  			"aws": testProviderFuncFixed(p),
  1858  		},
  1859  		State: &State{
  1860  			Modules: []*ModuleState{
  1861  				&ModuleState{
  1862  					Path: rootModulePath,
  1863  					Resources: map[string]*ResourceState{
  1864  						"aws_instance.web": &ResourceState{
  1865  							Type: "aws_instance",
  1866  							Primary: &InstanceState{
  1867  								ID: "foo",
  1868  							},
  1869  						},
  1870  					},
  1871  				},
  1872  			},
  1873  		},
  1874  	})
  1875  
  1876  	p.RefreshFn = nil
  1877  	p.RefreshReturn = nil
  1878  
  1879  	s, err := ctx.Refresh()
  1880  	if err != nil {
  1881  		t.Fatalf("err: %s", err)
  1882  	}
  1883  
  1884  	mod := s.RootModule()
  1885  	if len(mod.Resources) > 0 {
  1886  		t.Fatal("resources should be empty")
  1887  	}
  1888  }
  1889  
  1890  func TestContext2Refresh_ignoreUncreated(t *testing.T) {
  1891  	p := testProvider("aws")
  1892  	m := testModule(t, "refresh-basic")
  1893  	ctx := testContext2(t, &ContextOpts{
  1894  		Module: m,
  1895  		Providers: map[string]ResourceProviderFactory{
  1896  			"aws": testProviderFuncFixed(p),
  1897  		},
  1898  		State: nil,
  1899  	})
  1900  
  1901  	p.RefreshFn = nil
  1902  	p.RefreshReturn = &InstanceState{
  1903  		ID: "foo",
  1904  	}
  1905  
  1906  	_, err := ctx.Refresh()
  1907  	if err != nil {
  1908  		t.Fatalf("err: %s", err)
  1909  	}
  1910  	if p.RefreshCalled {
  1911  		t.Fatal("refresh should not be called")
  1912  	}
  1913  }
  1914  
  1915  func TestContext2Refresh_hook(t *testing.T) {
  1916  	h := new(MockHook)
  1917  	p := testProvider("aws")
  1918  	m := testModule(t, "refresh-basic")
  1919  	ctx := testContext2(t, &ContextOpts{
  1920  		Module: m,
  1921  		Hooks:  []Hook{h},
  1922  		Providers: map[string]ResourceProviderFactory{
  1923  			"aws": testProviderFuncFixed(p),
  1924  		},
  1925  		State: &State{
  1926  			Modules: []*ModuleState{
  1927  				&ModuleState{
  1928  					Path: rootModulePath,
  1929  					Resources: map[string]*ResourceState{
  1930  						"aws_instance.web": &ResourceState{
  1931  							Type: "aws_instance",
  1932  							Primary: &InstanceState{
  1933  								ID: "foo",
  1934  							},
  1935  						},
  1936  					},
  1937  				},
  1938  			},
  1939  		},
  1940  	})
  1941  
  1942  	if _, err := ctx.Refresh(); err != nil {
  1943  		t.Fatalf("err: %s", err)
  1944  	}
  1945  	if !h.PreRefreshCalled {
  1946  		t.Fatal("should be called")
  1947  	}
  1948  	if !h.PostRefreshCalled {
  1949  		t.Fatal("should be called")
  1950  	}
  1951  }
  1952  
  1953  func TestContext2Refresh_modules(t *testing.T) {
  1954  	p := testProvider("aws")
  1955  	m := testModule(t, "refresh-modules")
  1956  	state := &State{
  1957  		Modules: []*ModuleState{
  1958  			&ModuleState{
  1959  				Path: rootModulePath,
  1960  				Resources: map[string]*ResourceState{
  1961  					"aws_instance.web": &ResourceState{
  1962  						Type: "aws_instance",
  1963  						Tainted: []*InstanceState{
  1964  							&InstanceState{
  1965  								ID: "bar",
  1966  							},
  1967  						},
  1968  					},
  1969  				},
  1970  			},
  1971  
  1972  			&ModuleState{
  1973  				Path: []string{"root", "child"},
  1974  				Resources: map[string]*ResourceState{
  1975  					"aws_instance.web": &ResourceState{
  1976  						Type: "aws_instance",
  1977  						Primary: &InstanceState{
  1978  							ID: "baz",
  1979  						},
  1980  					},
  1981  				},
  1982  			},
  1983  		},
  1984  	}
  1985  	ctx := testContext2(t, &ContextOpts{
  1986  		Module: m,
  1987  		Providers: map[string]ResourceProviderFactory{
  1988  			"aws": testProviderFuncFixed(p),
  1989  		},
  1990  		State: state,
  1991  	})
  1992  
  1993  	p.RefreshFn = func(info *InstanceInfo, s *InstanceState) (*InstanceState, error) {
  1994  		if s.ID != "baz" {
  1995  			return s, nil
  1996  		}
  1997  
  1998  		s.ID = "new"
  1999  		return s, nil
  2000  	}
  2001  
  2002  	s, err := ctx.Refresh()
  2003  	if err != nil {
  2004  		t.Fatalf("err: %s", err)
  2005  	}
  2006  
  2007  	actual := strings.TrimSpace(s.String())
  2008  	expected := strings.TrimSpace(testContextRefreshModuleStr)
  2009  	if actual != expected {
  2010  		t.Fatalf("bad:\n\n%s\n\n%s", actual, expected)
  2011  	}
  2012  }
  2013  
  2014  func TestContext2Refresh_moduleInputComputedOutput(t *testing.T) {
  2015  	m := testModule(t, "refresh-module-input-computed-output")
  2016  	p := testProvider("aws")
  2017  	p.DiffFn = testDiffFn
  2018  	ctx := testContext2(t, &ContextOpts{
  2019  		Module: m,
  2020  		Providers: map[string]ResourceProviderFactory{
  2021  			"aws": testProviderFuncFixed(p),
  2022  		},
  2023  	})
  2024  
  2025  	if _, err := ctx.Refresh(); err != nil {
  2026  		t.Fatalf("err: %s", err)
  2027  	}
  2028  }
  2029  
  2030  func TestContext2Refresh_moduleVarModule(t *testing.T) {
  2031  	m := testModule(t, "refresh-module-var-module")
  2032  	p := testProvider("aws")
  2033  	p.DiffFn = testDiffFn
  2034  	ctx := testContext2(t, &ContextOpts{
  2035  		Module: m,
  2036  		Providers: map[string]ResourceProviderFactory{
  2037  			"aws": testProviderFuncFixed(p),
  2038  		},
  2039  	})
  2040  
  2041  	if _, err := ctx.Refresh(); err != nil {
  2042  		t.Fatalf("err: %s", err)
  2043  	}
  2044  }
  2045  
  2046  // GH-70
  2047  func TestContext2Refresh_noState(t *testing.T) {
  2048  	p := testProvider("aws")
  2049  	m := testModule(t, "refresh-no-state")
  2050  	ctx := testContext2(t, &ContextOpts{
  2051  		Module: m,
  2052  		Providers: map[string]ResourceProviderFactory{
  2053  			"aws": testProviderFuncFixed(p),
  2054  		},
  2055  	})
  2056  
  2057  	p.RefreshFn = nil
  2058  	p.RefreshReturn = &InstanceState{
  2059  		ID: "foo",
  2060  	}
  2061  
  2062  	if _, err := ctx.Refresh(); err != nil {
  2063  		t.Fatalf("err: %s", err)
  2064  	}
  2065  }
  2066  
  2067  func TestContext2Refresh_output(t *testing.T) {
  2068  	p := testProvider("aws")
  2069  	m := testModule(t, "refresh-output")
  2070  	ctx := testContext2(t, &ContextOpts{
  2071  		Module: m,
  2072  		Providers: map[string]ResourceProviderFactory{
  2073  			"aws": testProviderFuncFixed(p),
  2074  		},
  2075  		State: &State{
  2076  			Modules: []*ModuleState{
  2077  				&ModuleState{
  2078  					Path: rootModulePath,
  2079  					Resources: map[string]*ResourceState{
  2080  						"aws_instance.web": &ResourceState{
  2081  							Type: "aws_instance",
  2082  							Primary: &InstanceState{
  2083  								ID: "foo",
  2084  								Attributes: map[string]string{
  2085  									"foo": "bar",
  2086  								},
  2087  							},
  2088  						},
  2089  					},
  2090  
  2091  					Outputs: map[string]string{
  2092  						"foo": "foo",
  2093  					},
  2094  				},
  2095  			},
  2096  		},
  2097  	})
  2098  
  2099  	p.RefreshFn = func(info *InstanceInfo, s *InstanceState) (*InstanceState, error) {
  2100  		return s, nil
  2101  	}
  2102  
  2103  	s, err := ctx.Refresh()
  2104  	if err != nil {
  2105  		t.Fatalf("err: %s", err)
  2106  	}
  2107  
  2108  	actual := strings.TrimSpace(s.String())
  2109  	expected := strings.TrimSpace(testContextRefreshOutputStr)
  2110  	if actual != expected {
  2111  		t.Fatalf("bad:\n\n%s\n\n%s", actual, expected)
  2112  	}
  2113  }
  2114  
  2115  func TestContext2Refresh_outputPartial(t *testing.T) {
  2116  	p := testProvider("aws")
  2117  	m := testModule(t, "refresh-output-partial")
  2118  	ctx := testContext2(t, &ContextOpts{
  2119  		Module: m,
  2120  		Providers: map[string]ResourceProviderFactory{
  2121  			"aws": testProviderFuncFixed(p),
  2122  		},
  2123  		State: &State{
  2124  			Modules: []*ModuleState{
  2125  				&ModuleState{
  2126  					Path: rootModulePath,
  2127  					Resources: map[string]*ResourceState{
  2128  						"aws_instance.foo": &ResourceState{
  2129  							Type: "aws_instance",
  2130  							Primary: &InstanceState{
  2131  								ID: "foo",
  2132  							},
  2133  						},
  2134  					},
  2135  				},
  2136  			},
  2137  		},
  2138  	})
  2139  
  2140  	p.RefreshFn = nil
  2141  	p.RefreshReturn = nil
  2142  
  2143  	s, err := ctx.Refresh()
  2144  	if err != nil {
  2145  		t.Fatalf("err: %s", err)
  2146  	}
  2147  
  2148  	actual := strings.TrimSpace(s.String())
  2149  	expected := strings.TrimSpace(testContextRefreshOutputPartialStr)
  2150  	if actual != expected {
  2151  		t.Fatalf("bad:\n\n%s\n\n%s", actual, expected)
  2152  	}
  2153  }
  2154  
  2155  func TestContext2Refresh_state(t *testing.T) {
  2156  	p := testProvider("aws")
  2157  	m := testModule(t, "refresh-basic")
  2158  	state := &State{
  2159  		Modules: []*ModuleState{
  2160  			&ModuleState{
  2161  				Path: rootModulePath,
  2162  				Resources: map[string]*ResourceState{
  2163  					"aws_instance.web": &ResourceState{
  2164  						Primary: &InstanceState{
  2165  							ID: "bar",
  2166  						},
  2167  					},
  2168  				},
  2169  			},
  2170  		},
  2171  	}
  2172  	ctx := testContext2(t, &ContextOpts{
  2173  		Module: m,
  2174  		Providers: map[string]ResourceProviderFactory{
  2175  			"aws": testProviderFuncFixed(p),
  2176  		},
  2177  		State: state,
  2178  	})
  2179  
  2180  	p.RefreshFn = nil
  2181  	p.RefreshReturn = &InstanceState{
  2182  		ID: "foo",
  2183  	}
  2184  
  2185  	s, err := ctx.Refresh()
  2186  	if err != nil {
  2187  		t.Fatalf("err: %s", err)
  2188  	}
  2189  	originalMod := state.RootModule()
  2190  	mod := s.RootModule()
  2191  	if !p.RefreshCalled {
  2192  		t.Fatal("refresh should be called")
  2193  	}
  2194  	if !reflect.DeepEqual(p.RefreshState, originalMod.Resources["aws_instance.web"].Primary) {
  2195  		t.Fatalf(
  2196  			"bad:\n\n%#v\n\n%#v",
  2197  			p.RefreshState,
  2198  			originalMod.Resources["aws_instance.web"].Primary)
  2199  	}
  2200  	if !reflect.DeepEqual(mod.Resources["aws_instance.web"].Primary, p.RefreshReturn) {
  2201  		t.Fatalf("bad: %#v", mod.Resources)
  2202  	}
  2203  }
  2204  
  2205  func TestContext2Refresh_tainted(t *testing.T) {
  2206  	p := testProvider("aws")
  2207  	m := testModule(t, "refresh-basic")
  2208  	state := &State{
  2209  		Modules: []*ModuleState{
  2210  			&ModuleState{
  2211  				Path: rootModulePath,
  2212  				Resources: map[string]*ResourceState{
  2213  					"aws_instance.web": &ResourceState{
  2214  						Type: "aws_instance",
  2215  						Tainted: []*InstanceState{
  2216  							&InstanceState{
  2217  								ID: "bar",
  2218  							},
  2219  						},
  2220  					},
  2221  				},
  2222  			},
  2223  		},
  2224  	}
  2225  	ctx := testContext2(t, &ContextOpts{
  2226  		Module: m,
  2227  		Providers: map[string]ResourceProviderFactory{
  2228  			"aws": testProviderFuncFixed(p),
  2229  		},
  2230  		State: state,
  2231  	})
  2232  
  2233  	p.RefreshFn = nil
  2234  	p.RefreshReturn = &InstanceState{
  2235  		ID: "foo",
  2236  	}
  2237  
  2238  	s, err := ctx.Refresh()
  2239  	if err != nil {
  2240  		t.Fatalf("err: %s", err)
  2241  	}
  2242  	if !p.RefreshCalled {
  2243  		t.Fatal("refresh should be called")
  2244  	}
  2245  
  2246  	actual := strings.TrimSpace(s.String())
  2247  	expected := strings.TrimSpace(testContextRefreshTaintedStr)
  2248  	if actual != expected {
  2249  		t.Fatalf("bad:\n\n%s\n\n%s", actual, expected)
  2250  	}
  2251  }
  2252  
  2253  // Doing a Refresh (or any operation really, but Refresh usually
  2254  // happens first) with a config with an unknown provider should result in
  2255  // an error. The key bug this found was that this wasn't happening if
  2256  // Providers was _empty_.
  2257  func TestContext2Refresh_unknownProvider(t *testing.T) {
  2258  	m := testModule(t, "refresh-unknown-provider")
  2259  	p := testProvider("aws")
  2260  	p.ApplyFn = testApplyFn
  2261  	p.DiffFn = testDiffFn
  2262  	ctx := testContext2(t, &ContextOpts{
  2263  		Module:    m,
  2264  		Providers: map[string]ResourceProviderFactory{},
  2265  	})
  2266  
  2267  	if _, err := ctx.Refresh(); err == nil {
  2268  		t.Fatal("should error")
  2269  	}
  2270  }
  2271  
  2272  func TestContext2Refresh_vars(t *testing.T) {
  2273  	p := testProvider("aws")
  2274  	m := testModule(t, "refresh-vars")
  2275  	ctx := testContext2(t, &ContextOpts{
  2276  		Module: m,
  2277  		Providers: map[string]ResourceProviderFactory{
  2278  			"aws": testProviderFuncFixed(p),
  2279  		},
  2280  		State: &State{
  2281  
  2282  			Modules: []*ModuleState{
  2283  				&ModuleState{
  2284  					Path: rootModulePath,
  2285  					Resources: map[string]*ResourceState{
  2286  						"aws_instance.web": &ResourceState{
  2287  							Type: "aws_instance",
  2288  							Primary: &InstanceState{
  2289  								ID: "foo",
  2290  							},
  2291  						},
  2292  					},
  2293  				},
  2294  			},
  2295  		},
  2296  	})
  2297  
  2298  	p.RefreshFn = nil
  2299  	p.RefreshReturn = &InstanceState{
  2300  		ID: "foo",
  2301  	}
  2302  
  2303  	s, err := ctx.Refresh()
  2304  	if err != nil {
  2305  		t.Fatalf("err: %s", err)
  2306  	}
  2307  	mod := s.RootModule()
  2308  	if !p.RefreshCalled {
  2309  		t.Fatal("refresh should be called")
  2310  	}
  2311  	if p.RefreshState.ID != "foo" {
  2312  		t.Fatalf("bad: %#v", p.RefreshState)
  2313  	}
  2314  	if !reflect.DeepEqual(mod.Resources["aws_instance.web"].Primary, p.RefreshReturn) {
  2315  		t.Fatalf("bad: %#v", mod.Resources["aws_instance.web"])
  2316  	}
  2317  
  2318  	for _, r := range mod.Resources {
  2319  		if r.Type == "" {
  2320  			t.Fatalf("no type: %#v", r)
  2321  		}
  2322  	}
  2323  }
  2324  
  2325  func TestContext2Validate(t *testing.T) {
  2326  	p := testProvider("aws")
  2327  	m := testModule(t, "validate-good")
  2328  	c := testContext2(t, &ContextOpts{
  2329  		Module: m,
  2330  		Providers: map[string]ResourceProviderFactory{
  2331  			"aws": testProviderFuncFixed(p),
  2332  		},
  2333  	})
  2334  
  2335  	w, e := c.Validate()
  2336  	if len(w) > 0 {
  2337  		t.Fatalf("bad: %#v", w)
  2338  	}
  2339  	if len(e) > 0 {
  2340  		t.Fatalf("bad: %s", e)
  2341  	}
  2342  }
  2343  
  2344  func TestContext2Validate_badVar(t *testing.T) {
  2345  	p := testProvider("aws")
  2346  	m := testModule(t, "validate-bad-var")
  2347  	c := testContext2(t, &ContextOpts{
  2348  		Module: m,
  2349  		Providers: map[string]ResourceProviderFactory{
  2350  			"aws": testProviderFuncFixed(p),
  2351  		},
  2352  	})
  2353  
  2354  	w, e := c.Validate()
  2355  	if len(w) > 0 {
  2356  		t.Fatalf("bad: %#v", w)
  2357  	}
  2358  	if len(e) == 0 {
  2359  		t.Fatalf("bad: %#v", e)
  2360  	}
  2361  }
  2362  
  2363  func TestContext2Validate_countNegative(t *testing.T) {
  2364  	p := testProvider("aws")
  2365  	m := testModule(t, "validate-count-negative")
  2366  	c := testContext2(t, &ContextOpts{
  2367  		Module: m,
  2368  		Providers: map[string]ResourceProviderFactory{
  2369  			"aws": testProviderFuncFixed(p),
  2370  		},
  2371  	})
  2372  
  2373  	w, e := c.Validate()
  2374  	if len(w) > 0 {
  2375  		t.Fatalf("bad: %#v", w)
  2376  	}
  2377  	if len(e) == 0 {
  2378  		t.Fatalf("bad: %#v", e)
  2379  	}
  2380  }
  2381  
  2382  func TestContext2Validate_countVariable(t *testing.T) {
  2383  	p := testProvider("aws")
  2384  	m := testModule(t, "apply-count-variable")
  2385  	c := testContext2(t, &ContextOpts{
  2386  		Module: m,
  2387  		Providers: map[string]ResourceProviderFactory{
  2388  			"aws": testProviderFuncFixed(p),
  2389  		},
  2390  	})
  2391  
  2392  	w, e := c.Validate()
  2393  	if len(w) > 0 {
  2394  		t.Fatalf("bad: %#v", w)
  2395  	}
  2396  	if len(e) > 0 {
  2397  		t.Fatalf("bad: %s", e)
  2398  	}
  2399  }
  2400  
  2401  func TestContext2Validate_countVariableNoDefault(t *testing.T) {
  2402  	p := testProvider("aws")
  2403  	m := testModule(t, "validate-count-variable")
  2404  	c := testContext2(t, &ContextOpts{
  2405  		Module: m,
  2406  		Providers: map[string]ResourceProviderFactory{
  2407  			"aws": testProviderFuncFixed(p),
  2408  		},
  2409  	})
  2410  
  2411  	w, e := c.Validate()
  2412  	if len(w) > 0 {
  2413  		t.Fatalf("bad: %#v", w)
  2414  	}
  2415  	if len(e) != 1 {
  2416  		t.Fatalf("bad: %s", e)
  2417  	}
  2418  }
  2419  
  2420  /*
  2421  TODO: What should we do here?
  2422  func TestContext2Validate_cycle(t *testing.T) {
  2423  	p := testProvider("aws")
  2424  	m := testModule(t, "validate-cycle")
  2425  	c := testContext2(t, &ContextOpts{
  2426  		Module: m,
  2427  		Providers: map[string]ResourceProviderFactory{
  2428  			"aws": testProviderFuncFixed(p),
  2429  		},
  2430  	})
  2431  
  2432  	w, e := c.Validate()
  2433  	if len(w) > 0 {
  2434  		t.Fatalf("expected no warns, got: %#v", w)
  2435  	}
  2436  	if len(e) != 1 {
  2437  		t.Fatalf("expected 1 err, got: %s", e)
  2438  	}
  2439  }
  2440  */
  2441  
  2442  func TestContext2Validate_moduleBadOutput(t *testing.T) {
  2443  	p := testProvider("aws")
  2444  	m := testModule(t, "validate-bad-module-output")
  2445  	c := testContext2(t, &ContextOpts{
  2446  		Module: m,
  2447  		Providers: map[string]ResourceProviderFactory{
  2448  			"aws": testProviderFuncFixed(p),
  2449  		},
  2450  	})
  2451  
  2452  	w, e := c.Validate()
  2453  	if len(w) > 0 {
  2454  		t.Fatalf("bad: %#v", w)
  2455  	}
  2456  	if len(e) == 0 {
  2457  		t.Fatalf("bad: %s", e)
  2458  	}
  2459  }
  2460  
  2461  func TestContext2Validate_moduleGood(t *testing.T) {
  2462  	p := testProvider("aws")
  2463  	m := testModule(t, "validate-good-module")
  2464  	c := testContext2(t, &ContextOpts{
  2465  		Module: m,
  2466  		Providers: map[string]ResourceProviderFactory{
  2467  			"aws": testProviderFuncFixed(p),
  2468  		},
  2469  	})
  2470  
  2471  	w, e := c.Validate()
  2472  	if len(w) > 0 {
  2473  		t.Fatalf("bad: %#v", w)
  2474  	}
  2475  	if len(e) > 0 {
  2476  		t.Fatalf("bad: %#v", e)
  2477  	}
  2478  }
  2479  
  2480  func TestContext2Validate_moduleBadResource(t *testing.T) {
  2481  	m := testModule(t, "validate-module-bad-rc")
  2482  	p := testProvider("aws")
  2483  	c := testContext2(t, &ContextOpts{
  2484  		Module: m,
  2485  		Providers: map[string]ResourceProviderFactory{
  2486  			"aws": testProviderFuncFixed(p),
  2487  		},
  2488  	})
  2489  
  2490  	p.ValidateResourceReturnErrors = []error{fmt.Errorf("bad")}
  2491  
  2492  	w, e := c.Validate()
  2493  	if len(w) > 0 {
  2494  		t.Fatalf("bad: %#v", w)
  2495  	}
  2496  	if len(e) == 0 {
  2497  		t.Fatalf("bad: %#v", e)
  2498  	}
  2499  }
  2500  
  2501  func TestContext2Validate_moduleDepsShouldNotCycle(t *testing.T) {
  2502  	m := testModule(t, "validate-module-deps-cycle")
  2503  	p := testProvider("aws")
  2504  	ctx := testContext2(t, &ContextOpts{
  2505  		Module: m,
  2506  		Providers: map[string]ResourceProviderFactory{
  2507  			"aws": testProviderFuncFixed(p),
  2508  		},
  2509  	})
  2510  
  2511  	w, e := ctx.Validate()
  2512  
  2513  	if len(w) > 0 {
  2514  		t.Fatalf("expected no warnings, got: %s", w)
  2515  	}
  2516  	if len(e) > 0 {
  2517  		t.Fatalf("expected no errors, got: %s", e)
  2518  	}
  2519  }
  2520  
  2521  func TestContext2Validate_moduleProviderInherit(t *testing.T) {
  2522  	m := testModule(t, "validate-module-pc-inherit")
  2523  	p := testProvider("aws")
  2524  	c := testContext2(t, &ContextOpts{
  2525  		Module: m,
  2526  		Providers: map[string]ResourceProviderFactory{
  2527  			"aws": testProviderFuncFixed(p),
  2528  		},
  2529  	})
  2530  
  2531  	p.ValidateFn = func(c *ResourceConfig) ([]string, []error) {
  2532  		return nil, c.CheckSet([]string{"set"})
  2533  	}
  2534  
  2535  	w, e := c.Validate()
  2536  	if len(w) > 0 {
  2537  		t.Fatalf("bad: %#v", w)
  2538  	}
  2539  	if len(e) > 0 {
  2540  		t.Fatalf("bad: %s", e)
  2541  	}
  2542  }
  2543  
  2544  func TestContext2Validate_moduleProviderVar(t *testing.T) {
  2545  	m := testModule(t, "validate-module-pc-vars")
  2546  	p := testProvider("aws")
  2547  	c := testContext2(t, &ContextOpts{
  2548  		Module: m,
  2549  		Providers: map[string]ResourceProviderFactory{
  2550  			"aws": testProviderFuncFixed(p),
  2551  		},
  2552  		Variables: map[string]string{
  2553  			"provider_var": "bar",
  2554  		},
  2555  	})
  2556  
  2557  	p.ValidateFn = func(c *ResourceConfig) ([]string, []error) {
  2558  		return nil, c.CheckSet([]string{"foo"})
  2559  	}
  2560  
  2561  	w, e := c.Validate()
  2562  	if len(w) > 0 {
  2563  		t.Fatalf("bad: %#v", w)
  2564  	}
  2565  	if len(e) > 0 {
  2566  		t.Fatalf("bad: %s", e)
  2567  	}
  2568  }
  2569  
  2570  func TestContext2Validate_moduleProviderInheritUnused(t *testing.T) {
  2571  	m := testModule(t, "validate-module-pc-inherit-unused")
  2572  	p := testProvider("aws")
  2573  	c := testContext2(t, &ContextOpts{
  2574  		Module: m,
  2575  		Providers: map[string]ResourceProviderFactory{
  2576  			"aws": testProviderFuncFixed(p),
  2577  		},
  2578  	})
  2579  
  2580  	p.ValidateFn = func(c *ResourceConfig) ([]string, []error) {
  2581  		return nil, c.CheckSet([]string{"foo"})
  2582  	}
  2583  
  2584  	w, e := c.Validate()
  2585  	if len(w) > 0 {
  2586  		t.Fatalf("bad: %#v", w)
  2587  	}
  2588  	if len(e) > 0 {
  2589  		t.Fatalf("bad: %s", e)
  2590  	}
  2591  }
  2592  
  2593  func TestContext2Validate_orphans(t *testing.T) {
  2594  	p := testProvider("aws")
  2595  	m := testModule(t, "validate-good")
  2596  	state := &State{
  2597  		Modules: []*ModuleState{
  2598  			&ModuleState{
  2599  				Path: rootModulePath,
  2600  				Resources: map[string]*ResourceState{
  2601  					"aws_instance.web": &ResourceState{
  2602  						Type: "aws_instance",
  2603  						Primary: &InstanceState{
  2604  							ID: "bar",
  2605  						},
  2606  					},
  2607  				},
  2608  			},
  2609  		},
  2610  	}
  2611  	c := testContext2(t, &ContextOpts{
  2612  		Module: m,
  2613  		Providers: map[string]ResourceProviderFactory{
  2614  			"aws": testProviderFuncFixed(p),
  2615  		},
  2616  		State: state,
  2617  	})
  2618  
  2619  	p.ValidateResourceFn = func(
  2620  		t string, c *ResourceConfig) ([]string, []error) {
  2621  		return nil, c.CheckSet([]string{"foo"})
  2622  	}
  2623  
  2624  	w, e := c.Validate()
  2625  	if len(w) > 0 {
  2626  		t.Fatalf("bad: %#v", w)
  2627  	}
  2628  	if len(e) > 0 {
  2629  		t.Fatalf("bad: %s", e)
  2630  	}
  2631  }
  2632  
  2633  func TestContext2Validate_providerConfig_bad(t *testing.T) {
  2634  	m := testModule(t, "validate-bad-pc")
  2635  	p := testProvider("aws")
  2636  	c := testContext2(t, &ContextOpts{
  2637  		Module: m,
  2638  		Providers: map[string]ResourceProviderFactory{
  2639  			"aws": testProviderFuncFixed(p),
  2640  		},
  2641  	})
  2642  
  2643  	p.ValidateReturnErrors = []error{fmt.Errorf("bad")}
  2644  
  2645  	w, e := c.Validate()
  2646  	if len(w) > 0 {
  2647  		t.Fatalf("bad: %#v", w)
  2648  	}
  2649  	if len(e) == 0 {
  2650  		t.Fatalf("bad: %s", e)
  2651  	}
  2652  	if !strings.Contains(fmt.Sprintf("%s", e), "bad") {
  2653  		t.Fatalf("bad: %s", e)
  2654  	}
  2655  }
  2656  
  2657  func TestContext2Validate_providerConfig_badEmpty(t *testing.T) {
  2658  	m := testModule(t, "validate-bad-pc-empty")
  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  	p.ValidateReturnErrors = []error{fmt.Errorf("bad")}
  2668  
  2669  	w, e := c.Validate()
  2670  	if len(w) > 0 {
  2671  		t.Fatalf("bad: %#v", w)
  2672  	}
  2673  	if len(e) == 0 {
  2674  		t.Fatalf("bad: %#v", e)
  2675  	}
  2676  }
  2677  
  2678  func TestContext2Validate_providerConfig_good(t *testing.T) {
  2679  	m := testModule(t, "validate-bad-pc")
  2680  	p := testProvider("aws")
  2681  	c := testContext2(t, &ContextOpts{
  2682  		Module: m,
  2683  		Providers: map[string]ResourceProviderFactory{
  2684  			"aws": testProviderFuncFixed(p),
  2685  		},
  2686  	})
  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: %#v", e)
  2694  	}
  2695  }
  2696  
  2697  func TestContext2Validate_provisionerConfig_bad(t *testing.T) {
  2698  	m := testModule(t, "validate-bad-prov-conf")
  2699  	p := testProvider("aws")
  2700  	pr := testProvisioner()
  2701  	c := testContext2(t, &ContextOpts{
  2702  		Module: m,
  2703  		Providers: map[string]ResourceProviderFactory{
  2704  			"aws": testProviderFuncFixed(p),
  2705  		},
  2706  		Provisioners: map[string]ResourceProvisionerFactory{
  2707  			"shell": testProvisionerFuncFixed(pr),
  2708  		},
  2709  	})
  2710  
  2711  	pr.ValidateReturnErrors = []error{fmt.Errorf("bad")}
  2712  
  2713  	w, e := c.Validate()
  2714  	if len(w) > 0 {
  2715  		t.Fatalf("bad: %#v", w)
  2716  	}
  2717  	if len(e) == 0 {
  2718  		t.Fatalf("bad: %#v", e)
  2719  	}
  2720  }
  2721  
  2722  func TestContext2Validate_provisionerConfig_good(t *testing.T) {
  2723  	m := testModule(t, "validate-bad-prov-conf")
  2724  	p := testProvider("aws")
  2725  	pr := testProvisioner()
  2726  	pr.ValidateFn = func(c *ResourceConfig) ([]string, []error) {
  2727  		if c == nil {
  2728  			t.Fatalf("missing resource config for provisioner")
  2729  		}
  2730  		return nil, c.CheckSet([]string{"command"})
  2731  	}
  2732  	c := testContext2(t, &ContextOpts{
  2733  		Module: m,
  2734  		Providers: map[string]ResourceProviderFactory{
  2735  			"aws": testProviderFuncFixed(p),
  2736  		},
  2737  		Provisioners: map[string]ResourceProvisionerFactory{
  2738  			"shell": testProvisionerFuncFixed(pr),
  2739  		},
  2740  	})
  2741  
  2742  	w, e := c.Validate()
  2743  	if len(w) > 0 {
  2744  		t.Fatalf("bad: %#v", w)
  2745  	}
  2746  	if len(e) > 0 {
  2747  		t.Fatalf("bad: %#v", e)
  2748  	}
  2749  }
  2750  
  2751  func TestContext2Validate_requiredVar(t *testing.T) {
  2752  	m := testModule(t, "validate-required-var")
  2753  	p := testProvider("aws")
  2754  	c := testContext2(t, &ContextOpts{
  2755  		Module: m,
  2756  		Providers: map[string]ResourceProviderFactory{
  2757  			"aws": testProviderFuncFixed(p),
  2758  		},
  2759  	})
  2760  
  2761  	w, e := c.Validate()
  2762  	if len(w) > 0 {
  2763  		t.Fatalf("bad: %#v", w)
  2764  	}
  2765  	if len(e) == 0 {
  2766  		t.Fatalf("bad: %s", e)
  2767  	}
  2768  }
  2769  
  2770  func TestContext2Validate_resourceConfig_bad(t *testing.T) {
  2771  	m := testModule(t, "validate-bad-rc")
  2772  	p := testProvider("aws")
  2773  	c := testContext2(t, &ContextOpts{
  2774  		Module: m,
  2775  		Providers: map[string]ResourceProviderFactory{
  2776  			"aws": testProviderFuncFixed(p),
  2777  		},
  2778  	})
  2779  
  2780  	p.ValidateResourceReturnErrors = []error{fmt.Errorf("bad")}
  2781  
  2782  	w, e := c.Validate()
  2783  	if len(w) > 0 {
  2784  		t.Fatalf("bad: %#v", w)
  2785  	}
  2786  	if len(e) == 0 {
  2787  		t.Fatalf("bad: %s", e)
  2788  	}
  2789  }
  2790  
  2791  func TestContext2Validate_resourceConfig_good(t *testing.T) {
  2792  	m := testModule(t, "validate-bad-rc")
  2793  	p := testProvider("aws")
  2794  	c := testContext2(t, &ContextOpts{
  2795  		Module: m,
  2796  		Providers: map[string]ResourceProviderFactory{
  2797  			"aws": testProviderFuncFixed(p),
  2798  		},
  2799  	})
  2800  
  2801  	w, e := c.Validate()
  2802  	if len(w) > 0 {
  2803  		t.Fatalf("bad: %#v", w)
  2804  	}
  2805  	if len(e) > 0 {
  2806  		t.Fatalf("bad: %#v", e)
  2807  	}
  2808  }
  2809  
  2810  func TestContext2Validate_resourceNameSymbol(t *testing.T) {
  2811  	p := testProvider("aws")
  2812  	m := testModule(t, "validate-resource-name-symbol")
  2813  	c := testContext2(t, &ContextOpts{
  2814  		Module: m,
  2815  		Providers: map[string]ResourceProviderFactory{
  2816  			"aws": testProviderFuncFixed(p),
  2817  		},
  2818  	})
  2819  
  2820  	w, e := c.Validate()
  2821  	if len(w) == 0 {
  2822  		t.Fatalf("bad: %#v", w)
  2823  	}
  2824  	if len(e) > 0 {
  2825  		t.Fatalf("bad: %s", e)
  2826  	}
  2827  }
  2828  
  2829  func TestContext2Validate_selfRef(t *testing.T) {
  2830  	p := testProvider("aws")
  2831  	m := testModule(t, "validate-self-ref")
  2832  	c := testContext2(t, &ContextOpts{
  2833  		Module: m,
  2834  		Providers: map[string]ResourceProviderFactory{
  2835  			"aws": testProviderFuncFixed(p),
  2836  		},
  2837  	})
  2838  
  2839  	w, e := c.Validate()
  2840  	if len(w) > 0 {
  2841  		t.Fatalf("bad: %#v", w)
  2842  	}
  2843  	if len(e) == 0 {
  2844  		t.Fatalf("bad: %s", e)
  2845  	}
  2846  }
  2847  
  2848  func TestContext2Validate_selfRefMulti(t *testing.T) {
  2849  	p := testProvider("aws")
  2850  	m := testModule(t, "validate-self-ref-multi")
  2851  	c := testContext2(t, &ContextOpts{
  2852  		Module: m,
  2853  		Providers: map[string]ResourceProviderFactory{
  2854  			"aws": testProviderFuncFixed(p),
  2855  		},
  2856  	})
  2857  
  2858  	w, e := c.Validate()
  2859  	if len(w) > 0 {
  2860  		t.Fatalf("bad: %#v", w)
  2861  	}
  2862  	if len(e) == 0 {
  2863  		t.Fatalf("bad: %#v", e)
  2864  	}
  2865  }
  2866  
  2867  func TestContext2Validate_selfRefMultiAll(t *testing.T) {
  2868  	p := testProvider("aws")
  2869  	m := testModule(t, "validate-self-ref-multi-all")
  2870  	c := testContext2(t, &ContextOpts{
  2871  		Module: m,
  2872  		Providers: map[string]ResourceProviderFactory{
  2873  			"aws": testProviderFuncFixed(p),
  2874  		},
  2875  	})
  2876  
  2877  	w, e := c.Validate()
  2878  	if len(w) > 0 {
  2879  		t.Fatalf("bad: %#v", w)
  2880  	}
  2881  	if len(e) == 0 {
  2882  		t.Fatalf("bad: %#v", e)
  2883  	}
  2884  }
  2885  
  2886  func TestContext2Validate_tainted(t *testing.T) {
  2887  	p := testProvider("aws")
  2888  	m := testModule(t, "validate-good")
  2889  	state := &State{
  2890  		Modules: []*ModuleState{
  2891  			&ModuleState{
  2892  				Path: rootModulePath,
  2893  				Resources: map[string]*ResourceState{
  2894  					"aws_instance.foo": &ResourceState{
  2895  						Type: "aws_instance",
  2896  						Tainted: []*InstanceState{
  2897  							&InstanceState{
  2898  								ID: "bar",
  2899  							},
  2900  						},
  2901  					},
  2902  				},
  2903  			},
  2904  		},
  2905  	}
  2906  	c := testContext2(t, &ContextOpts{
  2907  		Module: m,
  2908  		Providers: map[string]ResourceProviderFactory{
  2909  			"aws": testProviderFuncFixed(p),
  2910  		},
  2911  		State: state,
  2912  	})
  2913  
  2914  	p.ValidateResourceFn = func(
  2915  		t string, c *ResourceConfig) ([]string, []error) {
  2916  		return nil, c.CheckSet([]string{"foo"})
  2917  	}
  2918  
  2919  	w, e := c.Validate()
  2920  	if len(w) > 0 {
  2921  		t.Fatalf("bad: %#v", w)
  2922  	}
  2923  	if len(e) > 0 {
  2924  		t.Fatalf("bad: %#v", e)
  2925  	}
  2926  }
  2927  
  2928  func TestContext2Validate_targetedDestroy(t *testing.T) {
  2929  	m := testModule(t, "validate-targeted")
  2930  	p := testProvider("aws")
  2931  	pr := testProvisioner()
  2932  	p.ApplyFn = testApplyFn
  2933  	p.DiffFn = testDiffFn
  2934  	ctx := testContext2(t, &ContextOpts{
  2935  		Module: m,
  2936  		Providers: map[string]ResourceProviderFactory{
  2937  			"aws": testProviderFuncFixed(p),
  2938  		},
  2939  		Provisioners: map[string]ResourceProvisionerFactory{
  2940  			"shell": testProvisionerFuncFixed(pr),
  2941  		},
  2942  		State: &State{
  2943  			Modules: []*ModuleState{
  2944  				&ModuleState{
  2945  					Path: rootModulePath,
  2946  					Resources: map[string]*ResourceState{
  2947  						"aws_instance.foo": resourceState("aws_instance", "i-bcd345"),
  2948  						"aws_instance.bar": resourceState("aws_instance", "i-abc123"),
  2949  					},
  2950  				},
  2951  			},
  2952  		},
  2953  		Targets: []string{"aws_instance.foo"},
  2954  		Destroy: true,
  2955  	})
  2956  
  2957  	w, e := ctx.Validate()
  2958  	if len(w) > 0 {
  2959  		warnStr := ""
  2960  		for _, v := range w {
  2961  			warnStr = warnStr + " " + v
  2962  		}
  2963  		t.Fatalf("bad: %s", warnStr)
  2964  	}
  2965  	if len(e) > 0 {
  2966  		t.Fatalf("bad: %s", e)
  2967  	}
  2968  }
  2969  
  2970  func TestContext2Validate_varRef(t *testing.T) {
  2971  	m := testModule(t, "validate-variable-ref")
  2972  	p := testProvider("aws")
  2973  	c := testContext2(t, &ContextOpts{
  2974  		Module: m,
  2975  		Providers: map[string]ResourceProviderFactory{
  2976  			"aws": testProviderFuncFixed(p),
  2977  		},
  2978  	})
  2979  
  2980  	computed := false
  2981  	p.ValidateResourceFn = func(t string, c *ResourceConfig) ([]string, []error) {
  2982  		computed = c.IsComputed("foo")
  2983  		return nil, nil
  2984  	}
  2985  
  2986  	c.Validate()
  2987  	if !computed {
  2988  		t.Fatal("should be computed")
  2989  	}
  2990  }
  2991  
  2992  func TestContext2Validate_varRefFilled(t *testing.T) {
  2993  	m := testModule(t, "validate-variable-ref")
  2994  	p := testProvider("aws")
  2995  	c := testContext2(t, &ContextOpts{
  2996  		Module: m,
  2997  		Providers: map[string]ResourceProviderFactory{
  2998  			"aws": testProviderFuncFixed(p),
  2999  		},
  3000  		Variables: map[string]string{
  3001  			"foo": "bar",
  3002  		},
  3003  	})
  3004  
  3005  	var value interface{}
  3006  	p.ValidateResourceFn = func(t string, c *ResourceConfig) ([]string, []error) {
  3007  		value, _ = c.Get("foo")
  3008  		return nil, nil
  3009  	}
  3010  
  3011  	c.Validate()
  3012  	if value != "bar" {
  3013  		t.Fatalf("bad: %#v", value)
  3014  	}
  3015  }
  3016  
  3017  func TestContext2Input(t *testing.T) {
  3018  	input := new(MockUIInput)
  3019  	m := testModule(t, "input-vars")
  3020  	p := testProvider("aws")
  3021  	p.ApplyFn = testApplyFn
  3022  	p.DiffFn = testDiffFn
  3023  	ctx := testContext2(t, &ContextOpts{
  3024  		Module: m,
  3025  		Providers: map[string]ResourceProviderFactory{
  3026  			"aws": testProviderFuncFixed(p),
  3027  		},
  3028  		Variables: map[string]string{
  3029  			"foo":            "us-west-2",
  3030  			"amis.us-east-1": "override",
  3031  		},
  3032  		UIInput: input,
  3033  	})
  3034  
  3035  	input.InputReturnMap = map[string]string{
  3036  		"var.foo": "us-east-1",
  3037  	}
  3038  
  3039  	if err := ctx.Input(InputModeStd); err != nil {
  3040  		t.Fatalf("err: %s", err)
  3041  	}
  3042  
  3043  	if _, err := ctx.Plan(); err != nil {
  3044  		t.Fatalf("err: %s", err)
  3045  	}
  3046  
  3047  	state, err := ctx.Apply()
  3048  	if err != nil {
  3049  		t.Fatalf("err: %s", err)
  3050  	}
  3051  
  3052  	actual := strings.TrimSpace(state.String())
  3053  	expected := strings.TrimSpace(testTerraformInputVarsStr)
  3054  	if actual != expected {
  3055  		t.Fatalf("bad: \n%s", actual)
  3056  	}
  3057  }
  3058  
  3059  func TestContext2Input_badVarDefault(t *testing.T) {
  3060  	m := testModule(t, "input-bad-var-default")
  3061  	p := testProvider("aws")
  3062  	p.ApplyFn = testApplyFn
  3063  	p.DiffFn = testDiffFn
  3064  	ctx := testContext2(t, &ContextOpts{
  3065  		Module: m,
  3066  		Providers: map[string]ResourceProviderFactory{
  3067  			"aws": testProviderFuncFixed(p),
  3068  		},
  3069  	})
  3070  
  3071  	p.InputFn = func(i UIInput, c *ResourceConfig) (*ResourceConfig, error) {
  3072  		c.Config["foo"] = "bar"
  3073  		return c, nil
  3074  	}
  3075  
  3076  	if err := ctx.Input(InputModeStd); err != nil {
  3077  		t.Fatalf("err: %s", err)
  3078  	}
  3079  }
  3080  
  3081  func TestContext2Input_provider(t *testing.T) {
  3082  	m := testModule(t, "input-provider")
  3083  	p := testProvider("aws")
  3084  	p.ApplyFn = testApplyFn
  3085  	p.DiffFn = testDiffFn
  3086  	ctx := testContext2(t, &ContextOpts{
  3087  		Module: m,
  3088  		Providers: map[string]ResourceProviderFactory{
  3089  			"aws": testProviderFuncFixed(p),
  3090  		},
  3091  	})
  3092  
  3093  	var actual interface{}
  3094  	p.InputFn = func(i UIInput, c *ResourceConfig) (*ResourceConfig, error) {
  3095  		c.Config["foo"] = "bar"
  3096  		return c, nil
  3097  	}
  3098  	p.ConfigureFn = func(c *ResourceConfig) error {
  3099  		actual = c.Config["foo"]
  3100  		return nil
  3101  	}
  3102  	p.ValidateFn = func(c *ResourceConfig) ([]string, []error) {
  3103  		return nil, c.CheckSet([]string{"foo"})
  3104  	}
  3105  
  3106  	if err := ctx.Input(InputModeStd); err != nil {
  3107  		t.Fatalf("err: %s", err)
  3108  	}
  3109  
  3110  	if _, err := ctx.Plan(); err != nil {
  3111  		t.Fatalf("err: %s", err)
  3112  	}
  3113  
  3114  	if _, err := ctx.Apply(); err != nil {
  3115  		t.Fatalf("err: %s", err)
  3116  	}
  3117  
  3118  	if !reflect.DeepEqual(actual, "bar") {
  3119  		t.Fatalf("bad: %#v", actual)
  3120  	}
  3121  }
  3122  
  3123  func TestContext2Input_providerMulti(t *testing.T) {
  3124  	m := testModule(t, "input-provider-multi")
  3125  	p := testProvider("aws")
  3126  	p.ApplyFn = testApplyFn
  3127  	p.DiffFn = testDiffFn
  3128  	ctx := testContext2(t, &ContextOpts{
  3129  		Module: m,
  3130  		Providers: map[string]ResourceProviderFactory{
  3131  			"aws": testProviderFuncFixed(p),
  3132  		},
  3133  	})
  3134  
  3135  	var actual []interface{}
  3136  	var lock sync.Mutex
  3137  	p.InputFn = func(i UIInput, c *ResourceConfig) (*ResourceConfig, error) {
  3138  		c.Config["foo"] = "bar"
  3139  		return c, nil
  3140  	}
  3141  	p.ConfigureFn = func(c *ResourceConfig) error {
  3142  		lock.Lock()
  3143  		defer lock.Unlock()
  3144  		actual = append(actual, c.Config["foo"])
  3145  		return nil
  3146  	}
  3147  	p.ValidateFn = func(c *ResourceConfig) ([]string, []error) {
  3148  		return nil, c.CheckSet([]string{"foo"})
  3149  	}
  3150  
  3151  	if err := ctx.Input(InputModeStd); err != nil {
  3152  		t.Fatalf("err: %s", err)
  3153  	}
  3154  
  3155  	if _, err := ctx.Plan(); err != nil {
  3156  		t.Fatalf("err: %s", err)
  3157  	}
  3158  
  3159  	if _, err := ctx.Apply(); err != nil {
  3160  		t.Fatalf("err: %s", err)
  3161  	}
  3162  
  3163  	expected := []interface{}{"bar", "bar"}
  3164  	if !reflect.DeepEqual(actual, expected) {
  3165  		t.Fatalf("bad: %#v", actual)
  3166  	}
  3167  }
  3168  
  3169  func TestContext2Input_providerOnce(t *testing.T) {
  3170  	m := testModule(t, "input-provider-once")
  3171  	p := testProvider("aws")
  3172  	p.ApplyFn = testApplyFn
  3173  	p.DiffFn = testDiffFn
  3174  	ctx := testContext2(t, &ContextOpts{
  3175  		Module: m,
  3176  		Providers: map[string]ResourceProviderFactory{
  3177  			"aws": testProviderFuncFixed(p),
  3178  		},
  3179  	})
  3180  
  3181  	count := 0
  3182  	p.InputFn = func(i UIInput, c *ResourceConfig) (*ResourceConfig, error) {
  3183  		count++
  3184  		return nil, nil
  3185  	}
  3186  
  3187  	if err := ctx.Input(InputModeStd); err != nil {
  3188  		t.Fatalf("err: %s", err)
  3189  	}
  3190  
  3191  	if count != 1 {
  3192  		t.Fatalf("should only be called once: %d", count)
  3193  	}
  3194  }
  3195  
  3196  func TestContext2Input_providerId(t *testing.T) {
  3197  	input := new(MockUIInput)
  3198  	m := testModule(t, "input-provider")
  3199  	p := testProvider("aws")
  3200  	p.ApplyFn = testApplyFn
  3201  	p.DiffFn = testDiffFn
  3202  	ctx := testContext2(t, &ContextOpts{
  3203  		Module: m,
  3204  		Providers: map[string]ResourceProviderFactory{
  3205  			"aws": testProviderFuncFixed(p),
  3206  		},
  3207  		UIInput: input,
  3208  	})
  3209  
  3210  	var actual interface{}
  3211  	p.InputFn = func(i UIInput, c *ResourceConfig) (*ResourceConfig, error) {
  3212  		v, err := i.Input(&InputOpts{Id: "foo"})
  3213  		if err != nil {
  3214  			return nil, err
  3215  		}
  3216  
  3217  		c.Config["foo"] = v
  3218  		return c, nil
  3219  	}
  3220  	p.ConfigureFn = func(c *ResourceConfig) error {
  3221  		actual = c.Config["foo"]
  3222  		return nil
  3223  	}
  3224  
  3225  	input.InputReturnMap = map[string]string{
  3226  		"provider.aws.foo": "bar",
  3227  	}
  3228  
  3229  	if err := ctx.Input(InputModeStd); err != nil {
  3230  		t.Fatalf("err: %s", err)
  3231  	}
  3232  
  3233  	if _, err := ctx.Plan(); err != nil {
  3234  		t.Fatalf("err: %s", err)
  3235  	}
  3236  
  3237  	if _, err := ctx.Apply(); err != nil {
  3238  		t.Fatalf("err: %s", err)
  3239  	}
  3240  
  3241  	if !reflect.DeepEqual(actual, "bar") {
  3242  		t.Fatalf("bad: %#v", actual)
  3243  	}
  3244  }
  3245  
  3246  func TestContext2Input_providerOnly(t *testing.T) {
  3247  	input := new(MockUIInput)
  3248  	m := testModule(t, "input-provider-vars")
  3249  	p := testProvider("aws")
  3250  	p.ApplyFn = testApplyFn
  3251  	p.DiffFn = testDiffFn
  3252  	ctx := testContext2(t, &ContextOpts{
  3253  		Module: m,
  3254  		Providers: map[string]ResourceProviderFactory{
  3255  			"aws": testProviderFuncFixed(p),
  3256  		},
  3257  		Variables: map[string]string{
  3258  			"foo": "us-west-2",
  3259  		},
  3260  		UIInput: input,
  3261  	})
  3262  
  3263  	input.InputReturnMap = map[string]string{
  3264  		"var.foo": "us-east-1",
  3265  	}
  3266  
  3267  	var actual interface{}
  3268  	p.InputFn = func(i UIInput, c *ResourceConfig) (*ResourceConfig, error) {
  3269  		c.Config["foo"] = "bar"
  3270  		return c, nil
  3271  	}
  3272  	p.ConfigureFn = func(c *ResourceConfig) error {
  3273  		actual = c.Config["foo"]
  3274  		return nil
  3275  	}
  3276  
  3277  	if err := ctx.Input(InputModeProvider); err != nil {
  3278  		t.Fatalf("err: %s", err)
  3279  	}
  3280  
  3281  	if _, err := ctx.Plan(); err != nil {
  3282  		t.Fatalf("err: %s", err)
  3283  	}
  3284  
  3285  	state, err := ctx.Apply()
  3286  	if err != nil {
  3287  		t.Fatalf("err: %s", err)
  3288  	}
  3289  
  3290  	if !reflect.DeepEqual(actual, "bar") {
  3291  		t.Fatalf("bad: %#v", actual)
  3292  	}
  3293  
  3294  	actualStr := strings.TrimSpace(state.String())
  3295  	expectedStr := strings.TrimSpace(testTerraformInputProviderOnlyStr)
  3296  	if actualStr != expectedStr {
  3297  		t.Fatalf("bad: \n%s", actualStr)
  3298  	}
  3299  }
  3300  
  3301  func TestContext2Input_providerVars(t *testing.T) {
  3302  	input := new(MockUIInput)
  3303  	m := testModule(t, "input-provider-with-vars")
  3304  	p := testProvider("aws")
  3305  	p.ApplyFn = testApplyFn
  3306  	p.DiffFn = testDiffFn
  3307  	ctx := testContext2(t, &ContextOpts{
  3308  		Module: m,
  3309  		Providers: map[string]ResourceProviderFactory{
  3310  			"aws": testProviderFuncFixed(p),
  3311  		},
  3312  		Variables: map[string]string{
  3313  			"foo": "bar",
  3314  		},
  3315  		UIInput: input,
  3316  	})
  3317  
  3318  	input.InputReturnMap = map[string]string{
  3319  		"var.foo": "bar",
  3320  	}
  3321  
  3322  	var actual interface{}
  3323  	p.InputFn = func(i UIInput, c *ResourceConfig) (*ResourceConfig, error) {
  3324  		c.Config["bar"] = "baz"
  3325  		return c, nil
  3326  	}
  3327  	p.ConfigureFn = func(c *ResourceConfig) error {
  3328  		actual, _ = c.Get("foo")
  3329  		return nil
  3330  	}
  3331  
  3332  	if err := ctx.Input(InputModeStd); err != nil {
  3333  		t.Fatalf("err: %s", err)
  3334  	}
  3335  
  3336  	if _, err := ctx.Plan(); err != nil {
  3337  		t.Fatalf("err: %s", err)
  3338  	}
  3339  
  3340  	if _, err := ctx.Apply(); err != nil {
  3341  		t.Fatalf("err: %s", err)
  3342  	}
  3343  
  3344  	if !reflect.DeepEqual(actual, "bar") {
  3345  		t.Fatalf("bad: %#v", actual)
  3346  	}
  3347  }
  3348  
  3349  func TestContext2Input_providerVarsModuleInherit(t *testing.T) {
  3350  	input := new(MockUIInput)
  3351  	m := testModule(t, "input-provider-with-vars-and-module")
  3352  	p := testProvider("aws")
  3353  	p.ApplyFn = testApplyFn
  3354  	p.DiffFn = testDiffFn
  3355  	ctx := testContext2(t, &ContextOpts{
  3356  		Module: m,
  3357  		Providers: map[string]ResourceProviderFactory{
  3358  			"aws": testProviderFuncFixed(p),
  3359  		},
  3360  		UIInput: input,
  3361  	})
  3362  
  3363  	p.InputFn = func(i UIInput, c *ResourceConfig) (*ResourceConfig, error) {
  3364  		if errs := c.CheckSet([]string{"access_key"}); len(errs) > 0 {
  3365  			return c, errs[0]
  3366  		}
  3367  		return c, nil
  3368  	}
  3369  	p.ConfigureFn = func(c *ResourceConfig) error {
  3370  		return nil
  3371  	}
  3372  
  3373  	if err := ctx.Input(InputModeStd); err != nil {
  3374  		t.Fatalf("err: %s", err)
  3375  	}
  3376  }
  3377  
  3378  func TestContext2Input_varOnly(t *testing.T) {
  3379  	input := new(MockUIInput)
  3380  	m := testModule(t, "input-provider-vars")
  3381  	p := testProvider("aws")
  3382  	p.ApplyFn = testApplyFn
  3383  	p.DiffFn = testDiffFn
  3384  	ctx := testContext2(t, &ContextOpts{
  3385  		Module: m,
  3386  		Providers: map[string]ResourceProviderFactory{
  3387  			"aws": testProviderFuncFixed(p),
  3388  		},
  3389  		Variables: map[string]string{
  3390  			"foo": "us-west-2",
  3391  		},
  3392  		UIInput: input,
  3393  	})
  3394  
  3395  	input.InputReturnMap = map[string]string{
  3396  		"var.foo": "us-east-1",
  3397  	}
  3398  
  3399  	var actual interface{}
  3400  	p.InputFn = func(i UIInput, c *ResourceConfig) (*ResourceConfig, error) {
  3401  		c.Raw["foo"] = "bar"
  3402  		return c, nil
  3403  	}
  3404  	p.ConfigureFn = func(c *ResourceConfig) error {
  3405  		actual = c.Raw["foo"]
  3406  		return nil
  3407  	}
  3408  
  3409  	if err := ctx.Input(InputModeVar); err != nil {
  3410  		t.Fatalf("err: %s", err)
  3411  	}
  3412  
  3413  	if _, err := ctx.Plan(); err != nil {
  3414  		t.Fatalf("err: %s", err)
  3415  	}
  3416  
  3417  	state, err := ctx.Apply()
  3418  	if err != nil {
  3419  		t.Fatalf("err: %s", err)
  3420  	}
  3421  
  3422  	if reflect.DeepEqual(actual, "bar") {
  3423  		t.Fatalf("bad: %#v", actual)
  3424  	}
  3425  
  3426  	actualStr := strings.TrimSpace(state.String())
  3427  	expectedStr := strings.TrimSpace(testTerraformInputVarOnlyStr)
  3428  	if actualStr != expectedStr {
  3429  		t.Fatalf("bad: \n%s", actualStr)
  3430  	}
  3431  }
  3432  
  3433  func TestContext2Input_varOnlyUnset(t *testing.T) {
  3434  	input := new(MockUIInput)
  3435  	m := testModule(t, "input-vars-unset")
  3436  	p := testProvider("aws")
  3437  	p.ApplyFn = testApplyFn
  3438  	p.DiffFn = testDiffFn
  3439  	ctx := testContext2(t, &ContextOpts{
  3440  		Module: m,
  3441  		Providers: map[string]ResourceProviderFactory{
  3442  			"aws": testProviderFuncFixed(p),
  3443  		},
  3444  		Variables: map[string]string{
  3445  			"foo": "foovalue",
  3446  		},
  3447  		UIInput: input,
  3448  	})
  3449  
  3450  	input.InputReturnMap = map[string]string{
  3451  		"var.foo": "nope",
  3452  		"var.bar": "baz",
  3453  	}
  3454  
  3455  	if err := ctx.Input(InputModeVar | InputModeVarUnset); err != nil {
  3456  		t.Fatalf("err: %s", err)
  3457  	}
  3458  
  3459  	if _, err := ctx.Plan(); err != nil {
  3460  		t.Fatalf("err: %s", err)
  3461  	}
  3462  
  3463  	state, err := ctx.Apply()
  3464  	if err != nil {
  3465  		t.Fatalf("err: %s", err)
  3466  	}
  3467  
  3468  	actualStr := strings.TrimSpace(state.String())
  3469  	expectedStr := strings.TrimSpace(testTerraformInputVarOnlyUnsetStr)
  3470  	if actualStr != expectedStr {
  3471  		t.Fatalf("bad: \n%s", actualStr)
  3472  	}
  3473  }
  3474  
  3475  func TestContext2Apply(t *testing.T) {
  3476  	m := testModule(t, "apply-good")
  3477  	p := testProvider("aws")
  3478  	p.ApplyFn = testApplyFn
  3479  	p.DiffFn = testDiffFn
  3480  	ctx := testContext2(t, &ContextOpts{
  3481  		Module: m,
  3482  		Providers: map[string]ResourceProviderFactory{
  3483  			"aws": testProviderFuncFixed(p),
  3484  		},
  3485  	})
  3486  
  3487  	if _, err := ctx.Plan(); err != nil {
  3488  		t.Fatalf("err: %s", err)
  3489  	}
  3490  
  3491  	state, err := ctx.Apply()
  3492  	if err != nil {
  3493  		t.Fatalf("err: %s", err)
  3494  	}
  3495  
  3496  	mod := state.RootModule()
  3497  	if len(mod.Resources) < 2 {
  3498  		t.Fatalf("bad: %#v", mod.Resources)
  3499  	}
  3500  
  3501  	actual := strings.TrimSpace(state.String())
  3502  	expected := strings.TrimSpace(testTerraformApplyStr)
  3503  	if actual != expected {
  3504  		t.Fatalf("bad: \n%s", actual)
  3505  	}
  3506  }
  3507  
  3508  func TestContext2Apply_providerAlias(t *testing.T) {
  3509  	m := testModule(t, "apply-provider-alias")
  3510  	p := testProvider("aws")
  3511  	p.ApplyFn = testApplyFn
  3512  	p.DiffFn = testDiffFn
  3513  	ctx := testContext2(t, &ContextOpts{
  3514  		Module: m,
  3515  		Providers: map[string]ResourceProviderFactory{
  3516  			"aws": testProviderFuncFixed(p),
  3517  		},
  3518  	})
  3519  
  3520  	if _, err := ctx.Plan(); err != nil {
  3521  		t.Fatalf("err: %s", err)
  3522  	}
  3523  
  3524  	state, err := ctx.Apply()
  3525  	if err != nil {
  3526  		t.Fatalf("err: %s", err)
  3527  	}
  3528  
  3529  	mod := state.RootModule()
  3530  	if len(mod.Resources) < 2 {
  3531  		t.Fatalf("bad: %#v", mod.Resources)
  3532  	}
  3533  
  3534  	actual := strings.TrimSpace(state.String())
  3535  	expected := strings.TrimSpace(testTerraformApplyProviderAliasStr)
  3536  	if actual != expected {
  3537  		t.Fatalf("bad: \n%s", actual)
  3538  	}
  3539  }
  3540  
  3541  func TestContext2Apply_emptyModule(t *testing.T) {
  3542  	m := testModule(t, "apply-empty-module")
  3543  	p := testProvider("aws")
  3544  	p.ApplyFn = testApplyFn
  3545  	p.DiffFn = testDiffFn
  3546  	ctx := testContext2(t, &ContextOpts{
  3547  		Module: m,
  3548  		Providers: map[string]ResourceProviderFactory{
  3549  			"aws": testProviderFuncFixed(p),
  3550  		},
  3551  	})
  3552  
  3553  	if _, err := ctx.Plan(); err != nil {
  3554  		t.Fatalf("err: %s", err)
  3555  	}
  3556  
  3557  	state, err := ctx.Apply()
  3558  	if err != nil {
  3559  		t.Fatalf("err: %s", err)
  3560  	}
  3561  
  3562  	actual := strings.TrimSpace(state.String())
  3563  	actual = strings.Replace(actual, "  ", "", -1)
  3564  	expected := strings.TrimSpace(testTerraformApplyEmptyModuleStr)
  3565  	if actual != expected {
  3566  		t.Fatalf("bad: \n%s\nexpect:\n%s", actual, expected)
  3567  	}
  3568  }
  3569  
  3570  func TestContext2Apply_createBeforeDestroy(t *testing.T) {
  3571  	m := testModule(t, "apply-good-create-before")
  3572  	p := testProvider("aws")
  3573  	p.ApplyFn = testApplyFn
  3574  	p.DiffFn = testDiffFn
  3575  	state := &State{
  3576  		Modules: []*ModuleState{
  3577  			&ModuleState{
  3578  				Path: rootModulePath,
  3579  				Resources: map[string]*ResourceState{
  3580  					"aws_instance.bar": &ResourceState{
  3581  						Type: "aws_instance",
  3582  						Primary: &InstanceState{
  3583  							ID: "bar",
  3584  							Attributes: map[string]string{
  3585  								"require_new": "abc",
  3586  							},
  3587  						},
  3588  					},
  3589  				},
  3590  			},
  3591  		},
  3592  	}
  3593  	ctx := testContext2(t, &ContextOpts{
  3594  		Module: m,
  3595  		Providers: map[string]ResourceProviderFactory{
  3596  			"aws": testProviderFuncFixed(p),
  3597  		},
  3598  		State: state,
  3599  	})
  3600  
  3601  	if p, err := ctx.Plan(); err != nil {
  3602  		t.Fatalf("err: %s", err)
  3603  	} else {
  3604  		t.Logf(p.String())
  3605  	}
  3606  
  3607  	state, err := ctx.Apply()
  3608  	if err != nil {
  3609  		t.Fatalf("err: %s", err)
  3610  	}
  3611  
  3612  	mod := state.RootModule()
  3613  	if len(mod.Resources) != 1 {
  3614  		t.Fatalf("bad: %s", state)
  3615  	}
  3616  
  3617  	actual := strings.TrimSpace(state.String())
  3618  	expected := strings.TrimSpace(testTerraformApplyCreateBeforeStr)
  3619  	if actual != expected {
  3620  		t.Fatalf("bad: \n%s", actual)
  3621  	}
  3622  }
  3623  
  3624  func TestContext2Apply_createBeforeDestroyUpdate(t *testing.T) {
  3625  	m := testModule(t, "apply-good-create-before-update")
  3626  	p := testProvider("aws")
  3627  	p.ApplyFn = testApplyFn
  3628  	p.DiffFn = testDiffFn
  3629  	state := &State{
  3630  		Modules: []*ModuleState{
  3631  			&ModuleState{
  3632  				Path: rootModulePath,
  3633  				Resources: map[string]*ResourceState{
  3634  					"aws_instance.bar": &ResourceState{
  3635  						Type: "aws_instance",
  3636  						Primary: &InstanceState{
  3637  							ID: "bar",
  3638  							Attributes: map[string]string{
  3639  								"foo": "bar",
  3640  							},
  3641  						},
  3642  					},
  3643  				},
  3644  			},
  3645  		},
  3646  	}
  3647  	ctx := testContext2(t, &ContextOpts{
  3648  		Module: m,
  3649  		Providers: map[string]ResourceProviderFactory{
  3650  			"aws": testProviderFuncFixed(p),
  3651  		},
  3652  		State: state,
  3653  	})
  3654  
  3655  	if p, err := ctx.Plan(); err != nil {
  3656  		t.Fatalf("err: %s", err)
  3657  	} else {
  3658  		t.Logf(p.String())
  3659  	}
  3660  
  3661  	state, err := ctx.Apply()
  3662  	if err != nil {
  3663  		t.Fatalf("err: %s", err)
  3664  	}
  3665  
  3666  	mod := state.RootModule()
  3667  	if len(mod.Resources) != 1 {
  3668  		t.Fatalf("bad: %s", state)
  3669  	}
  3670  
  3671  	actual := strings.TrimSpace(state.String())
  3672  	expected := strings.TrimSpace(testTerraformApplyCreateBeforeUpdateStr)
  3673  	if actual != expected {
  3674  		t.Fatalf("bad: \n%s", actual)
  3675  	}
  3676  }
  3677  
  3678  func TestContext2Apply_minimal(t *testing.T) {
  3679  	m := testModule(t, "apply-minimal")
  3680  	p := testProvider("aws")
  3681  	p.ApplyFn = testApplyFn
  3682  	p.DiffFn = testDiffFn
  3683  	ctx := testContext2(t, &ContextOpts{
  3684  		Module: m,
  3685  		Providers: map[string]ResourceProviderFactory{
  3686  			"aws": testProviderFuncFixed(p),
  3687  		},
  3688  	})
  3689  
  3690  	if _, err := ctx.Plan(); err != nil {
  3691  		t.Fatalf("err: %s", err)
  3692  	}
  3693  
  3694  	state, err := ctx.Apply()
  3695  	if err != nil {
  3696  		t.Fatalf("err: %s", err)
  3697  	}
  3698  
  3699  	actual := strings.TrimSpace(state.String())
  3700  	expected := strings.TrimSpace(testTerraformApplyMinimalStr)
  3701  	if actual != expected {
  3702  		t.Fatalf("bad: \n%s", actual)
  3703  	}
  3704  }
  3705  
  3706  func TestContext2Apply_badDiff(t *testing.T) {
  3707  	m := testModule(t, "apply-good")
  3708  	p := testProvider("aws")
  3709  	p.ApplyFn = testApplyFn
  3710  	p.DiffFn = testDiffFn
  3711  	ctx := testContext2(t, &ContextOpts{
  3712  		Module: m,
  3713  		Providers: map[string]ResourceProviderFactory{
  3714  			"aws": testProviderFuncFixed(p),
  3715  		},
  3716  	})
  3717  
  3718  	if _, err := ctx.Plan(); err != nil {
  3719  		t.Fatalf("err: %s", err)
  3720  	}
  3721  
  3722  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  3723  		return &InstanceDiff{
  3724  			Attributes: map[string]*ResourceAttrDiff{
  3725  				"newp": nil,
  3726  			},
  3727  		}, nil
  3728  	}
  3729  
  3730  	if _, err := ctx.Apply(); err == nil {
  3731  		t.Fatal("should error")
  3732  	}
  3733  }
  3734  
  3735  func TestContext2Apply_cancel(t *testing.T) {
  3736  	stopped := false
  3737  
  3738  	m := testModule(t, "apply-cancel")
  3739  	p := testProvider("aws")
  3740  	ctx := testContext2(t, &ContextOpts{
  3741  		Module: m,
  3742  		Providers: map[string]ResourceProviderFactory{
  3743  			"aws": testProviderFuncFixed(p),
  3744  		},
  3745  	})
  3746  
  3747  	p.ApplyFn = func(*InstanceInfo, *InstanceState, *InstanceDiff) (*InstanceState, error) {
  3748  		if !stopped {
  3749  			stopped = true
  3750  			go ctx.Stop()
  3751  
  3752  			for {
  3753  				if ctx.sh.Stopped() {
  3754  					break
  3755  				}
  3756  			}
  3757  		}
  3758  
  3759  		return &InstanceState{
  3760  			ID: "foo",
  3761  			Attributes: map[string]string{
  3762  				"num": "2",
  3763  			},
  3764  		}, nil
  3765  	}
  3766  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  3767  		return &InstanceDiff{
  3768  			Attributes: map[string]*ResourceAttrDiff{
  3769  				"num": &ResourceAttrDiff{
  3770  					New: "bar",
  3771  				},
  3772  			},
  3773  		}, nil
  3774  	}
  3775  
  3776  	if _, err := ctx.Plan(); err != nil {
  3777  		t.Fatalf("err: %s", err)
  3778  	}
  3779  
  3780  	// Start the Apply in a goroutine
  3781  	stateCh := make(chan *State)
  3782  	go func() {
  3783  		state, err := ctx.Apply()
  3784  		if err != nil {
  3785  			panic(err)
  3786  		}
  3787  
  3788  		stateCh <- state
  3789  	}()
  3790  
  3791  	state := <-stateCh
  3792  
  3793  	mod := state.RootModule()
  3794  	if len(mod.Resources) != 1 {
  3795  		t.Fatalf("bad: %s", state.String())
  3796  	}
  3797  
  3798  	actual := strings.TrimSpace(state.String())
  3799  	expected := strings.TrimSpace(testTerraformApplyCancelStr)
  3800  	if actual != expected {
  3801  		t.Fatalf("bad: \n%s", actual)
  3802  	}
  3803  }
  3804  
  3805  func TestContext2Apply_compute(t *testing.T) {
  3806  	m := testModule(t, "apply-compute")
  3807  	p := testProvider("aws")
  3808  	p.ApplyFn = testApplyFn
  3809  	p.DiffFn = testDiffFn
  3810  	ctx := testContext2(t, &ContextOpts{
  3811  		Module: m,
  3812  		Providers: map[string]ResourceProviderFactory{
  3813  			"aws": testProviderFuncFixed(p),
  3814  		},
  3815  	})
  3816  
  3817  	if _, err := ctx.Plan(); err != nil {
  3818  		t.Fatalf("err: %s", err)
  3819  	}
  3820  
  3821  	ctx.variables = map[string]string{"value": "1"}
  3822  
  3823  	state, err := ctx.Apply()
  3824  	if err != nil {
  3825  		t.Fatalf("err: %s", err)
  3826  	}
  3827  
  3828  	actual := strings.TrimSpace(state.String())
  3829  	expected := strings.TrimSpace(testTerraformApplyComputeStr)
  3830  	if actual != expected {
  3831  		t.Fatalf("bad: \n%s", actual)
  3832  	}
  3833  }
  3834  
  3835  func TestContext2Apply_countDecrease(t *testing.T) {
  3836  	m := testModule(t, "apply-count-dec")
  3837  	p := testProvider("aws")
  3838  	p.DiffFn = testDiffFn
  3839  	s := &State{
  3840  		Modules: []*ModuleState{
  3841  			&ModuleState{
  3842  				Path: rootModulePath,
  3843  				Resources: map[string]*ResourceState{
  3844  					"aws_instance.foo.0": &ResourceState{
  3845  						Type: "aws_instance",
  3846  						Primary: &InstanceState{
  3847  							ID: "bar",
  3848  							Attributes: map[string]string{
  3849  								"foo":  "foo",
  3850  								"type": "aws_instance",
  3851  							},
  3852  						},
  3853  					},
  3854  					"aws_instance.foo.1": &ResourceState{
  3855  						Type: "aws_instance",
  3856  						Primary: &InstanceState{
  3857  							ID: "bar",
  3858  							Attributes: map[string]string{
  3859  								"foo":  "foo",
  3860  								"type": "aws_instance",
  3861  							},
  3862  						},
  3863  					},
  3864  					"aws_instance.foo.2": &ResourceState{
  3865  						Type: "aws_instance",
  3866  						Primary: &InstanceState{
  3867  							ID: "bar",
  3868  							Attributes: map[string]string{
  3869  								"foo":  "foo",
  3870  								"type": "aws_instance",
  3871  							},
  3872  						},
  3873  					},
  3874  				},
  3875  			},
  3876  		},
  3877  	}
  3878  	ctx := testContext2(t, &ContextOpts{
  3879  		Module: m,
  3880  		Providers: map[string]ResourceProviderFactory{
  3881  			"aws": testProviderFuncFixed(p),
  3882  		},
  3883  		State: s,
  3884  	})
  3885  
  3886  	if _, err := ctx.Plan(); err != nil {
  3887  		t.Fatalf("err: %s", err)
  3888  	}
  3889  
  3890  	state, err := ctx.Apply()
  3891  	if err != nil {
  3892  		t.Fatalf("err: %s", err)
  3893  	}
  3894  
  3895  	actual := strings.TrimSpace(state.String())
  3896  	expected := strings.TrimSpace(testTerraformApplyCountDecStr)
  3897  	if actual != expected {
  3898  		t.Fatalf("bad: \n%s", actual)
  3899  	}
  3900  }
  3901  
  3902  func TestContext2Apply_countDecreaseToOne(t *testing.T) {
  3903  	m := testModule(t, "apply-count-dec-one")
  3904  	p := testProvider("aws")
  3905  	p.ApplyFn = testApplyFn
  3906  	p.DiffFn = testDiffFn
  3907  	s := &State{
  3908  		Modules: []*ModuleState{
  3909  			&ModuleState{
  3910  				Path: rootModulePath,
  3911  				Resources: map[string]*ResourceState{
  3912  					"aws_instance.foo.0": &ResourceState{
  3913  						Type: "aws_instance",
  3914  						Primary: &InstanceState{
  3915  							ID: "bar",
  3916  							Attributes: map[string]string{
  3917  								"foo":  "foo",
  3918  								"type": "aws_instance",
  3919  							},
  3920  						},
  3921  					},
  3922  					"aws_instance.foo.1": &ResourceState{
  3923  						Type: "aws_instance",
  3924  						Primary: &InstanceState{
  3925  							ID: "bar",
  3926  						},
  3927  					},
  3928  					"aws_instance.foo.2": &ResourceState{
  3929  						Type: "aws_instance",
  3930  						Primary: &InstanceState{
  3931  							ID: "bar",
  3932  						},
  3933  					},
  3934  				},
  3935  			},
  3936  		},
  3937  	}
  3938  	ctx := testContext2(t, &ContextOpts{
  3939  		Module: m,
  3940  		Providers: map[string]ResourceProviderFactory{
  3941  			"aws": testProviderFuncFixed(p),
  3942  		},
  3943  		State: s,
  3944  	})
  3945  
  3946  	if _, err := ctx.Plan(); err != nil {
  3947  		t.Fatalf("err: %s", err)
  3948  	}
  3949  
  3950  	state, err := ctx.Apply()
  3951  	if err != nil {
  3952  		t.Fatalf("err: %s", err)
  3953  	}
  3954  
  3955  	actual := strings.TrimSpace(state.String())
  3956  	expected := strings.TrimSpace(testTerraformApplyCountDecToOneStr)
  3957  	if actual != expected {
  3958  		t.Fatalf("bad: \n%s", actual)
  3959  	}
  3960  }
  3961  
  3962  // https://github.com/PeoplePerHour/terraform/pull/11
  3963  //
  3964  // This tests a case where both a "resource" and "resource.0" are in
  3965  // the state file, which apparently is a reasonable backwards compatibility
  3966  // concern found in the above 3rd party repo.
  3967  func TestContext2Apply_countDecreaseToOneCorrupted(t *testing.T) {
  3968  	m := testModule(t, "apply-count-dec-one")
  3969  	p := testProvider("aws")
  3970  	p.ApplyFn = testApplyFn
  3971  	p.DiffFn = testDiffFn
  3972  	s := &State{
  3973  		Modules: []*ModuleState{
  3974  			&ModuleState{
  3975  				Path: rootModulePath,
  3976  				Resources: map[string]*ResourceState{
  3977  					"aws_instance.foo": &ResourceState{
  3978  						Type: "aws_instance",
  3979  						Primary: &InstanceState{
  3980  							ID: "bar",
  3981  							Attributes: map[string]string{
  3982  								"foo":  "foo",
  3983  								"type": "aws_instance",
  3984  							},
  3985  						},
  3986  					},
  3987  					"aws_instance.foo.0": &ResourceState{
  3988  						Type: "aws_instance",
  3989  						Primary: &InstanceState{
  3990  							ID: "baz",
  3991  							Attributes: map[string]string{
  3992  								"type": "aws_instance",
  3993  							},
  3994  						},
  3995  					},
  3996  				},
  3997  			},
  3998  		},
  3999  	}
  4000  	ctx := testContext2(t, &ContextOpts{
  4001  		Module: m,
  4002  		Providers: map[string]ResourceProviderFactory{
  4003  			"aws": testProviderFuncFixed(p),
  4004  		},
  4005  		State: s,
  4006  	})
  4007  
  4008  	if p, err := ctx.Plan(); err != nil {
  4009  		t.Fatalf("err: %s", err)
  4010  	} else {
  4011  		testStringMatch(t, p, testTerraformApplyCountDecToOneCorruptedPlanStr)
  4012  	}
  4013  
  4014  	state, err := ctx.Apply()
  4015  	if err != nil {
  4016  		t.Fatalf("err: %s", err)
  4017  	}
  4018  
  4019  	actual := strings.TrimSpace(state.String())
  4020  	expected := strings.TrimSpace(testTerraformApplyCountDecToOneCorruptedStr)
  4021  	if actual != expected {
  4022  		t.Fatalf("bad: \n%s", actual)
  4023  	}
  4024  }
  4025  
  4026  func TestContext2Apply_countTainted(t *testing.T) {
  4027  	m := testModule(t, "apply-count-tainted")
  4028  	p := testProvider("aws")
  4029  	p.DiffFn = testDiffFn
  4030  	s := &State{
  4031  		Modules: []*ModuleState{
  4032  			&ModuleState{
  4033  				Path: rootModulePath,
  4034  				Resources: map[string]*ResourceState{
  4035  					"aws_instance.foo.0": &ResourceState{
  4036  						Type: "aws_instance",
  4037  						Tainted: []*InstanceState{
  4038  							&InstanceState{
  4039  								ID: "bar",
  4040  								Attributes: map[string]string{
  4041  									"foo":  "foo",
  4042  									"type": "aws_instance",
  4043  								},
  4044  							},
  4045  						},
  4046  					},
  4047  				},
  4048  			},
  4049  		},
  4050  	}
  4051  	ctx := testContext2(t, &ContextOpts{
  4052  		Module: m,
  4053  		Providers: map[string]ResourceProviderFactory{
  4054  			"aws": testProviderFuncFixed(p),
  4055  		},
  4056  		State: s,
  4057  	})
  4058  
  4059  	if _, err := ctx.Plan(); err != nil {
  4060  		t.Fatalf("err: %s", err)
  4061  	}
  4062  
  4063  	state, err := ctx.Apply()
  4064  	if err != nil {
  4065  		t.Fatalf("err: %s", err)
  4066  	}
  4067  
  4068  	actual := strings.TrimSpace(state.String())
  4069  	expected := strings.TrimSpace(testTerraformApplyCountTaintedStr)
  4070  	if actual != expected {
  4071  		t.Fatalf("bad: \n%s", actual)
  4072  	}
  4073  }
  4074  
  4075  func TestContext2Apply_countVariable(t *testing.T) {
  4076  	m := testModule(t, "apply-count-variable")
  4077  	p := testProvider("aws")
  4078  	p.ApplyFn = testApplyFn
  4079  	p.DiffFn = testDiffFn
  4080  	ctx := testContext2(t, &ContextOpts{
  4081  		Module: m,
  4082  		Providers: map[string]ResourceProviderFactory{
  4083  			"aws": testProviderFuncFixed(p),
  4084  		},
  4085  	})
  4086  
  4087  	if _, err := ctx.Plan(); err != nil {
  4088  		t.Fatalf("err: %s", err)
  4089  	}
  4090  
  4091  	state, err := ctx.Apply()
  4092  	if err != nil {
  4093  		t.Fatalf("err: %s", err)
  4094  	}
  4095  
  4096  	actual := strings.TrimSpace(state.String())
  4097  	expected := strings.TrimSpace(testTerraformApplyCountVariableStr)
  4098  	if actual != expected {
  4099  		t.Fatalf("bad: \n%s", actual)
  4100  	}
  4101  }
  4102  
  4103  func TestContext2Apply_module(t *testing.T) {
  4104  	m := testModule(t, "apply-module")
  4105  	p := testProvider("aws")
  4106  	p.ApplyFn = testApplyFn
  4107  	p.DiffFn = testDiffFn
  4108  	ctx := testContext2(t, &ContextOpts{
  4109  		Module: m,
  4110  		Providers: map[string]ResourceProviderFactory{
  4111  			"aws": testProviderFuncFixed(p),
  4112  		},
  4113  	})
  4114  
  4115  	if _, err := ctx.Plan(); err != nil {
  4116  		t.Fatalf("err: %s", err)
  4117  	}
  4118  
  4119  	state, err := ctx.Apply()
  4120  	if err != nil {
  4121  		t.Fatalf("err: %s", err)
  4122  	}
  4123  
  4124  	actual := strings.TrimSpace(state.String())
  4125  	expected := strings.TrimSpace(testTerraformApplyModuleStr)
  4126  	if actual != expected {
  4127  		t.Fatalf("bad: \n%s", actual)
  4128  	}
  4129  }
  4130  
  4131  func TestContext2Apply_moduleDestroyOrder(t *testing.T) {
  4132  	m := testModule(t, "apply-module-destroy-order")
  4133  	p := testProvider("aws")
  4134  	p.DiffFn = testDiffFn
  4135  
  4136  	// Create a custom apply function to track the order they were destroyed
  4137  	var order []string
  4138  	var orderLock sync.Mutex
  4139  	p.ApplyFn = func(
  4140  		info *InstanceInfo,
  4141  		is *InstanceState,
  4142  		id *InstanceDiff) (*InstanceState, error) {
  4143  		orderLock.Lock()
  4144  		defer orderLock.Unlock()
  4145  
  4146  		order = append(order, is.ID)
  4147  		return nil, nil
  4148  	}
  4149  
  4150  	state := &State{
  4151  		Modules: []*ModuleState{
  4152  			&ModuleState{
  4153  				Path: rootModulePath,
  4154  				Resources: map[string]*ResourceState{
  4155  					"aws_instance.b": &ResourceState{
  4156  						Type: "aws_instance",
  4157  						Primary: &InstanceState{
  4158  							ID: "b",
  4159  						},
  4160  					},
  4161  				},
  4162  			},
  4163  
  4164  			&ModuleState{
  4165  				Path: []string{"root", "child"},
  4166  				Resources: map[string]*ResourceState{
  4167  					"aws_instance.a": &ResourceState{
  4168  						Type: "aws_instance",
  4169  						Primary: &InstanceState{
  4170  							ID: "a",
  4171  						},
  4172  					},
  4173  				},
  4174  				Outputs: map[string]string{
  4175  					"a_output": "a",
  4176  				},
  4177  			},
  4178  		},
  4179  	}
  4180  
  4181  	ctx := testContext2(t, &ContextOpts{
  4182  		Module: m,
  4183  		Providers: map[string]ResourceProviderFactory{
  4184  			"aws": testProviderFuncFixed(p),
  4185  		},
  4186  		State:   state,
  4187  		Destroy: true,
  4188  	})
  4189  
  4190  	if _, err := ctx.Plan(); err != nil {
  4191  		t.Fatalf("err: %s", err)
  4192  	}
  4193  
  4194  	state, err := ctx.Apply()
  4195  	if err != nil {
  4196  		t.Fatalf("err: %s", err)
  4197  	}
  4198  
  4199  	expected := []string{"b", "a"}
  4200  	if !reflect.DeepEqual(order, expected) {
  4201  		t.Fatalf("bad: %#v", order)
  4202  	}
  4203  
  4204  	{
  4205  		actual := strings.TrimSpace(state.String())
  4206  		expected := strings.TrimSpace(testTerraformApplyModuleDestroyOrderStr)
  4207  		if actual != expected {
  4208  			t.Fatalf("bad: \n%s", actual)
  4209  		}
  4210  	}
  4211  }
  4212  
  4213  func TestContext2Apply_moduleVarResourceCount(t *testing.T) {
  4214  	m := testModule(t, "apply-module-var-resource-count")
  4215  	p := testProvider("aws")
  4216  	p.ApplyFn = testApplyFn
  4217  	p.DiffFn = testDiffFn
  4218  	ctx := testContext2(t, &ContextOpts{
  4219  		Module: m,
  4220  		Providers: map[string]ResourceProviderFactory{
  4221  			"aws": testProviderFuncFixed(p),
  4222  		},
  4223  		Variables: map[string]string{
  4224  			"count": "2",
  4225  		},
  4226  		Destroy: true,
  4227  	})
  4228  
  4229  	if _, err := ctx.Plan(); err != nil {
  4230  		t.Fatalf("err: %s", err)
  4231  	}
  4232  
  4233  	if _, err := ctx.Apply(); err != nil {
  4234  		t.Fatalf("err: %s", err)
  4235  	}
  4236  
  4237  	ctx = testContext2(t, &ContextOpts{
  4238  		Module: m,
  4239  		Providers: map[string]ResourceProviderFactory{
  4240  			"aws": testProviderFuncFixed(p),
  4241  		},
  4242  		Variables: map[string]string{
  4243  			"count": "5",
  4244  		},
  4245  	})
  4246  
  4247  	if _, err := ctx.Plan(); err != nil {
  4248  		t.Fatalf("err: %s", err)
  4249  	}
  4250  
  4251  	if _, err := ctx.Apply(); err != nil {
  4252  		t.Fatalf("err: %s", err)
  4253  	}
  4254  }
  4255  
  4256  // GH-819
  4257  func TestContext2Apply_moduleBool(t *testing.T) {
  4258  	m := testModule(t, "apply-module-bool")
  4259  	p := testProvider("aws")
  4260  	p.ApplyFn = testApplyFn
  4261  	p.DiffFn = testDiffFn
  4262  	ctx := testContext2(t, &ContextOpts{
  4263  		Module: m,
  4264  		Providers: map[string]ResourceProviderFactory{
  4265  			"aws": testProviderFuncFixed(p),
  4266  		},
  4267  	})
  4268  
  4269  	if _, err := ctx.Plan(); err != nil {
  4270  		t.Fatalf("err: %s", err)
  4271  	}
  4272  
  4273  	state, err := ctx.Apply()
  4274  	if err != nil {
  4275  		t.Fatalf("err: %s", err)
  4276  	}
  4277  
  4278  	actual := strings.TrimSpace(state.String())
  4279  	expected := strings.TrimSpace(testTerraformApplyModuleBoolStr)
  4280  	if actual != expected {
  4281  		t.Fatalf("bad: \n%s", actual)
  4282  	}
  4283  }
  4284  
  4285  func TestContext2Apply_multiProvider(t *testing.T) {
  4286  	m := testModule(t, "apply-multi-provider")
  4287  	p := testProvider("aws")
  4288  	p.ApplyFn = testApplyFn
  4289  	p.DiffFn = testDiffFn
  4290  
  4291  	pDO := testProvider("do")
  4292  	pDO.ApplyFn = testApplyFn
  4293  	pDO.DiffFn = testDiffFn
  4294  
  4295  	ctx := testContext2(t, &ContextOpts{
  4296  		Module: m,
  4297  		Providers: map[string]ResourceProviderFactory{
  4298  			"aws": testProviderFuncFixed(p),
  4299  			"do":  testProviderFuncFixed(pDO),
  4300  		},
  4301  	})
  4302  
  4303  	if _, err := ctx.Plan(); err != nil {
  4304  		t.Fatalf("err: %s", err)
  4305  	}
  4306  
  4307  	state, err := ctx.Apply()
  4308  	if err != nil {
  4309  		t.Fatalf("err: %s", err)
  4310  	}
  4311  
  4312  	mod := state.RootModule()
  4313  	if len(mod.Resources) < 2 {
  4314  		t.Fatalf("bad: %#v", mod.Resources)
  4315  	}
  4316  
  4317  	actual := strings.TrimSpace(state.String())
  4318  	expected := strings.TrimSpace(testTerraformApplyMultiProviderStr)
  4319  	if actual != expected {
  4320  		t.Fatalf("bad: \n%s", actual)
  4321  	}
  4322  }
  4323  
  4324  func TestContext2Apply_nilDiff(t *testing.T) {
  4325  	m := testModule(t, "apply-good")
  4326  	p := testProvider("aws")
  4327  	p.ApplyFn = testApplyFn
  4328  	p.DiffFn = testDiffFn
  4329  	ctx := testContext2(t, &ContextOpts{
  4330  		Module: m,
  4331  		Providers: map[string]ResourceProviderFactory{
  4332  			"aws": testProviderFuncFixed(p),
  4333  		},
  4334  	})
  4335  
  4336  	if _, err := ctx.Plan(); err != nil {
  4337  		t.Fatalf("err: %s", err)
  4338  	}
  4339  
  4340  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  4341  		return nil, nil
  4342  	}
  4343  
  4344  	if _, err := ctx.Apply(); err == nil {
  4345  		t.Fatal("should error")
  4346  	}
  4347  }
  4348  
  4349  func TestContext2Apply_outputOrphan(t *testing.T) {
  4350  	m := testModule(t, "apply-output-orphan")
  4351  	p := testProvider("aws")
  4352  	p.ApplyFn = testApplyFn
  4353  	p.DiffFn = testDiffFn
  4354  
  4355  	state := &State{
  4356  		Modules: []*ModuleState{
  4357  			&ModuleState{
  4358  				Path: rootModulePath,
  4359  				Outputs: map[string]string{
  4360  					"foo": "bar",
  4361  					"bar": "baz",
  4362  				},
  4363  			},
  4364  		},
  4365  	}
  4366  
  4367  	ctx := testContext2(t, &ContextOpts{
  4368  		Module: m,
  4369  		Providers: map[string]ResourceProviderFactory{
  4370  			"aws": testProviderFuncFixed(p),
  4371  		},
  4372  		State: state,
  4373  	})
  4374  
  4375  	if _, err := ctx.Plan(); err != nil {
  4376  		t.Fatalf("err: %s", err)
  4377  	}
  4378  
  4379  	state, err := ctx.Apply()
  4380  	if err != nil {
  4381  		t.Fatalf("err: %s", err)
  4382  	}
  4383  
  4384  	actual := strings.TrimSpace(state.String())
  4385  	expected := strings.TrimSpace(testTerraformApplyOutputOrphanStr)
  4386  	if actual != expected {
  4387  		t.Fatalf("bad: \n%s", actual)
  4388  	}
  4389  }
  4390  
  4391  func TestContext2Apply_Provisioner_compute(t *testing.T) {
  4392  	m := testModule(t, "apply-provisioner-compute")
  4393  	p := testProvider("aws")
  4394  	pr := testProvisioner()
  4395  	p.ApplyFn = testApplyFn
  4396  	p.DiffFn = testDiffFn
  4397  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  4398  		val, ok := c.Config["foo"]
  4399  		if !ok || val != "computed_dynamical" {
  4400  			t.Fatalf("bad value for foo: %v %#v", val, c)
  4401  		}
  4402  
  4403  		return nil
  4404  	}
  4405  	ctx := testContext2(t, &ContextOpts{
  4406  		Module: m,
  4407  		Providers: map[string]ResourceProviderFactory{
  4408  			"aws": testProviderFuncFixed(p),
  4409  		},
  4410  		Provisioners: map[string]ResourceProvisionerFactory{
  4411  			"shell": testProvisionerFuncFixed(pr),
  4412  		},
  4413  		Variables: map[string]string{
  4414  			"value": "1",
  4415  		},
  4416  	})
  4417  
  4418  	if _, err := ctx.Plan(); err != nil {
  4419  		t.Fatalf("err: %s", err)
  4420  	}
  4421  
  4422  	state, err := ctx.Apply()
  4423  	if err != nil {
  4424  		t.Fatalf("err: %s", err)
  4425  	}
  4426  
  4427  	actual := strings.TrimSpace(state.String())
  4428  	expected := strings.TrimSpace(testTerraformApplyProvisionerStr)
  4429  	if actual != expected {
  4430  		t.Fatalf("bad: \n%s", actual)
  4431  	}
  4432  
  4433  	// Verify apply was invoked
  4434  	if !pr.ApplyCalled {
  4435  		t.Fatalf("provisioner not invoked")
  4436  	}
  4437  }
  4438  
  4439  func TestContext2Apply_provisionerCreateFail(t *testing.T) {
  4440  	m := testModule(t, "apply-provisioner-fail-create")
  4441  	p := testProvider("aws")
  4442  	pr := testProvisioner()
  4443  	p.DiffFn = testDiffFn
  4444  
  4445  	p.ApplyFn = func(
  4446  		info *InstanceInfo,
  4447  		is *InstanceState,
  4448  		id *InstanceDiff) (*InstanceState, error) {
  4449  		is.ID = "foo"
  4450  		return is, fmt.Errorf("error")
  4451  	}
  4452  
  4453  	ctx := testContext2(t, &ContextOpts{
  4454  		Module: m,
  4455  		Providers: map[string]ResourceProviderFactory{
  4456  			"aws": testProviderFuncFixed(p),
  4457  		},
  4458  		Provisioners: map[string]ResourceProvisionerFactory{
  4459  			"shell": testProvisionerFuncFixed(pr),
  4460  		},
  4461  	})
  4462  
  4463  	if _, err := ctx.Plan(); err != nil {
  4464  		t.Fatalf("err: %s", err)
  4465  	}
  4466  
  4467  	state, err := ctx.Apply()
  4468  	if err == nil {
  4469  		t.Fatal("should error")
  4470  	}
  4471  
  4472  	actual := strings.TrimSpace(state.String())
  4473  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailCreateStr)
  4474  	if actual != expected {
  4475  		t.Fatalf("bad: \n%s", actual)
  4476  	}
  4477  }
  4478  
  4479  func TestContext2Apply_provisionerCreateFailNoId(t *testing.T) {
  4480  	m := testModule(t, "apply-provisioner-fail-create")
  4481  	p := testProvider("aws")
  4482  	pr := testProvisioner()
  4483  	p.DiffFn = testDiffFn
  4484  
  4485  	p.ApplyFn = func(
  4486  		info *InstanceInfo,
  4487  		is *InstanceState,
  4488  		id *InstanceDiff) (*InstanceState, error) {
  4489  		return nil, fmt.Errorf("error")
  4490  	}
  4491  
  4492  	ctx := testContext2(t, &ContextOpts{
  4493  		Module: m,
  4494  		Providers: map[string]ResourceProviderFactory{
  4495  			"aws": testProviderFuncFixed(p),
  4496  		},
  4497  		Provisioners: map[string]ResourceProvisionerFactory{
  4498  			"shell": testProvisionerFuncFixed(pr),
  4499  		},
  4500  	})
  4501  
  4502  	if _, err := ctx.Plan(); err != nil {
  4503  		t.Fatalf("err: %s", err)
  4504  	}
  4505  
  4506  	state, err := ctx.Apply()
  4507  	if err == nil {
  4508  		t.Fatal("should error")
  4509  	}
  4510  
  4511  	actual := strings.TrimSpace(state.String())
  4512  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailCreateNoIdStr)
  4513  	if actual != expected {
  4514  		t.Fatalf("bad: \n%s", actual)
  4515  	}
  4516  }
  4517  
  4518  func TestContext2Apply_provisionerFail(t *testing.T) {
  4519  	m := testModule(t, "apply-provisioner-fail")
  4520  	p := testProvider("aws")
  4521  	pr := testProvisioner()
  4522  	p.ApplyFn = testApplyFn
  4523  	p.DiffFn = testDiffFn
  4524  
  4525  	pr.ApplyFn = func(*InstanceState, *ResourceConfig) error {
  4526  		return fmt.Errorf("EXPLOSION")
  4527  	}
  4528  
  4529  	ctx := testContext2(t, &ContextOpts{
  4530  		Module: m,
  4531  		Providers: map[string]ResourceProviderFactory{
  4532  			"aws": testProviderFuncFixed(p),
  4533  		},
  4534  		Provisioners: map[string]ResourceProvisionerFactory{
  4535  			"shell": testProvisionerFuncFixed(pr),
  4536  		},
  4537  		Variables: map[string]string{
  4538  			"value": "1",
  4539  		},
  4540  	})
  4541  
  4542  	if _, err := ctx.Plan(); err != nil {
  4543  		t.Fatalf("err: %s", err)
  4544  	}
  4545  
  4546  	state, err := ctx.Apply()
  4547  	if err == nil {
  4548  		t.Fatal("should error")
  4549  	}
  4550  
  4551  	actual := strings.TrimSpace(state.String())
  4552  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailStr)
  4553  	if actual != expected {
  4554  		t.Fatalf("bad: \n%s", actual)
  4555  	}
  4556  }
  4557  
  4558  func TestContext2Apply_provisionerFail_createBeforeDestroy(t *testing.T) {
  4559  	m := testModule(t, "apply-provisioner-fail-create-before")
  4560  	p := testProvider("aws")
  4561  	pr := testProvisioner()
  4562  	p.ApplyFn = testApplyFn
  4563  	p.DiffFn = testDiffFn
  4564  	pr.ApplyFn = func(*InstanceState, *ResourceConfig) error {
  4565  		return fmt.Errorf("EXPLOSION")
  4566  	}
  4567  
  4568  	state := &State{
  4569  		Modules: []*ModuleState{
  4570  			&ModuleState{
  4571  				Path: rootModulePath,
  4572  				Resources: map[string]*ResourceState{
  4573  					"aws_instance.bar": &ResourceState{
  4574  						Type: "aws_instance",
  4575  						Primary: &InstanceState{
  4576  							ID: "bar",
  4577  							Attributes: map[string]string{
  4578  								"require_new": "abc",
  4579  							},
  4580  						},
  4581  					},
  4582  				},
  4583  			},
  4584  		},
  4585  	}
  4586  	ctx := testContext2(t, &ContextOpts{
  4587  		Module: m,
  4588  		Providers: map[string]ResourceProviderFactory{
  4589  			"aws": testProviderFuncFixed(p),
  4590  		},
  4591  		Provisioners: map[string]ResourceProvisionerFactory{
  4592  			"shell": testProvisionerFuncFixed(pr),
  4593  		},
  4594  		State: state,
  4595  	})
  4596  
  4597  	if _, err := ctx.Plan(); err != nil {
  4598  		t.Fatalf("err: %s", err)
  4599  	}
  4600  
  4601  	state, err := ctx.Apply()
  4602  	if err == nil {
  4603  		t.Fatal("should error")
  4604  	}
  4605  
  4606  	actual := strings.TrimSpace(state.String())
  4607  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailCreateBeforeDestroyStr)
  4608  	if actual != expected {
  4609  		t.Fatalf("bad: \n%s", actual)
  4610  	}
  4611  }
  4612  
  4613  func TestContext2Apply_error_createBeforeDestroy(t *testing.T) {
  4614  	m := testModule(t, "apply-error-create-before")
  4615  	p := testProvider("aws")
  4616  	state := &State{
  4617  		Modules: []*ModuleState{
  4618  			&ModuleState{
  4619  				Path: rootModulePath,
  4620  				Resources: map[string]*ResourceState{
  4621  					"aws_instance.bar": &ResourceState{
  4622  						Type: "aws_instance",
  4623  						Primary: &InstanceState{
  4624  							ID: "bar",
  4625  							Attributes: map[string]string{
  4626  								"require_new": "abc",
  4627  							},
  4628  						},
  4629  					},
  4630  				},
  4631  			},
  4632  		},
  4633  	}
  4634  	ctx := testContext2(t, &ContextOpts{
  4635  		Module: m,
  4636  		Providers: map[string]ResourceProviderFactory{
  4637  			"aws": testProviderFuncFixed(p),
  4638  		},
  4639  		State: state,
  4640  	})
  4641  	p.ApplyFn = func(info *InstanceInfo, is *InstanceState, id *InstanceDiff) (*InstanceState, error) {
  4642  		return nil, fmt.Errorf("error")
  4643  	}
  4644  	p.DiffFn = testDiffFn
  4645  
  4646  	if _, err := ctx.Plan(); err != nil {
  4647  		t.Fatalf("err: %s", err)
  4648  	}
  4649  
  4650  	state, err := ctx.Apply()
  4651  	if err == nil {
  4652  		t.Fatal("should have error")
  4653  	}
  4654  
  4655  	actual := strings.TrimSpace(state.String())
  4656  	expected := strings.TrimSpace(testTerraformApplyErrorCreateBeforeDestroyStr)
  4657  	if actual != expected {
  4658  		t.Fatalf("bad: \n%s\n\nExpected:\n\n%s", actual, expected)
  4659  	}
  4660  }
  4661  
  4662  func TestContext2Apply_errorDestroy_createBeforeDestroy(t *testing.T) {
  4663  	m := testModule(t, "apply-error-create-before")
  4664  	p := testProvider("aws")
  4665  	state := &State{
  4666  		Modules: []*ModuleState{
  4667  			&ModuleState{
  4668  				Path: rootModulePath,
  4669  				Resources: map[string]*ResourceState{
  4670  					"aws_instance.bar": &ResourceState{
  4671  						Type: "aws_instance",
  4672  						Primary: &InstanceState{
  4673  							ID: "bar",
  4674  							Attributes: map[string]string{
  4675  								"require_new": "abc",
  4676  							},
  4677  						},
  4678  					},
  4679  				},
  4680  			},
  4681  		},
  4682  	}
  4683  	ctx := testContext2(t, &ContextOpts{
  4684  		Module: m,
  4685  		Providers: map[string]ResourceProviderFactory{
  4686  			"aws": testProviderFuncFixed(p),
  4687  		},
  4688  		State: state,
  4689  	})
  4690  	p.ApplyFn = func(info *InstanceInfo, is *InstanceState, id *InstanceDiff) (*InstanceState, error) {
  4691  		// Fail the destroy!
  4692  		if id.Destroy {
  4693  			return is, fmt.Errorf("error")
  4694  		}
  4695  
  4696  		// Create should work
  4697  		is = &InstanceState{
  4698  			ID: "foo",
  4699  		}
  4700  		return is, nil
  4701  	}
  4702  	p.DiffFn = testDiffFn
  4703  
  4704  	if _, err := ctx.Plan(); err != nil {
  4705  		t.Fatalf("err: %s", err)
  4706  	}
  4707  
  4708  	state, err := ctx.Apply()
  4709  	if err == nil {
  4710  		t.Fatal("should have error")
  4711  	}
  4712  
  4713  	actual := strings.TrimSpace(state.String())
  4714  	expected := strings.TrimSpace(testTerraformApplyErrorDestroyCreateBeforeDestroyStr)
  4715  	if actual != expected {
  4716  		t.Fatalf("bad: actual:\n%s\n\nexpected:\n%s", actual, expected)
  4717  	}
  4718  }
  4719  
  4720  func TestContext2Apply_multiDepose_createBeforeDestroy(t *testing.T) {
  4721  	m := testModule(t, "apply-multi-depose-create-before-destroy")
  4722  	p := testProvider("aws")
  4723  	p.DiffFn = testDiffFn
  4724  	ps := map[string]ResourceProviderFactory{"aws": testProviderFuncFixed(p)}
  4725  	state := &State{
  4726  		Modules: []*ModuleState{
  4727  			&ModuleState{
  4728  				Path: rootModulePath,
  4729  				Resources: map[string]*ResourceState{
  4730  					"aws_instance.web": &ResourceState{
  4731  						Type:    "aws_instance",
  4732  						Primary: &InstanceState{ID: "foo"},
  4733  					},
  4734  				},
  4735  			},
  4736  		},
  4737  	}
  4738  
  4739  	ctx := testContext2(t, &ContextOpts{
  4740  		Module:    m,
  4741  		Providers: ps,
  4742  		State:     state,
  4743  	})
  4744  	createdInstanceId := "bar"
  4745  	// Create works
  4746  	createFunc := func(is *InstanceState) (*InstanceState, error) {
  4747  		return &InstanceState{ID: createdInstanceId}, nil
  4748  	}
  4749  	// Destroy starts broken
  4750  	destroyFunc := func(is *InstanceState) (*InstanceState, error) {
  4751  		return is, fmt.Errorf("destroy failed")
  4752  	}
  4753  	p.ApplyFn = func(info *InstanceInfo, is *InstanceState, id *InstanceDiff) (*InstanceState, error) {
  4754  		if id.Destroy {
  4755  			return destroyFunc(is)
  4756  		} else {
  4757  			return createFunc(is)
  4758  		}
  4759  	}
  4760  
  4761  	if _, err := ctx.Plan(); err != nil {
  4762  		t.Fatalf("err: %s", err)
  4763  	}
  4764  
  4765  	// Destroy is broken, so even though CBD successfully replaces the instance,
  4766  	// we'll have to save the Deposed instance to destroy later
  4767  	state, err := ctx.Apply()
  4768  	if err == nil {
  4769  		t.Fatal("should have error")
  4770  	}
  4771  
  4772  	checkStateString(t, state, `
  4773  aws_instance.web: (1 deposed)
  4774    ID = bar
  4775    Deposed ID 1 = foo
  4776  	`)
  4777  
  4778  	createdInstanceId = "baz"
  4779  	ctx = testContext2(t, &ContextOpts{
  4780  		Module:    m,
  4781  		Providers: ps,
  4782  		State:     state,
  4783  	})
  4784  
  4785  	if _, err := ctx.Plan(); err != nil {
  4786  		t.Fatalf("err: %s", err)
  4787  	}
  4788  
  4789  	// We're replacing the primary instance once again. Destroy is _still_
  4790  	// broken, so the Deposed list gets longer
  4791  	state, err = ctx.Apply()
  4792  	if err == nil {
  4793  		t.Fatal("should have error")
  4794  	}
  4795  
  4796  	checkStateString(t, state, `
  4797  aws_instance.web: (2 deposed)
  4798    ID = baz
  4799    Deposed ID 1 = foo
  4800    Deposed ID 2 = bar
  4801  	`)
  4802  
  4803  	// Destroy partially fixed!
  4804  	destroyFunc = func(is *InstanceState) (*InstanceState, error) {
  4805  		if is.ID == "foo" || is.ID == "baz" {
  4806  			return nil, nil
  4807  		} else {
  4808  			return is, fmt.Errorf("destroy partially failed")
  4809  		}
  4810  	}
  4811  
  4812  	createdInstanceId = "qux"
  4813  	if _, err := ctx.Plan(); err != nil {
  4814  		t.Fatalf("err: %s", err)
  4815  	}
  4816  	state, err = ctx.Apply()
  4817  	// Expect error because 1/2 of Deposed destroys failed
  4818  	if err == nil {
  4819  		t.Fatal("should have error")
  4820  	}
  4821  
  4822  	// foo and baz are now gone, bar sticks around
  4823  	checkStateString(t, state, `
  4824  aws_instance.web: (1 deposed)
  4825    ID = qux
  4826    Deposed ID 1 = bar
  4827  	`)
  4828  
  4829  	// Destroy working fully!
  4830  	destroyFunc = func(is *InstanceState) (*InstanceState, error) {
  4831  		return nil, nil
  4832  	}
  4833  
  4834  	createdInstanceId = "quux"
  4835  	if _, err := ctx.Plan(); err != nil {
  4836  		t.Fatalf("err: %s", err)
  4837  	}
  4838  	state, err = ctx.Apply()
  4839  	if err != nil {
  4840  		t.Fatal("should not have error:", err)
  4841  	}
  4842  
  4843  	// And finally the state is clean
  4844  	checkStateString(t, state, `
  4845  aws_instance.web:
  4846    ID = quux
  4847  	`)
  4848  }
  4849  
  4850  func TestContext2Apply_provisionerResourceRef(t *testing.T) {
  4851  	m := testModule(t, "apply-provisioner-resource-ref")
  4852  	p := testProvider("aws")
  4853  	pr := testProvisioner()
  4854  	p.ApplyFn = testApplyFn
  4855  	p.DiffFn = testDiffFn
  4856  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  4857  		val, ok := c.Config["foo"]
  4858  		if !ok || val != "2" {
  4859  			t.Fatalf("bad value for foo: %v %#v", val, c)
  4860  		}
  4861  
  4862  		return nil
  4863  	}
  4864  
  4865  	ctx := testContext2(t, &ContextOpts{
  4866  		Module: m,
  4867  		Providers: map[string]ResourceProviderFactory{
  4868  			"aws": testProviderFuncFixed(p),
  4869  		},
  4870  		Provisioners: map[string]ResourceProvisionerFactory{
  4871  			"shell": testProvisionerFuncFixed(pr),
  4872  		},
  4873  	})
  4874  
  4875  	if _, err := ctx.Plan(); err != nil {
  4876  		t.Fatalf("err: %s", err)
  4877  	}
  4878  
  4879  	state, err := ctx.Apply()
  4880  	if err != nil {
  4881  		t.Fatalf("err: %s", err)
  4882  	}
  4883  
  4884  	actual := strings.TrimSpace(state.String())
  4885  	expected := strings.TrimSpace(testTerraformApplyProvisionerResourceRefStr)
  4886  	if actual != expected {
  4887  		t.Fatalf("bad: \n%s", actual)
  4888  	}
  4889  
  4890  	// Verify apply was invoked
  4891  	if !pr.ApplyCalled {
  4892  		t.Fatalf("provisioner not invoked")
  4893  	}
  4894  }
  4895  
  4896  func TestContext2Apply_provisionerSelfRef(t *testing.T) {
  4897  	m := testModule(t, "apply-provisioner-self-ref")
  4898  	p := testProvider("aws")
  4899  	pr := testProvisioner()
  4900  	p.ApplyFn = testApplyFn
  4901  	p.DiffFn = testDiffFn
  4902  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  4903  		val, ok := c.Config["command"]
  4904  		if !ok || val != "bar" {
  4905  			t.Fatalf("bad value for command: %v %#v", val, c)
  4906  		}
  4907  
  4908  		return nil
  4909  	}
  4910  
  4911  	ctx := testContext2(t, &ContextOpts{
  4912  		Module: m,
  4913  		Providers: map[string]ResourceProviderFactory{
  4914  			"aws": testProviderFuncFixed(p),
  4915  		},
  4916  		Provisioners: map[string]ResourceProvisionerFactory{
  4917  			"shell": testProvisionerFuncFixed(pr),
  4918  		},
  4919  	})
  4920  
  4921  	if _, err := ctx.Plan(); err != nil {
  4922  		t.Fatalf("err: %s", err)
  4923  	}
  4924  
  4925  	state, err := ctx.Apply()
  4926  	if err != nil {
  4927  		t.Fatalf("err: %s", err)
  4928  	}
  4929  
  4930  	actual := strings.TrimSpace(state.String())
  4931  	expected := strings.TrimSpace(testTerraformApplyProvisionerSelfRefStr)
  4932  	if actual != expected {
  4933  		t.Fatalf("bad: \n%s", actual)
  4934  	}
  4935  
  4936  	// Verify apply was invoked
  4937  	if !pr.ApplyCalled {
  4938  		t.Fatalf("provisioner not invoked")
  4939  	}
  4940  }
  4941  
  4942  func TestContext2Apply_provisionerMultiSelfRef(t *testing.T) {
  4943  	var lock sync.Mutex
  4944  	commands := make([]string, 0, 5)
  4945  
  4946  	m := testModule(t, "apply-provisioner-multi-self-ref")
  4947  	p := testProvider("aws")
  4948  	pr := testProvisioner()
  4949  	p.ApplyFn = testApplyFn
  4950  	p.DiffFn = testDiffFn
  4951  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  4952  		lock.Lock()
  4953  		defer lock.Unlock()
  4954  
  4955  		val, ok := c.Config["command"]
  4956  		if !ok {
  4957  			t.Fatalf("bad value for command: %v %#v", val, c)
  4958  		}
  4959  
  4960  		commands = append(commands, val.(string))
  4961  		return nil
  4962  	}
  4963  
  4964  	ctx := testContext2(t, &ContextOpts{
  4965  		Module: m,
  4966  		Providers: map[string]ResourceProviderFactory{
  4967  			"aws": testProviderFuncFixed(p),
  4968  		},
  4969  		Provisioners: map[string]ResourceProvisionerFactory{
  4970  			"shell": testProvisionerFuncFixed(pr),
  4971  		},
  4972  	})
  4973  
  4974  	if _, err := ctx.Plan(); err != nil {
  4975  		t.Fatalf("err: %s", err)
  4976  	}
  4977  
  4978  	state, err := ctx.Apply()
  4979  	if err != nil {
  4980  		t.Fatalf("err: %s", err)
  4981  	}
  4982  
  4983  	actual := strings.TrimSpace(state.String())
  4984  	expected := strings.TrimSpace(testTerraformApplyProvisionerMultiSelfRefStr)
  4985  	if actual != expected {
  4986  		t.Fatalf("bad: \n%s", actual)
  4987  	}
  4988  
  4989  	// Verify apply was invoked
  4990  	if !pr.ApplyCalled {
  4991  		t.Fatalf("provisioner not invoked")
  4992  	}
  4993  
  4994  	// Verify our result
  4995  	sort.Strings(commands)
  4996  	expectedCommands := []string{"number 0", "number 1", "number 2"}
  4997  	if !reflect.DeepEqual(commands, expectedCommands) {
  4998  		t.Fatalf("bad: %#v", commands)
  4999  	}
  5000  }
  5001  
  5002  // Provisioner should NOT run on a diff, only create
  5003  func TestContext2Apply_Provisioner_Diff(t *testing.T) {
  5004  	m := testModule(t, "apply-provisioner-diff")
  5005  	p := testProvider("aws")
  5006  	pr := testProvisioner()
  5007  	p.ApplyFn = testApplyFn
  5008  	p.DiffFn = testDiffFn
  5009  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  5010  		return nil
  5011  	}
  5012  	ctx := testContext2(t, &ContextOpts{
  5013  		Module: m,
  5014  		Providers: map[string]ResourceProviderFactory{
  5015  			"aws": testProviderFuncFixed(p),
  5016  		},
  5017  		Provisioners: map[string]ResourceProvisionerFactory{
  5018  			"shell": testProvisionerFuncFixed(pr),
  5019  		},
  5020  	})
  5021  
  5022  	if _, err := ctx.Plan(); err != nil {
  5023  		t.Fatalf("err: %s", err)
  5024  	}
  5025  
  5026  	state, err := ctx.Apply()
  5027  	if err != nil {
  5028  		t.Fatalf("err: %s", err)
  5029  	}
  5030  
  5031  	actual := strings.TrimSpace(state.String())
  5032  	expected := strings.TrimSpace(testTerraformApplyProvisionerDiffStr)
  5033  	if actual != expected {
  5034  		t.Fatalf("bad: \n%s", actual)
  5035  	}
  5036  
  5037  	// Verify apply was invoked
  5038  	if !pr.ApplyCalled {
  5039  		t.Fatalf("provisioner not invoked")
  5040  	}
  5041  	pr.ApplyCalled = false
  5042  
  5043  	// Change the state to force a diff
  5044  	mod := state.RootModule()
  5045  	mod.Resources["aws_instance.bar"].Primary.Attributes["foo"] = "baz"
  5046  
  5047  	// Re-create context with state
  5048  	ctx = testContext2(t, &ContextOpts{
  5049  		Module: m,
  5050  		Providers: map[string]ResourceProviderFactory{
  5051  			"aws": testProviderFuncFixed(p),
  5052  		},
  5053  		Provisioners: map[string]ResourceProvisionerFactory{
  5054  			"shell": testProvisionerFuncFixed(pr),
  5055  		},
  5056  		State: state,
  5057  	})
  5058  
  5059  	if _, err := ctx.Plan(); err != nil {
  5060  		t.Fatalf("err: %s", err)
  5061  	}
  5062  
  5063  	state2, err := ctx.Apply()
  5064  	if err != nil {
  5065  		t.Fatalf("err: %s", err)
  5066  	}
  5067  
  5068  	actual = strings.TrimSpace(state2.String())
  5069  	if actual != expected {
  5070  		t.Fatalf("bad: \n%s", actual)
  5071  	}
  5072  
  5073  	// Verify apply was NOT invoked
  5074  	if pr.ApplyCalled {
  5075  		t.Fatalf("provisioner invoked")
  5076  	}
  5077  }
  5078  
  5079  func TestContext2Apply_outputDiffVars(t *testing.T) {
  5080  	m := testModule(t, "apply-good")
  5081  	p := testProvider("aws")
  5082  	s := &State{
  5083  		Modules: []*ModuleState{
  5084  			&ModuleState{
  5085  				Path: rootModulePath,
  5086  				Resources: map[string]*ResourceState{
  5087  					"aws_instance.baz": &ResourceState{
  5088  						Type: "aws_instance",
  5089  						Primary: &InstanceState{
  5090  							ID: "bar",
  5091  						},
  5092  					},
  5093  				},
  5094  			},
  5095  		},
  5096  	}
  5097  	ctx := testContext2(t, &ContextOpts{
  5098  		Module: m,
  5099  		Providers: map[string]ResourceProviderFactory{
  5100  			"aws": testProviderFuncFixed(p),
  5101  		},
  5102  		State: s,
  5103  	})
  5104  
  5105  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  5106  		for k, ad := range d.Attributes {
  5107  			if ad.NewComputed {
  5108  				return nil, fmt.Errorf("%s: computed", k)
  5109  			}
  5110  		}
  5111  
  5112  		result := s.MergeDiff(d)
  5113  		result.ID = "foo"
  5114  		return result, nil
  5115  	}
  5116  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  5117  		return &InstanceDiff{
  5118  			Attributes: map[string]*ResourceAttrDiff{
  5119  				"foo": &ResourceAttrDiff{
  5120  					NewComputed: true,
  5121  					Type:        DiffAttrOutput,
  5122  				},
  5123  				"bar": &ResourceAttrDiff{
  5124  					New: "baz",
  5125  				},
  5126  			},
  5127  		}, nil
  5128  	}
  5129  
  5130  	if _, err := ctx.Plan(); err != nil {
  5131  		t.Fatalf("err: %s", err)
  5132  	}
  5133  	if _, err := ctx.Apply(); err != nil {
  5134  		t.Fatalf("err: %s", err)
  5135  	}
  5136  }
  5137  
  5138  func TestContext2Apply_Provisioner_ConnInfo(t *testing.T) {
  5139  	m := testModule(t, "apply-provisioner-conninfo")
  5140  	p := testProvider("aws")
  5141  	pr := testProvisioner()
  5142  
  5143  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  5144  		if s.Ephemeral.ConnInfo == nil {
  5145  			t.Fatalf("ConnInfo not initialized")
  5146  		}
  5147  
  5148  		result, _ := testApplyFn(info, s, d)
  5149  		result.Ephemeral.ConnInfo = map[string]string{
  5150  			"type": "ssh",
  5151  			"host": "127.0.0.1",
  5152  			"port": "22",
  5153  		}
  5154  		return result, nil
  5155  	}
  5156  	p.DiffFn = testDiffFn
  5157  
  5158  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  5159  		conn := rs.Ephemeral.ConnInfo
  5160  		if conn["type"] != "telnet" {
  5161  			t.Fatalf("Bad: %#v", conn)
  5162  		}
  5163  		if conn["host"] != "127.0.0.1" {
  5164  			t.Fatalf("Bad: %#v", conn)
  5165  		}
  5166  		if conn["port"] != "2222" {
  5167  			t.Fatalf("Bad: %#v", conn)
  5168  		}
  5169  		if conn["user"] != "superuser" {
  5170  			t.Fatalf("Bad: %#v", conn)
  5171  		}
  5172  		if conn["pass"] != "test" {
  5173  			t.Fatalf("Bad: %#v", conn)
  5174  		}
  5175  
  5176  		return nil
  5177  	}
  5178  
  5179  	ctx := testContext2(t, &ContextOpts{
  5180  		Module: m,
  5181  		Providers: map[string]ResourceProviderFactory{
  5182  			"aws": testProviderFuncFixed(p),
  5183  		},
  5184  		Provisioners: map[string]ResourceProvisionerFactory{
  5185  			"shell": testProvisionerFuncFixed(pr),
  5186  		},
  5187  		Variables: map[string]string{
  5188  			"value": "1",
  5189  			"pass":  "test",
  5190  		},
  5191  	})
  5192  
  5193  	if _, err := ctx.Plan(); err != nil {
  5194  		t.Fatalf("err: %s", err)
  5195  	}
  5196  
  5197  	state, err := ctx.Apply()
  5198  	if err != nil {
  5199  		t.Fatalf("err: %s", err)
  5200  	}
  5201  
  5202  	actual := strings.TrimSpace(state.String())
  5203  	expected := strings.TrimSpace(testTerraformApplyProvisionerStr)
  5204  	if actual != expected {
  5205  		t.Fatalf("bad: \n%s", actual)
  5206  	}
  5207  
  5208  	// Verify apply was invoked
  5209  	if !pr.ApplyCalled {
  5210  		t.Fatalf("provisioner not invoked")
  5211  	}
  5212  }
  5213  
  5214  func TestContext2Apply_destroy(t *testing.T) {
  5215  	m := testModule(t, "apply-destroy")
  5216  	h := new(HookRecordApplyOrder)
  5217  	p := testProvider("aws")
  5218  	p.ApplyFn = testApplyFn
  5219  	p.DiffFn = testDiffFn
  5220  	ctx := testContext2(t, &ContextOpts{
  5221  		Module: m,
  5222  		Hooks:  []Hook{h},
  5223  		Providers: map[string]ResourceProviderFactory{
  5224  			"aws": testProviderFuncFixed(p),
  5225  		},
  5226  	})
  5227  
  5228  	// First plan and apply a create operation
  5229  	if _, err := ctx.Plan(); err != nil {
  5230  		t.Fatalf("err: %s", err)
  5231  	}
  5232  
  5233  	state, err := ctx.Apply()
  5234  	if err != nil {
  5235  		t.Fatalf("err: %s", err)
  5236  	}
  5237  
  5238  	// Next, plan and apply a destroy operation
  5239  	h.Active = true
  5240  	ctx = testContext2(t, &ContextOpts{
  5241  		Destroy: true,
  5242  		State:   state,
  5243  		Module:  m,
  5244  		Hooks:   []Hook{h},
  5245  		Providers: map[string]ResourceProviderFactory{
  5246  			"aws": testProviderFuncFixed(p),
  5247  		},
  5248  	})
  5249  
  5250  	if _, err := ctx.Plan(); err != nil {
  5251  		t.Fatalf("err: %s", err)
  5252  	}
  5253  
  5254  	state, err = ctx.Apply()
  5255  	if err != nil {
  5256  		t.Fatalf("err: %s", err)
  5257  	}
  5258  
  5259  	// Test that things were destroyed
  5260  	actual := strings.TrimSpace(state.String())
  5261  	expected := strings.TrimSpace(testTerraformApplyDestroyStr)
  5262  	if actual != expected {
  5263  		t.Fatalf("bad: \n%s", actual)
  5264  	}
  5265  
  5266  	// Test that things were destroyed _in the right order_
  5267  	expected2 := []string{"aws_instance.bar", "aws_instance.foo"}
  5268  	actual2 := h.IDs
  5269  	if !reflect.DeepEqual(actual2, expected2) {
  5270  		t.Fatalf("expected: %#v\n\ngot:%#v", expected2, actual2)
  5271  	}
  5272  }
  5273  
  5274  func TestContext2Apply_destroyOutputs(t *testing.T) {
  5275  	m := testModule(t, "apply-destroy-outputs")
  5276  	h := new(HookRecordApplyOrder)
  5277  	p := testProvider("aws")
  5278  	p.ApplyFn = testApplyFn
  5279  	p.DiffFn = testDiffFn
  5280  	ctx := testContext2(t, &ContextOpts{
  5281  		Module: m,
  5282  		Hooks:  []Hook{h},
  5283  		Providers: map[string]ResourceProviderFactory{
  5284  			"aws": testProviderFuncFixed(p),
  5285  		},
  5286  	})
  5287  
  5288  	// First plan and apply a create operation
  5289  	if _, err := ctx.Plan(); err != nil {
  5290  		t.Fatalf("err: %s", err)
  5291  	}
  5292  
  5293  	state, err := ctx.Apply()
  5294  
  5295  	if err != nil {
  5296  		t.Fatalf("err: %s", err)
  5297  	}
  5298  
  5299  	// Next, plan and apply a destroy operation
  5300  	h.Active = true
  5301  	ctx = testContext2(t, &ContextOpts{
  5302  		Destroy: true,
  5303  		State:   state,
  5304  		Module:  m,
  5305  		Hooks:   []Hook{h},
  5306  		Providers: map[string]ResourceProviderFactory{
  5307  			"aws": testProviderFuncFixed(p),
  5308  		},
  5309  	})
  5310  
  5311  	if _, err := ctx.Plan(); err != nil {
  5312  		t.Fatalf("err: %s", err)
  5313  	}
  5314  
  5315  	state, err = ctx.Apply()
  5316  	if err != nil {
  5317  		t.Fatalf("err: %s", err)
  5318  	}
  5319  
  5320  	mod := state.RootModule()
  5321  	if len(mod.Resources) > 0 {
  5322  		t.Fatalf("bad: %#v", mod)
  5323  	}
  5324  }
  5325  
  5326  func TestContext2Apply_destroyOrphan(t *testing.T) {
  5327  	m := testModule(t, "apply-error")
  5328  	p := testProvider("aws")
  5329  	s := &State{
  5330  		Modules: []*ModuleState{
  5331  			&ModuleState{
  5332  				Path: rootModulePath,
  5333  				Resources: map[string]*ResourceState{
  5334  					"aws_instance.baz": &ResourceState{
  5335  						Type: "aws_instance",
  5336  						Primary: &InstanceState{
  5337  							ID: "bar",
  5338  						},
  5339  					},
  5340  				},
  5341  			},
  5342  		},
  5343  	}
  5344  	ctx := testContext2(t, &ContextOpts{
  5345  		Module: m,
  5346  		Providers: map[string]ResourceProviderFactory{
  5347  			"aws": testProviderFuncFixed(p),
  5348  		},
  5349  		State: s,
  5350  	})
  5351  
  5352  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  5353  		if d.Destroy {
  5354  			return nil, nil
  5355  		}
  5356  
  5357  		result := s.MergeDiff(d)
  5358  		result.ID = "foo"
  5359  		return result, nil
  5360  	}
  5361  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  5362  		return &InstanceDiff{
  5363  			Attributes: map[string]*ResourceAttrDiff{
  5364  				"num": &ResourceAttrDiff{
  5365  					New: "bar",
  5366  				},
  5367  			},
  5368  		}, nil
  5369  	}
  5370  
  5371  	if _, err := ctx.Plan(); err != nil {
  5372  		t.Fatalf("err: %s", err)
  5373  	}
  5374  
  5375  	state, err := ctx.Apply()
  5376  	if err != nil {
  5377  		t.Fatalf("err: %s", err)
  5378  	}
  5379  
  5380  	mod := state.RootModule()
  5381  	if _, ok := mod.Resources["aws_instance.baz"]; ok {
  5382  		t.Fatalf("bad: %#v", mod.Resources)
  5383  	}
  5384  }
  5385  
  5386  func TestContext2Apply_destroyTaintedProvisioner(t *testing.T) {
  5387  	m := testModule(t, "apply-destroy-provisioner")
  5388  	p := testProvider("aws")
  5389  	pr := testProvisioner()
  5390  	p.ApplyFn = testApplyFn
  5391  	p.DiffFn = testDiffFn
  5392  
  5393  	called := false
  5394  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  5395  		called = true
  5396  		return nil
  5397  	}
  5398  
  5399  	s := &State{
  5400  		Modules: []*ModuleState{
  5401  			&ModuleState{
  5402  				Path: rootModulePath,
  5403  				Resources: map[string]*ResourceState{
  5404  					"aws_instance.foo": &ResourceState{
  5405  						Type: "aws_instance",
  5406  						Tainted: []*InstanceState{
  5407  							&InstanceState{
  5408  								ID: "bar",
  5409  								Attributes: map[string]string{
  5410  									"id": "bar",
  5411  								},
  5412  							},
  5413  						},
  5414  					},
  5415  				},
  5416  			},
  5417  		},
  5418  	}
  5419  
  5420  	ctx := testContext2(t, &ContextOpts{
  5421  		Module: m,
  5422  		Providers: map[string]ResourceProviderFactory{
  5423  			"aws": testProviderFuncFixed(p),
  5424  		},
  5425  		Provisioners: map[string]ResourceProvisionerFactory{
  5426  			"shell": testProvisionerFuncFixed(pr),
  5427  		},
  5428  		State:   s,
  5429  		Destroy: true,
  5430  	})
  5431  
  5432  	if _, err := ctx.Plan(); err != nil {
  5433  		t.Fatalf("err: %s", err)
  5434  	}
  5435  
  5436  	state, err := ctx.Apply()
  5437  	if err != nil {
  5438  		t.Fatalf("err: %s", err)
  5439  	}
  5440  
  5441  	if called {
  5442  		t.Fatal("provisioner should not be called")
  5443  	}
  5444  
  5445  	actual := strings.TrimSpace(state.String())
  5446  	expected := strings.TrimSpace("<no state>")
  5447  	if actual != expected {
  5448  		t.Fatalf("bad: \n%s", actual)
  5449  	}
  5450  }
  5451  
  5452  func TestContext2Apply_error(t *testing.T) {
  5453  	errored := false
  5454  
  5455  	m := testModule(t, "apply-error")
  5456  	p := testProvider("aws")
  5457  	ctx := testContext2(t, &ContextOpts{
  5458  		Module: m,
  5459  		Providers: map[string]ResourceProviderFactory{
  5460  			"aws": testProviderFuncFixed(p),
  5461  		},
  5462  	})
  5463  
  5464  	p.ApplyFn = func(*InstanceInfo, *InstanceState, *InstanceDiff) (*InstanceState, error) {
  5465  		if errored {
  5466  			state := &InstanceState{
  5467  				ID: "bar",
  5468  			}
  5469  			return state, fmt.Errorf("error")
  5470  		}
  5471  		errored = true
  5472  
  5473  		return &InstanceState{
  5474  			ID: "foo",
  5475  			Attributes: map[string]string{
  5476  				"num": "2",
  5477  			},
  5478  		}, nil
  5479  	}
  5480  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  5481  		return &InstanceDiff{
  5482  			Attributes: map[string]*ResourceAttrDiff{
  5483  				"num": &ResourceAttrDiff{
  5484  					New: "bar",
  5485  				},
  5486  			},
  5487  		}, nil
  5488  	}
  5489  
  5490  	if _, err := ctx.Plan(); err != nil {
  5491  		t.Fatalf("err: %s", err)
  5492  	}
  5493  
  5494  	state, err := ctx.Apply()
  5495  	if err == nil {
  5496  		t.Fatal("should have error")
  5497  	}
  5498  
  5499  	actual := strings.TrimSpace(state.String())
  5500  	expected := strings.TrimSpace(testTerraformApplyErrorStr)
  5501  	if actual != expected {
  5502  		t.Fatalf("bad: \n%s", actual)
  5503  	}
  5504  }
  5505  
  5506  func TestContext2Apply_errorPartial(t *testing.T) {
  5507  	errored := false
  5508  
  5509  	m := testModule(t, "apply-error")
  5510  	p := testProvider("aws")
  5511  	s := &State{
  5512  		Modules: []*ModuleState{
  5513  			&ModuleState{
  5514  				Path: rootModulePath,
  5515  				Resources: map[string]*ResourceState{
  5516  					"aws_instance.bar": &ResourceState{
  5517  						Type: "aws_instance",
  5518  						Primary: &InstanceState{
  5519  							ID: "bar",
  5520  						},
  5521  					},
  5522  				},
  5523  			},
  5524  		},
  5525  	}
  5526  	ctx := testContext2(t, &ContextOpts{
  5527  		Module: m,
  5528  		Providers: map[string]ResourceProviderFactory{
  5529  			"aws": testProviderFuncFixed(p),
  5530  		},
  5531  		State: s,
  5532  	})
  5533  
  5534  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  5535  		if errored {
  5536  			return s, fmt.Errorf("error")
  5537  		}
  5538  		errored = true
  5539  
  5540  		return &InstanceState{
  5541  			ID: "foo",
  5542  			Attributes: map[string]string{
  5543  				"num": "2",
  5544  			},
  5545  		}, nil
  5546  	}
  5547  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  5548  		return &InstanceDiff{
  5549  			Attributes: map[string]*ResourceAttrDiff{
  5550  				"num": &ResourceAttrDiff{
  5551  					New: "bar",
  5552  				},
  5553  			},
  5554  		}, nil
  5555  	}
  5556  
  5557  	if _, err := ctx.Plan(); err != nil {
  5558  		t.Fatalf("err: %s", err)
  5559  	}
  5560  
  5561  	state, err := ctx.Apply()
  5562  	if err == nil {
  5563  		t.Fatal("should have error")
  5564  	}
  5565  
  5566  	mod := state.RootModule()
  5567  	if len(mod.Resources) != 2 {
  5568  		t.Fatalf("bad: %#v", mod.Resources)
  5569  	}
  5570  
  5571  	actual := strings.TrimSpace(state.String())
  5572  	expected := strings.TrimSpace(testTerraformApplyErrorPartialStr)
  5573  	if actual != expected {
  5574  		t.Fatalf("bad: \n%s", actual)
  5575  	}
  5576  }
  5577  
  5578  func TestContext2Apply_hook(t *testing.T) {
  5579  	m := testModule(t, "apply-good")
  5580  	h := new(MockHook)
  5581  	p := testProvider("aws")
  5582  	p.ApplyFn = testApplyFn
  5583  	p.DiffFn = testDiffFn
  5584  	ctx := testContext2(t, &ContextOpts{
  5585  		Module: m,
  5586  		Hooks:  []Hook{h},
  5587  		Providers: map[string]ResourceProviderFactory{
  5588  			"aws": testProviderFuncFixed(p),
  5589  		},
  5590  	})
  5591  
  5592  	if _, err := ctx.Plan(); err != nil {
  5593  		t.Fatalf("err: %s", err)
  5594  	}
  5595  
  5596  	if _, err := ctx.Apply(); err != nil {
  5597  		t.Fatalf("err: %s", err)
  5598  	}
  5599  
  5600  	if !h.PreApplyCalled {
  5601  		t.Fatal("should be called")
  5602  	}
  5603  	if !h.PostApplyCalled {
  5604  		t.Fatal("should be called")
  5605  	}
  5606  	if !h.PostStateUpdateCalled {
  5607  		t.Fatalf("should call post state update")
  5608  	}
  5609  }
  5610  
  5611  func TestContext2Apply_idAttr(t *testing.T) {
  5612  	m := testModule(t, "apply-idattr")
  5613  	p := testProvider("aws")
  5614  	ctx := testContext2(t, &ContextOpts{
  5615  		Module: m,
  5616  		Providers: map[string]ResourceProviderFactory{
  5617  			"aws": testProviderFuncFixed(p),
  5618  		},
  5619  	})
  5620  
  5621  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  5622  		result := s.MergeDiff(d)
  5623  		result.ID = "foo"
  5624  		result.Attributes = map[string]string{
  5625  			"id": "bar",
  5626  		}
  5627  
  5628  		return result, nil
  5629  	}
  5630  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  5631  		return &InstanceDiff{
  5632  			Attributes: map[string]*ResourceAttrDiff{
  5633  				"num": &ResourceAttrDiff{
  5634  					New: "bar",
  5635  				},
  5636  			},
  5637  		}, nil
  5638  	}
  5639  
  5640  	if _, err := ctx.Plan(); err != nil {
  5641  		t.Fatalf("err: %s", err)
  5642  	}
  5643  
  5644  	state, err := ctx.Apply()
  5645  	if err != nil {
  5646  		t.Fatalf("err: %s", err)
  5647  	}
  5648  
  5649  	mod := state.RootModule()
  5650  	rs, ok := mod.Resources["aws_instance.foo"]
  5651  	if !ok {
  5652  		t.Fatal("not in state")
  5653  	}
  5654  	if rs.Primary.ID != "foo" {
  5655  		t.Fatalf("bad: %#v", rs.Primary.ID)
  5656  	}
  5657  	if rs.Primary.Attributes["id"] != "foo" {
  5658  		t.Fatalf("bad: %#v", rs.Primary.Attributes)
  5659  	}
  5660  }
  5661  
  5662  func TestContext2Apply_output(t *testing.T) {
  5663  	m := testModule(t, "apply-output")
  5664  	p := testProvider("aws")
  5665  	p.ApplyFn = testApplyFn
  5666  	p.DiffFn = testDiffFn
  5667  	ctx := testContext2(t, &ContextOpts{
  5668  		Module: m,
  5669  		Providers: map[string]ResourceProviderFactory{
  5670  			"aws": testProviderFuncFixed(p),
  5671  		},
  5672  	})
  5673  
  5674  	if _, err := ctx.Plan(); err != nil {
  5675  		t.Fatalf("err: %s", err)
  5676  	}
  5677  
  5678  	state, err := ctx.Apply()
  5679  	if err != nil {
  5680  		t.Fatalf("err: %s", err)
  5681  	}
  5682  
  5683  	actual := strings.TrimSpace(state.String())
  5684  	expected := strings.TrimSpace(testTerraformApplyOutputStr)
  5685  	if actual != expected {
  5686  		t.Fatalf("bad: \n%s", actual)
  5687  	}
  5688  }
  5689  
  5690  func TestContext2Apply_outputInvalid(t *testing.T) {
  5691  	m := testModule(t, "apply-output-invalid")
  5692  	p := testProvider("aws")
  5693  	p.ApplyFn = testApplyFn
  5694  	p.DiffFn = testDiffFn
  5695  	ctx := testContext2(t, &ContextOpts{
  5696  		Module: m,
  5697  		Providers: map[string]ResourceProviderFactory{
  5698  			"aws": testProviderFuncFixed(p),
  5699  		},
  5700  	})
  5701  
  5702  	_, err := ctx.Plan()
  5703  	if err == nil {
  5704  		t.Fatalf("err: %s", err)
  5705  	}
  5706  	if !strings.Contains(err.Error(), "is not a string") {
  5707  		t.Fatalf("err: %s", err)
  5708  	}
  5709  }
  5710  
  5711  func TestContext2Apply_outputList(t *testing.T) {
  5712  	m := testModule(t, "apply-output-list")
  5713  	p := testProvider("aws")
  5714  	p.ApplyFn = testApplyFn
  5715  	p.DiffFn = testDiffFn
  5716  	ctx := testContext2(t, &ContextOpts{
  5717  		Module: m,
  5718  		Providers: map[string]ResourceProviderFactory{
  5719  			"aws": testProviderFuncFixed(p),
  5720  		},
  5721  	})
  5722  
  5723  	if _, err := ctx.Plan(); err != nil {
  5724  		t.Fatalf("err: %s", err)
  5725  	}
  5726  
  5727  	state, err := ctx.Apply()
  5728  	if err != nil {
  5729  		t.Fatalf("err: %s", err)
  5730  	}
  5731  
  5732  	actual := strings.TrimSpace(state.String())
  5733  	expected := strings.TrimSpace(testTerraformApplyOutputListStr)
  5734  	if actual != expected {
  5735  		t.Fatalf("bad: \n%s", actual)
  5736  	}
  5737  }
  5738  
  5739  func TestContext2Apply_outputMulti(t *testing.T) {
  5740  	m := testModule(t, "apply-output-multi")
  5741  	p := testProvider("aws")
  5742  	p.ApplyFn = testApplyFn
  5743  	p.DiffFn = testDiffFn
  5744  	ctx := testContext2(t, &ContextOpts{
  5745  		Module: m,
  5746  		Providers: map[string]ResourceProviderFactory{
  5747  			"aws": testProviderFuncFixed(p),
  5748  		},
  5749  	})
  5750  
  5751  	if _, err := ctx.Plan(); err != nil {
  5752  		t.Fatalf("err: %s", err)
  5753  	}
  5754  
  5755  	state, err := ctx.Apply()
  5756  	if err != nil {
  5757  		t.Fatalf("err: %s", err)
  5758  	}
  5759  
  5760  	actual := strings.TrimSpace(state.String())
  5761  	expected := strings.TrimSpace(testTerraformApplyOutputMultiStr)
  5762  	if actual != expected {
  5763  		t.Fatalf("bad: \n%s", actual)
  5764  	}
  5765  }
  5766  
  5767  func TestContext2Apply_outputMultiIndex(t *testing.T) {
  5768  	m := testModule(t, "apply-output-multi-index")
  5769  	p := testProvider("aws")
  5770  	p.ApplyFn = testApplyFn
  5771  	p.DiffFn = testDiffFn
  5772  	ctx := testContext2(t, &ContextOpts{
  5773  		Module: m,
  5774  		Providers: map[string]ResourceProviderFactory{
  5775  			"aws": testProviderFuncFixed(p),
  5776  		},
  5777  	})
  5778  
  5779  	if _, err := ctx.Plan(); err != nil {
  5780  		t.Fatalf("err: %s", err)
  5781  	}
  5782  
  5783  	state, err := ctx.Apply()
  5784  	if err != nil {
  5785  		t.Fatalf("err: %s", err)
  5786  	}
  5787  
  5788  	actual := strings.TrimSpace(state.String())
  5789  	expected := strings.TrimSpace(testTerraformApplyOutputMultiIndexStr)
  5790  	if actual != expected {
  5791  		t.Fatalf("bad: \n%s", actual)
  5792  	}
  5793  }
  5794  
  5795  func TestContext2Apply_taint(t *testing.T) {
  5796  	m := testModule(t, "apply-taint")
  5797  	p := testProvider("aws")
  5798  
  5799  	// destroyCount tests against regression of
  5800  	// https://github.com/hashicorp/terraform/issues/1056
  5801  	var destroyCount = int32(0)
  5802  	var once sync.Once
  5803  	simulateProviderDelay := func() {
  5804  		time.Sleep(10 * time.Millisecond)
  5805  	}
  5806  
  5807  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  5808  		once.Do(simulateProviderDelay)
  5809  		if d.Destroy {
  5810  			atomic.AddInt32(&destroyCount, 1)
  5811  		}
  5812  		return testApplyFn(info, s, d)
  5813  	}
  5814  	p.DiffFn = testDiffFn
  5815  	s := &State{
  5816  		Modules: []*ModuleState{
  5817  			&ModuleState{
  5818  				Path: rootModulePath,
  5819  				Resources: map[string]*ResourceState{
  5820  					"aws_instance.bar": &ResourceState{
  5821  						Type: "aws_instance",
  5822  						Tainted: []*InstanceState{
  5823  							&InstanceState{
  5824  								ID: "baz",
  5825  								Attributes: map[string]string{
  5826  									"num":  "2",
  5827  									"type": "aws_instance",
  5828  								},
  5829  							},
  5830  						},
  5831  					},
  5832  				},
  5833  			},
  5834  		},
  5835  	}
  5836  	ctx := testContext2(t, &ContextOpts{
  5837  		Module: m,
  5838  		Providers: map[string]ResourceProviderFactory{
  5839  			"aws": testProviderFuncFixed(p),
  5840  		},
  5841  		State: s,
  5842  	})
  5843  
  5844  	if _, err := ctx.Plan(); err != nil {
  5845  		t.Fatalf("err: %s", err)
  5846  	}
  5847  
  5848  	state, err := ctx.Apply()
  5849  	if err != nil {
  5850  		t.Fatalf("err: %s", err)
  5851  	}
  5852  
  5853  	actual := strings.TrimSpace(state.String())
  5854  	expected := strings.TrimSpace(testTerraformApplyTaintStr)
  5855  	if actual != expected {
  5856  		t.Fatalf("bad:\n%s", actual)
  5857  	}
  5858  
  5859  	if destroyCount != 1 {
  5860  		t.Fatalf("Expected 1 destroy, got %d", destroyCount)
  5861  	}
  5862  }
  5863  
  5864  func TestContext2Apply_taintDep(t *testing.T) {
  5865  	m := testModule(t, "apply-taint-dep")
  5866  	p := testProvider("aws")
  5867  	p.ApplyFn = testApplyFn
  5868  	p.DiffFn = testDiffFn
  5869  	s := &State{
  5870  		Modules: []*ModuleState{
  5871  			&ModuleState{
  5872  				Path: rootModulePath,
  5873  				Resources: map[string]*ResourceState{
  5874  					"aws_instance.foo": &ResourceState{
  5875  						Type: "aws_instance",
  5876  						Tainted: []*InstanceState{
  5877  							&InstanceState{
  5878  								ID: "baz",
  5879  								Attributes: map[string]string{
  5880  									"num":  "2",
  5881  									"type": "aws_instance",
  5882  								},
  5883  							},
  5884  						},
  5885  					},
  5886  					"aws_instance.bar": &ResourceState{
  5887  						Type: "aws_instance",
  5888  						Primary: &InstanceState{
  5889  							ID: "bar",
  5890  							Attributes: map[string]string{
  5891  								"foo":  "baz",
  5892  								"num":  "2",
  5893  								"type": "aws_instance",
  5894  							},
  5895  						},
  5896  					},
  5897  				},
  5898  			},
  5899  		},
  5900  	}
  5901  	ctx := testContext2(t, &ContextOpts{
  5902  		Module: m,
  5903  		Providers: map[string]ResourceProviderFactory{
  5904  			"aws": testProviderFuncFixed(p),
  5905  		},
  5906  		State: s,
  5907  	})
  5908  
  5909  	if p, err := ctx.Plan(); err != nil {
  5910  		t.Fatalf("err: %s", err)
  5911  	} else {
  5912  		t.Logf("plan: %s", p)
  5913  	}
  5914  
  5915  	state, err := ctx.Apply()
  5916  	if err != nil {
  5917  		t.Fatalf("err: %s", err)
  5918  	}
  5919  
  5920  	actual := strings.TrimSpace(state.String())
  5921  	expected := strings.TrimSpace(testTerraformApplyTaintDepStr)
  5922  	if actual != expected {
  5923  		t.Fatalf("bad:\n%s", actual)
  5924  	}
  5925  }
  5926  
  5927  func TestContext2Apply_taintDepRequiresNew(t *testing.T) {
  5928  	m := testModule(t, "apply-taint-dep-requires-new")
  5929  	p := testProvider("aws")
  5930  	p.ApplyFn = testApplyFn
  5931  	p.DiffFn = testDiffFn
  5932  	s := &State{
  5933  		Modules: []*ModuleState{
  5934  			&ModuleState{
  5935  				Path: rootModulePath,
  5936  				Resources: map[string]*ResourceState{
  5937  					"aws_instance.foo": &ResourceState{
  5938  						Type: "aws_instance",
  5939  						Tainted: []*InstanceState{
  5940  							&InstanceState{
  5941  								ID: "baz",
  5942  								Attributes: map[string]string{
  5943  									"num":  "2",
  5944  									"type": "aws_instance",
  5945  								},
  5946  							},
  5947  						},
  5948  					},
  5949  					"aws_instance.bar": &ResourceState{
  5950  						Type: "aws_instance",
  5951  						Primary: &InstanceState{
  5952  							ID: "bar",
  5953  							Attributes: map[string]string{
  5954  								"foo":  "baz",
  5955  								"num":  "2",
  5956  								"type": "aws_instance",
  5957  							},
  5958  						},
  5959  					},
  5960  				},
  5961  			},
  5962  		},
  5963  	}
  5964  	ctx := testContext2(t, &ContextOpts{
  5965  		Module: m,
  5966  		Providers: map[string]ResourceProviderFactory{
  5967  			"aws": testProviderFuncFixed(p),
  5968  		},
  5969  		State: s,
  5970  	})
  5971  
  5972  	if p, err := ctx.Plan(); err != nil {
  5973  		t.Fatalf("err: %s", err)
  5974  	} else {
  5975  		t.Logf("plan: %s", p)
  5976  	}
  5977  
  5978  	state, err := ctx.Apply()
  5979  	if err != nil {
  5980  		t.Fatalf("err: %s", err)
  5981  	}
  5982  
  5983  	actual := strings.TrimSpace(state.String())
  5984  	expected := strings.TrimSpace(testTerraformApplyTaintDepRequireNewStr)
  5985  	if actual != expected {
  5986  		t.Fatalf("bad:\n%s", actual)
  5987  	}
  5988  }
  5989  
  5990  func TestContext2Apply_targeted(t *testing.T) {
  5991  	m := testModule(t, "apply-targeted")
  5992  	p := testProvider("aws")
  5993  	p.ApplyFn = testApplyFn
  5994  	p.DiffFn = testDiffFn
  5995  	ctx := testContext2(t, &ContextOpts{
  5996  		Module: m,
  5997  		Providers: map[string]ResourceProviderFactory{
  5998  			"aws": testProviderFuncFixed(p),
  5999  		},
  6000  		Targets: []string{"aws_instance.foo"},
  6001  	})
  6002  
  6003  	if _, err := ctx.Plan(); err != nil {
  6004  		t.Fatalf("err: %s", err)
  6005  	}
  6006  
  6007  	state, err := ctx.Apply()
  6008  	if err != nil {
  6009  		t.Fatalf("err: %s", err)
  6010  	}
  6011  
  6012  	mod := state.RootModule()
  6013  	if len(mod.Resources) != 1 {
  6014  		t.Fatalf("expected 1 resource, got: %#v", mod.Resources)
  6015  	}
  6016  
  6017  	checkStateString(t, state, `
  6018  aws_instance.foo:
  6019    ID = foo
  6020    num = 2
  6021    type = aws_instance
  6022  	`)
  6023  }
  6024  
  6025  func TestContext2Apply_targetedCount(t *testing.T) {
  6026  	m := testModule(t, "apply-targeted-count")
  6027  	p := testProvider("aws")
  6028  	p.ApplyFn = testApplyFn
  6029  	p.DiffFn = testDiffFn
  6030  	ctx := testContext2(t, &ContextOpts{
  6031  		Module: m,
  6032  		Providers: map[string]ResourceProviderFactory{
  6033  			"aws": testProviderFuncFixed(p),
  6034  		},
  6035  		Targets: []string{"aws_instance.foo"},
  6036  	})
  6037  
  6038  	if _, err := ctx.Plan(); err != nil {
  6039  		t.Fatalf("err: %s", err)
  6040  	}
  6041  
  6042  	state, err := ctx.Apply()
  6043  	if err != nil {
  6044  		t.Fatalf("err: %s", err)
  6045  	}
  6046  
  6047  	checkStateString(t, state, `
  6048  aws_instance.foo.0:
  6049    ID = foo
  6050  aws_instance.foo.1:
  6051    ID = foo
  6052  aws_instance.foo.2:
  6053    ID = foo
  6054  	`)
  6055  }
  6056  
  6057  func TestContext2Apply_targetedCountIndex(t *testing.T) {
  6058  	m := testModule(t, "apply-targeted-count")
  6059  	p := testProvider("aws")
  6060  	p.ApplyFn = testApplyFn
  6061  	p.DiffFn = testDiffFn
  6062  	ctx := testContext2(t, &ContextOpts{
  6063  		Module: m,
  6064  		Providers: map[string]ResourceProviderFactory{
  6065  			"aws": testProviderFuncFixed(p),
  6066  		},
  6067  		Targets: []string{"aws_instance.foo[1]"},
  6068  	})
  6069  
  6070  	if _, err := ctx.Plan(); err != nil {
  6071  		t.Fatalf("err: %s", err)
  6072  	}
  6073  
  6074  	state, err := ctx.Apply()
  6075  	if err != nil {
  6076  		t.Fatalf("err: %s", err)
  6077  	}
  6078  
  6079  	checkStateString(t, state, `
  6080  aws_instance.foo.1:
  6081    ID = foo
  6082  	`)
  6083  }
  6084  
  6085  func TestContext2Apply_targetedDestroy(t *testing.T) {
  6086  	m := testModule(t, "apply-targeted")
  6087  	p := testProvider("aws")
  6088  	p.ApplyFn = testApplyFn
  6089  	p.DiffFn = testDiffFn
  6090  	ctx := testContext2(t, &ContextOpts{
  6091  		Module: m,
  6092  		Providers: map[string]ResourceProviderFactory{
  6093  			"aws": testProviderFuncFixed(p),
  6094  		},
  6095  		State: &State{
  6096  			Modules: []*ModuleState{
  6097  				&ModuleState{
  6098  					Path: rootModulePath,
  6099  					Resources: map[string]*ResourceState{
  6100  						"aws_instance.foo": resourceState("aws_instance", "i-bcd345"),
  6101  						"aws_instance.bar": resourceState("aws_instance", "i-abc123"),
  6102  					},
  6103  				},
  6104  			},
  6105  		},
  6106  		Targets: []string{"aws_instance.foo"},
  6107  		Destroy: true,
  6108  	})
  6109  
  6110  	if _, err := ctx.Plan(); err != nil {
  6111  		t.Fatalf("err: %s", err)
  6112  	}
  6113  
  6114  	state, err := ctx.Apply()
  6115  	if err != nil {
  6116  		t.Fatalf("err: %s", err)
  6117  	}
  6118  
  6119  	mod := state.RootModule()
  6120  	if len(mod.Resources) != 1 {
  6121  		t.Fatalf("expected 1 resource, got: %#v", mod.Resources)
  6122  	}
  6123  
  6124  	checkStateString(t, state, `
  6125  aws_instance.bar:
  6126    ID = i-abc123
  6127  	`)
  6128  }
  6129  
  6130  func TestContext2Apply_targetedDestroyCountIndex(t *testing.T) {
  6131  	m := testModule(t, "apply-targeted-count")
  6132  	p := testProvider("aws")
  6133  	p.ApplyFn = testApplyFn
  6134  	p.DiffFn = testDiffFn
  6135  	ctx := testContext2(t, &ContextOpts{
  6136  		Module: m,
  6137  		Providers: map[string]ResourceProviderFactory{
  6138  			"aws": testProviderFuncFixed(p),
  6139  		},
  6140  		State: &State{
  6141  			Modules: []*ModuleState{
  6142  				&ModuleState{
  6143  					Path: rootModulePath,
  6144  					Resources: map[string]*ResourceState{
  6145  						"aws_instance.foo.0": resourceState("aws_instance", "i-bcd345"),
  6146  						"aws_instance.foo.1": resourceState("aws_instance", "i-bcd345"),
  6147  						"aws_instance.foo.2": resourceState("aws_instance", "i-bcd345"),
  6148  						"aws_instance.bar.0": resourceState("aws_instance", "i-abc123"),
  6149  						"aws_instance.bar.1": resourceState("aws_instance", "i-abc123"),
  6150  						"aws_instance.bar.2": resourceState("aws_instance", "i-abc123"),
  6151  					},
  6152  				},
  6153  			},
  6154  		},
  6155  		Targets: []string{
  6156  			"aws_instance.foo[2]",
  6157  			"aws_instance.bar[1]",
  6158  		},
  6159  		Destroy: true,
  6160  	})
  6161  
  6162  	if _, err := ctx.Plan(); err != nil {
  6163  		t.Fatalf("err: %s", err)
  6164  	}
  6165  
  6166  	state, err := ctx.Apply()
  6167  	if err != nil {
  6168  		t.Fatalf("err: %s", err)
  6169  	}
  6170  
  6171  	checkStateString(t, state, `
  6172  aws_instance.bar.0:
  6173    ID = i-abc123
  6174  aws_instance.bar.2:
  6175    ID = i-abc123
  6176  aws_instance.foo.0:
  6177    ID = i-bcd345
  6178  aws_instance.foo.1:
  6179    ID = i-bcd345
  6180  	`)
  6181  }
  6182  
  6183  func TestContext2Apply_targetedModule(t *testing.T) {
  6184  	m := testModule(t, "apply-targeted-module")
  6185  	p := testProvider("aws")
  6186  	p.ApplyFn = testApplyFn
  6187  	p.DiffFn = testDiffFn
  6188  	ctx := testContext2(t, &ContextOpts{
  6189  		Module: m,
  6190  		Providers: map[string]ResourceProviderFactory{
  6191  			"aws": testProviderFuncFixed(p),
  6192  		},
  6193  		Targets: []string{"module.child"},
  6194  	})
  6195  
  6196  	if _, err := ctx.Plan(); err != nil {
  6197  		t.Fatalf("err: %s", err)
  6198  	}
  6199  
  6200  	state, err := ctx.Apply()
  6201  	if err != nil {
  6202  		t.Fatalf("err: %s", err)
  6203  	}
  6204  
  6205  	mod := state.ModuleByPath([]string{"root", "child"})
  6206  	if mod == nil {
  6207  		t.Fatalf("no child module found in the state!\n\n%#v", state)
  6208  	}
  6209  	if len(mod.Resources) != 2 {
  6210  		t.Fatalf("expected 2 resources, got: %#v", mod.Resources)
  6211  	}
  6212  
  6213  	checkStateString(t, state, `
  6214  <no state>
  6215  module.child:
  6216    aws_instance.bar:
  6217      ID = foo
  6218      num = 2
  6219      type = aws_instance
  6220    aws_instance.foo:
  6221      ID = foo
  6222      num = 2
  6223      type = aws_instance
  6224  	`)
  6225  }
  6226  
  6227  func TestContext2Apply_targetedModuleResource(t *testing.T) {
  6228  	m := testModule(t, "apply-targeted-module-resource")
  6229  	p := testProvider("aws")
  6230  	p.ApplyFn = testApplyFn
  6231  	p.DiffFn = testDiffFn
  6232  	ctx := testContext2(t, &ContextOpts{
  6233  		Module: m,
  6234  		Providers: map[string]ResourceProviderFactory{
  6235  			"aws": testProviderFuncFixed(p),
  6236  		},
  6237  		Targets: []string{"module.child.aws_instance.foo"},
  6238  	})
  6239  
  6240  	if _, err := ctx.Plan(); err != nil {
  6241  		t.Fatalf("err: %s", err)
  6242  	}
  6243  
  6244  	state, err := ctx.Apply()
  6245  	if err != nil {
  6246  		t.Fatalf("err: %s", err)
  6247  	}
  6248  
  6249  	mod := state.ModuleByPath([]string{"root", "child"})
  6250  	if len(mod.Resources) != 1 {
  6251  		t.Fatalf("expected 1 resource, got: %#v", mod.Resources)
  6252  	}
  6253  
  6254  	checkStateString(t, state, `
  6255  <no state>
  6256  module.child:
  6257    aws_instance.foo:
  6258      ID = foo
  6259      num = 2
  6260      type = aws_instance
  6261  	`)
  6262  }
  6263  
  6264  func TestContext2Apply_unknownAttribute(t *testing.T) {
  6265  	m := testModule(t, "apply-unknown")
  6266  	p := testProvider("aws")
  6267  	p.ApplyFn = testApplyFn
  6268  	p.DiffFn = testDiffFn
  6269  	ctx := testContext2(t, &ContextOpts{
  6270  		Module: m,
  6271  		Providers: map[string]ResourceProviderFactory{
  6272  			"aws": testProviderFuncFixed(p),
  6273  		},
  6274  	})
  6275  
  6276  	if _, err := ctx.Plan(); err != nil {
  6277  		t.Fatalf("err: %s", err)
  6278  	}
  6279  
  6280  	state, err := ctx.Apply()
  6281  	if err == nil {
  6282  		t.Fatal("should error")
  6283  	}
  6284  
  6285  	actual := strings.TrimSpace(state.String())
  6286  	expected := strings.TrimSpace(testTerraformApplyUnknownAttrStr)
  6287  	if actual != expected {
  6288  		t.Fatalf("bad: \n%s", actual)
  6289  	}
  6290  }
  6291  
  6292  func TestContext2Apply_vars(t *testing.T) {
  6293  	m := testModule(t, "apply-vars")
  6294  	p := testProvider("aws")
  6295  	p.ApplyFn = testApplyFn
  6296  	p.DiffFn = testDiffFn
  6297  	ctx := testContext2(t, &ContextOpts{
  6298  		Module: m,
  6299  		Providers: map[string]ResourceProviderFactory{
  6300  			"aws": testProviderFuncFixed(p),
  6301  		},
  6302  		Variables: map[string]string{
  6303  			"foo":            "us-west-2",
  6304  			"amis.us-east-1": "override",
  6305  		},
  6306  	})
  6307  
  6308  	w, e := ctx.Validate()
  6309  	if len(w) > 0 {
  6310  		t.Fatalf("bad: %#v", w)
  6311  	}
  6312  	if len(e) > 0 {
  6313  		t.Fatalf("bad: %s", e)
  6314  	}
  6315  
  6316  	if _, err := ctx.Plan(); err != nil {
  6317  		t.Fatalf("err: %s", err)
  6318  	}
  6319  
  6320  	state, err := ctx.Apply()
  6321  	if err != nil {
  6322  		t.Fatalf("err: %s", err)
  6323  	}
  6324  
  6325  	actual := strings.TrimSpace(state.String())
  6326  	expected := strings.TrimSpace(testTerraformApplyVarsStr)
  6327  	if actual != expected {
  6328  		t.Fatalf("bad: \n%s", actual)
  6329  	}
  6330  }
  6331  
  6332  func TestContext2Apply_varsEnv(t *testing.T) {
  6333  	m := testModule(t, "apply-vars-env")
  6334  	p := testProvider("aws")
  6335  	p.ApplyFn = testApplyFn
  6336  	p.DiffFn = testDiffFn
  6337  	ctx := testContext2(t, &ContextOpts{
  6338  		Module: m,
  6339  		Providers: map[string]ResourceProviderFactory{
  6340  			"aws": testProviderFuncFixed(p),
  6341  		},
  6342  	})
  6343  
  6344  	// Set the env var
  6345  	old := tempEnv(t, "TF_VAR_ami", "baz")
  6346  	defer os.Setenv("TF_VAR_ami", old)
  6347  
  6348  	w, e := ctx.Validate()
  6349  	if len(w) > 0 {
  6350  		t.Fatalf("bad: %#v", w)
  6351  	}
  6352  	if len(e) > 0 {
  6353  		t.Fatalf("bad: %s", e)
  6354  	}
  6355  
  6356  	if _, err := ctx.Plan(); err != nil {
  6357  		t.Fatalf("err: %s", err)
  6358  	}
  6359  
  6360  	state, err := ctx.Apply()
  6361  	if err != nil {
  6362  		t.Fatalf("err: %s", err)
  6363  	}
  6364  
  6365  	actual := strings.TrimSpace(state.String())
  6366  	expected := strings.TrimSpace(testTerraformApplyVarsEnvStr)
  6367  	if actual != expected {
  6368  		t.Fatalf("bad: \n%s", actual)
  6369  	}
  6370  }
  6371  
  6372  func TestContext2Apply_createBefore_depends(t *testing.T) {
  6373  	m := testModule(t, "apply-depends-create-before")
  6374  	h := new(HookRecordApplyOrder)
  6375  	p := testProvider("aws")
  6376  	p.ApplyFn = testApplyFn
  6377  	p.DiffFn = testDiffFn
  6378  	state := &State{
  6379  		Modules: []*ModuleState{
  6380  			&ModuleState{
  6381  				Path: rootModulePath,
  6382  				Resources: map[string]*ResourceState{
  6383  					"aws_instance.web": &ResourceState{
  6384  						Type: "aws_instance",
  6385  						Primary: &InstanceState{
  6386  							ID: "bar",
  6387  							Attributes: map[string]string{
  6388  								"require_new": "ami-old",
  6389  							},
  6390  						},
  6391  					},
  6392  					"aws_instance.lb": &ResourceState{
  6393  						Type: "aws_instance",
  6394  						Primary: &InstanceState{
  6395  							ID: "baz",
  6396  							Attributes: map[string]string{
  6397  								"instance": "bar",
  6398  							},
  6399  						},
  6400  					},
  6401  				},
  6402  			},
  6403  		},
  6404  	}
  6405  	ctx := testContext2(t, &ContextOpts{
  6406  		Module: m,
  6407  		Hooks:  []Hook{h},
  6408  		Providers: map[string]ResourceProviderFactory{
  6409  			"aws": testProviderFuncFixed(p),
  6410  		},
  6411  		State: state,
  6412  	})
  6413  
  6414  	if _, err := ctx.Plan(); err != nil {
  6415  		t.Fatalf("err: %s", err)
  6416  	}
  6417  
  6418  	h.Active = true
  6419  	state, err := ctx.Apply()
  6420  	if err != nil {
  6421  		t.Fatalf("err: %s", err)
  6422  	}
  6423  
  6424  	mod := state.RootModule()
  6425  	if len(mod.Resources) < 2 {
  6426  		t.Fatalf("bad: %#v", mod.Resources)
  6427  	}
  6428  
  6429  	actual := strings.TrimSpace(state.String())
  6430  	expected := strings.TrimSpace(testTerraformApplyDependsCreateBeforeStr)
  6431  	if actual != expected {
  6432  		t.Fatalf("bad: \n%s\n%s", actual, expected)
  6433  	}
  6434  
  6435  	// Test that things were managed _in the right order_
  6436  	order := h.States
  6437  	diffs := h.Diffs
  6438  	if order[0].ID != "" || diffs[0].Destroy {
  6439  		t.Fatalf("should create new instance first: %#v", order)
  6440  	}
  6441  
  6442  	if order[1].ID != "baz" {
  6443  		t.Fatalf("update must happen after create: %#v", order)
  6444  	}
  6445  
  6446  	if order[2].ID != "bar" || !diffs[2].Destroy {
  6447  		t.Fatalf("destroy must happen after update: %#v", order)
  6448  	}
  6449  }
  6450  
  6451  func TestContext2Apply_singleDestroy(t *testing.T) {
  6452  	m := testModule(t, "apply-depends-create-before")
  6453  	h := new(HookRecordApplyOrder)
  6454  	p := testProvider("aws")
  6455  
  6456  	invokeCount := 0
  6457  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  6458  		invokeCount++
  6459  		switch invokeCount {
  6460  		case 1:
  6461  			if d.Destroy {
  6462  				t.Fatalf("should not destroy")
  6463  			}
  6464  			if s.ID != "" {
  6465  				t.Fatalf("should not have ID")
  6466  			}
  6467  		case 2:
  6468  			if d.Destroy {
  6469  				t.Fatalf("should not destroy")
  6470  			}
  6471  			if s.ID != "baz" {
  6472  				t.Fatalf("should have id")
  6473  			}
  6474  		case 3:
  6475  			if !d.Destroy {
  6476  				t.Fatalf("should destroy")
  6477  			}
  6478  			if s.ID == "" {
  6479  				t.Fatalf("should have ID")
  6480  			}
  6481  		default:
  6482  			t.Fatalf("bad invoke count %d", invokeCount)
  6483  		}
  6484  		return testApplyFn(info, s, d)
  6485  	}
  6486  	p.DiffFn = testDiffFn
  6487  	state := &State{
  6488  		Modules: []*ModuleState{
  6489  			&ModuleState{
  6490  				Path: rootModulePath,
  6491  				Resources: map[string]*ResourceState{
  6492  					"aws_instance.web": &ResourceState{
  6493  						Type: "aws_instance",
  6494  						Primary: &InstanceState{
  6495  							ID: "bar",
  6496  							Attributes: map[string]string{
  6497  								"require_new": "ami-old",
  6498  							},
  6499  						},
  6500  					},
  6501  					"aws_instance.lb": &ResourceState{
  6502  						Type: "aws_instance",
  6503  						Primary: &InstanceState{
  6504  							ID: "baz",
  6505  							Attributes: map[string]string{
  6506  								"instance": "bar",
  6507  							},
  6508  						},
  6509  					},
  6510  				},
  6511  			},
  6512  		},
  6513  	}
  6514  	ctx := testContext2(t, &ContextOpts{
  6515  		Module: m,
  6516  		Hooks:  []Hook{h},
  6517  		Providers: map[string]ResourceProviderFactory{
  6518  			"aws": testProviderFuncFixed(p),
  6519  		},
  6520  		State: state,
  6521  	})
  6522  
  6523  	if _, err := ctx.Plan(); err != nil {
  6524  		t.Fatalf("err: %s", err)
  6525  	}
  6526  
  6527  	h.Active = true
  6528  	state, err := ctx.Apply()
  6529  	if err != nil {
  6530  		t.Fatalf("err: %s", err)
  6531  	}
  6532  
  6533  	if invokeCount != 3 {
  6534  		t.Fatalf("bad: %d", invokeCount)
  6535  	}
  6536  }
  6537  
  6538  func testContext2(t *testing.T, opts *ContextOpts) *Context {
  6539  	return NewContext(opts)
  6540  }
  6541  
  6542  func testApplyFn(
  6543  	info *InstanceInfo,
  6544  	s *InstanceState,
  6545  	d *InstanceDiff) (*InstanceState, error) {
  6546  	if d.Destroy {
  6547  		return nil, nil
  6548  	}
  6549  
  6550  	id := "foo"
  6551  	if idAttr, ok := d.Attributes["id"]; ok && !idAttr.NewComputed {
  6552  		id = idAttr.New
  6553  	}
  6554  
  6555  	result := &InstanceState{
  6556  		ID:         id,
  6557  		Attributes: make(map[string]string),
  6558  	}
  6559  
  6560  	// Copy all the prior attributes
  6561  	for k, v := range s.Attributes {
  6562  		result.Attributes[k] = v
  6563  	}
  6564  
  6565  	if d != nil {
  6566  		result = result.MergeDiff(d)
  6567  	}
  6568  	return result, nil
  6569  }
  6570  
  6571  func testDiffFn(
  6572  	info *InstanceInfo,
  6573  	s *InstanceState,
  6574  	c *ResourceConfig) (*InstanceDiff, error) {
  6575  	var diff InstanceDiff
  6576  	diff.Attributes = make(map[string]*ResourceAttrDiff)
  6577  
  6578  	for k, v := range c.Raw {
  6579  		if _, ok := v.(string); !ok {
  6580  			continue
  6581  		}
  6582  
  6583  		if k == "nil" {
  6584  			return nil, nil
  6585  		}
  6586  
  6587  		// This key is used for other purposes
  6588  		if k == "compute_value" {
  6589  			continue
  6590  		}
  6591  
  6592  		if k == "compute" {
  6593  			attrDiff := &ResourceAttrDiff{
  6594  				Old:         "",
  6595  				New:         "",
  6596  				NewComputed: true,
  6597  			}
  6598  
  6599  			if cv, ok := c.Config["compute_value"]; ok {
  6600  				if cv.(string) == "1" {
  6601  					attrDiff.NewComputed = false
  6602  					attrDiff.New = fmt.Sprintf("computed_%s", v.(string))
  6603  				}
  6604  			}
  6605  
  6606  			diff.Attributes[v.(string)] = attrDiff
  6607  			continue
  6608  		}
  6609  
  6610  		// If this key is not computed, then look it up in the
  6611  		// cleaned config.
  6612  		found := false
  6613  		for _, ck := range c.ComputedKeys {
  6614  			if ck == k {
  6615  				found = true
  6616  				break
  6617  			}
  6618  		}
  6619  		if !found {
  6620  			v = c.Config[k]
  6621  		}
  6622  
  6623  		attrDiff := &ResourceAttrDiff{
  6624  			Old: "",
  6625  			New: v.(string),
  6626  		}
  6627  
  6628  		if k == "require_new" {
  6629  			attrDiff.RequiresNew = true
  6630  		}
  6631  		diff.Attributes[k] = attrDiff
  6632  	}
  6633  
  6634  	for _, k := range c.ComputedKeys {
  6635  		diff.Attributes[k] = &ResourceAttrDiff{
  6636  			Old:         "",
  6637  			NewComputed: true,
  6638  		}
  6639  	}
  6640  
  6641  	for k, v := range diff.Attributes {
  6642  		if v.NewComputed {
  6643  			continue
  6644  		}
  6645  
  6646  		old, ok := s.Attributes[k]
  6647  		if !ok {
  6648  			continue
  6649  		}
  6650  		if old == v.New {
  6651  			delete(diff.Attributes, k)
  6652  		}
  6653  	}
  6654  
  6655  	if !diff.Empty() {
  6656  		diff.Attributes["type"] = &ResourceAttrDiff{
  6657  			Old: "",
  6658  			New: info.Type,
  6659  		}
  6660  	}
  6661  
  6662  	return &diff, nil
  6663  }
  6664  
  6665  func testProvider(prefix string) *MockResourceProvider {
  6666  	p := new(MockResourceProvider)
  6667  	p.RefreshFn = func(info *InstanceInfo, s *InstanceState) (*InstanceState, error) {
  6668  		return s, nil
  6669  	}
  6670  	p.ResourcesReturn = []ResourceType{
  6671  		ResourceType{
  6672  			Name: fmt.Sprintf("%s_instance", prefix),
  6673  		},
  6674  	}
  6675  
  6676  	return p
  6677  }
  6678  
  6679  func testProvisioner() *MockResourceProvisioner {
  6680  	p := new(MockResourceProvisioner)
  6681  	return p
  6682  }
  6683  
  6684  func checkStateString(t *testing.T, state *State, expected string) {
  6685  	actual := strings.TrimSpace(state.String())
  6686  	expected = strings.TrimSpace(expected)
  6687  
  6688  	if actual != expected {
  6689  		t.Fatalf("state does not match! actual:\n%s\n\nexpected:\n%s", actual, expected)
  6690  	}
  6691  }
  6692  
  6693  func resourceState(resourceType, resourceID string) *ResourceState {
  6694  	return &ResourceState{
  6695  		Type: resourceType,
  6696  		Primary: &InstanceState{
  6697  			ID: resourceID,
  6698  		},
  6699  	}
  6700  }
  6701  
  6702  const testContextGraph = `
  6703  root: root
  6704  aws_instance.bar
  6705    aws_instance.bar -> provider.aws
  6706  aws_instance.foo
  6707    aws_instance.foo -> provider.aws
  6708  provider.aws
  6709  root
  6710    root -> aws_instance.bar
  6711    root -> aws_instance.foo
  6712  `
  6713  
  6714  const testContextRefreshModuleStr = `
  6715  aws_instance.web: (1 tainted)
  6716    ID = <not created>
  6717    Tainted ID 1 = bar
  6718  
  6719  module.child:
  6720    aws_instance.web:
  6721      ID = new
  6722  `
  6723  
  6724  const testContextRefreshOutputStr = `
  6725  aws_instance.web:
  6726    ID = foo
  6727    foo = bar
  6728  
  6729  Outputs:
  6730  
  6731  foo = bar
  6732  `
  6733  
  6734  const testContextRefreshOutputPartialStr = `
  6735  <no state>
  6736  `
  6737  
  6738  const testContextRefreshTaintedStr = `
  6739  aws_instance.web: (1 tainted)
  6740    ID = <not created>
  6741    Tainted ID 1 = foo
  6742  `