github.com/tarrant/terraform@v0.3.8-0.20150402012457-f68c9eee638e/terraform/context_test.go (about)

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