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