github.com/acm1/terraform@v0.6.2-0.20150729164239-1f314444f45c/terraform/context_apply_test.go (about)

     1  package terraform
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"reflect"
     7  	"sort"
     8  	"strings"
     9  	"sync"
    10  	"sync/atomic"
    11  	"testing"
    12  	"time"
    13  )
    14  
    15  func TestContext2Apply(t *testing.T) {
    16  	m := testModule(t, "apply-good")
    17  	p := testProvider("aws")
    18  	p.ApplyFn = testApplyFn
    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  	if _, err := ctx.Plan(); err != nil {
    28  		t.Fatalf("err: %s", err)
    29  	}
    30  
    31  	state, err := ctx.Apply()
    32  	if err != nil {
    33  		t.Fatalf("err: %s", err)
    34  	}
    35  
    36  	mod := state.RootModule()
    37  	if len(mod.Resources) < 2 {
    38  		t.Fatalf("bad: %#v", mod.Resources)
    39  	}
    40  
    41  	actual := strings.TrimSpace(state.String())
    42  	expected := strings.TrimSpace(testTerraformApplyStr)
    43  	if actual != expected {
    44  		t.Fatalf("bad: \n%s", actual)
    45  	}
    46  }
    47  
    48  func TestContext2Apply_providerAlias(t *testing.T) {
    49  	m := testModule(t, "apply-provider-alias")
    50  	p := testProvider("aws")
    51  	p.ApplyFn = testApplyFn
    52  	p.DiffFn = testDiffFn
    53  	ctx := testContext2(t, &ContextOpts{
    54  		Module: m,
    55  		Providers: map[string]ResourceProviderFactory{
    56  			"aws": testProviderFuncFixed(p),
    57  		},
    58  	})
    59  
    60  	if _, err := ctx.Plan(); err != nil {
    61  		t.Fatalf("err: %s", err)
    62  	}
    63  
    64  	state, err := ctx.Apply()
    65  	if err != nil {
    66  		t.Fatalf("err: %s", err)
    67  	}
    68  
    69  	mod := state.RootModule()
    70  	if len(mod.Resources) < 2 {
    71  		t.Fatalf("bad: %#v", mod.Resources)
    72  	}
    73  
    74  	actual := strings.TrimSpace(state.String())
    75  	expected := strings.TrimSpace(testTerraformApplyProviderAliasStr)
    76  	if actual != expected {
    77  		t.Fatalf("bad: \n%s", actual)
    78  	}
    79  }
    80  
    81  func TestContext2Apply_emptyModule(t *testing.T) {
    82  	m := testModule(t, "apply-empty-module")
    83  	p := testProvider("aws")
    84  	p.ApplyFn = testApplyFn
    85  	p.DiffFn = testDiffFn
    86  	ctx := testContext2(t, &ContextOpts{
    87  		Module: m,
    88  		Providers: map[string]ResourceProviderFactory{
    89  			"aws": testProviderFuncFixed(p),
    90  		},
    91  	})
    92  
    93  	if _, err := ctx.Plan(); err != nil {
    94  		t.Fatalf("err: %s", err)
    95  	}
    96  
    97  	state, err := ctx.Apply()
    98  	if err != nil {
    99  		t.Fatalf("err: %s", err)
   100  	}
   101  
   102  	actual := strings.TrimSpace(state.String())
   103  	actual = strings.Replace(actual, "  ", "", -1)
   104  	expected := strings.TrimSpace(testTerraformApplyEmptyModuleStr)
   105  	if actual != expected {
   106  		t.Fatalf("bad: \n%s\nexpect:\n%s", actual, expected)
   107  	}
   108  }
   109  
   110  func TestContext2Apply_createBeforeDestroy(t *testing.T) {
   111  	m := testModule(t, "apply-good-create-before")
   112  	p := testProvider("aws")
   113  	p.ApplyFn = testApplyFn
   114  	p.DiffFn = testDiffFn
   115  	state := &State{
   116  		Modules: []*ModuleState{
   117  			&ModuleState{
   118  				Path: rootModulePath,
   119  				Resources: map[string]*ResourceState{
   120  					"aws_instance.bar": &ResourceState{
   121  						Type: "aws_instance",
   122  						Primary: &InstanceState{
   123  							ID: "bar",
   124  							Attributes: map[string]string{
   125  								"require_new": "abc",
   126  							},
   127  						},
   128  					},
   129  				},
   130  			},
   131  		},
   132  	}
   133  	ctx := testContext2(t, &ContextOpts{
   134  		Module: m,
   135  		Providers: map[string]ResourceProviderFactory{
   136  			"aws": testProviderFuncFixed(p),
   137  		},
   138  		State: state,
   139  	})
   140  
   141  	if p, err := ctx.Plan(); err != nil {
   142  		t.Fatalf("err: %s", err)
   143  	} else {
   144  		t.Logf(p.String())
   145  	}
   146  
   147  	state, err := ctx.Apply()
   148  	if err != nil {
   149  		t.Fatalf("err: %s", err)
   150  	}
   151  
   152  	mod := state.RootModule()
   153  	if len(mod.Resources) != 1 {
   154  		t.Fatalf("bad: %s", state)
   155  	}
   156  
   157  	actual := strings.TrimSpace(state.String())
   158  	expected := strings.TrimSpace(testTerraformApplyCreateBeforeStr)
   159  	if actual != expected {
   160  		t.Fatalf("bad: \n%s", actual)
   161  	}
   162  }
   163  
   164  func TestContext2Apply_createBeforeDestroyUpdate(t *testing.T) {
   165  	m := testModule(t, "apply-good-create-before-update")
   166  	p := testProvider("aws")
   167  	p.ApplyFn = testApplyFn
   168  	p.DiffFn = testDiffFn
   169  	state := &State{
   170  		Modules: []*ModuleState{
   171  			&ModuleState{
   172  				Path: rootModulePath,
   173  				Resources: map[string]*ResourceState{
   174  					"aws_instance.bar": &ResourceState{
   175  						Type: "aws_instance",
   176  						Primary: &InstanceState{
   177  							ID: "bar",
   178  							Attributes: map[string]string{
   179  								"foo": "bar",
   180  							},
   181  						},
   182  					},
   183  				},
   184  			},
   185  		},
   186  	}
   187  	ctx := testContext2(t, &ContextOpts{
   188  		Module: m,
   189  		Providers: map[string]ResourceProviderFactory{
   190  			"aws": testProviderFuncFixed(p),
   191  		},
   192  		State: state,
   193  	})
   194  
   195  	if p, err := ctx.Plan(); err != nil {
   196  		t.Fatalf("err: %s", err)
   197  	} else {
   198  		t.Logf(p.String())
   199  	}
   200  
   201  	state, err := ctx.Apply()
   202  	if err != nil {
   203  		t.Fatalf("err: %s", err)
   204  	}
   205  
   206  	mod := state.RootModule()
   207  	if len(mod.Resources) != 1 {
   208  		t.Fatalf("bad: %s", state)
   209  	}
   210  
   211  	actual := strings.TrimSpace(state.String())
   212  	expected := strings.TrimSpace(testTerraformApplyCreateBeforeUpdateStr)
   213  	if actual != expected {
   214  		t.Fatalf("bad: \n%s", actual)
   215  	}
   216  }
   217  
   218  func TestContext2Apply_destroyComputed(t *testing.T) {
   219  	m := testModule(t, "apply-destroy-computed")
   220  	p := testProvider("aws")
   221  	p.ApplyFn = testApplyFn
   222  	p.DiffFn = testDiffFn
   223  	state := &State{
   224  		Modules: []*ModuleState{
   225  			&ModuleState{
   226  				Path: rootModulePath,
   227  				Resources: map[string]*ResourceState{
   228  					"aws_instance.foo": &ResourceState{
   229  						Type: "aws_instance",
   230  						Primary: &InstanceState{
   231  							ID: "foo",
   232  							Attributes: map[string]string{
   233  								"output": "value",
   234  							},
   235  						},
   236  					},
   237  				},
   238  			},
   239  		},
   240  	}
   241  	ctx := testContext2(t, &ContextOpts{
   242  		Module: m,
   243  		Providers: map[string]ResourceProviderFactory{
   244  			"aws": testProviderFuncFixed(p),
   245  		},
   246  		State:   state,
   247  		Destroy: true,
   248  	})
   249  
   250  	if p, err := ctx.Plan(); err != nil {
   251  		t.Fatalf("err: %s", err)
   252  	} else {
   253  		t.Logf(p.String())
   254  	}
   255  
   256  	if _, err := ctx.Apply(); err != nil {
   257  		t.Fatalf("err: %s", err)
   258  	}
   259  }
   260  
   261  func TestContext2Apply_minimal(t *testing.T) {
   262  	m := testModule(t, "apply-minimal")
   263  	p := testProvider("aws")
   264  	p.ApplyFn = testApplyFn
   265  	p.DiffFn = testDiffFn
   266  	ctx := testContext2(t, &ContextOpts{
   267  		Module: m,
   268  		Providers: map[string]ResourceProviderFactory{
   269  			"aws": testProviderFuncFixed(p),
   270  		},
   271  	})
   272  
   273  	if _, err := ctx.Plan(); err != nil {
   274  		t.Fatalf("err: %s", err)
   275  	}
   276  
   277  	state, err := ctx.Apply()
   278  	if err != nil {
   279  		t.Fatalf("err: %s", err)
   280  	}
   281  
   282  	actual := strings.TrimSpace(state.String())
   283  	expected := strings.TrimSpace(testTerraformApplyMinimalStr)
   284  	if actual != expected {
   285  		t.Fatalf("bad: \n%s", actual)
   286  	}
   287  }
   288  
   289  func TestContext2Apply_badDiff(t *testing.T) {
   290  	m := testModule(t, "apply-good")
   291  	p := testProvider("aws")
   292  	p.ApplyFn = testApplyFn
   293  	p.DiffFn = testDiffFn
   294  	ctx := testContext2(t, &ContextOpts{
   295  		Module: m,
   296  		Providers: map[string]ResourceProviderFactory{
   297  			"aws": testProviderFuncFixed(p),
   298  		},
   299  	})
   300  
   301  	if _, err := ctx.Plan(); err != nil {
   302  		t.Fatalf("err: %s", err)
   303  	}
   304  
   305  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
   306  		return &InstanceDiff{
   307  			Attributes: map[string]*ResourceAttrDiff{
   308  				"newp": nil,
   309  			},
   310  		}, nil
   311  	}
   312  
   313  	if _, err := ctx.Apply(); err == nil {
   314  		t.Fatal("should error")
   315  	}
   316  }
   317  
   318  func TestContext2Apply_cancel(t *testing.T) {
   319  	stopped := false
   320  
   321  	m := testModule(t, "apply-cancel")
   322  	p := testProvider("aws")
   323  	ctx := testContext2(t, &ContextOpts{
   324  		Module: m,
   325  		Providers: map[string]ResourceProviderFactory{
   326  			"aws": testProviderFuncFixed(p),
   327  		},
   328  	})
   329  
   330  	p.ApplyFn = func(*InstanceInfo, *InstanceState, *InstanceDiff) (*InstanceState, error) {
   331  		if !stopped {
   332  			stopped = true
   333  			go ctx.Stop()
   334  
   335  			for {
   336  				if ctx.sh.Stopped() {
   337  					break
   338  				}
   339  			}
   340  		}
   341  
   342  		return &InstanceState{
   343  			ID: "foo",
   344  			Attributes: map[string]string{
   345  				"num": "2",
   346  			},
   347  		}, nil
   348  	}
   349  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
   350  		return &InstanceDiff{
   351  			Attributes: map[string]*ResourceAttrDiff{
   352  				"num": &ResourceAttrDiff{
   353  					New: "bar",
   354  				},
   355  			},
   356  		}, nil
   357  	}
   358  
   359  	if _, err := ctx.Plan(); err != nil {
   360  		t.Fatalf("err: %s", err)
   361  	}
   362  
   363  	// Start the Apply in a goroutine
   364  	stateCh := make(chan *State)
   365  	go func() {
   366  		state, err := ctx.Apply()
   367  		if err != nil {
   368  			panic(err)
   369  		}
   370  
   371  		stateCh <- state
   372  	}()
   373  
   374  	state := <-stateCh
   375  
   376  	mod := state.RootModule()
   377  	if len(mod.Resources) != 1 {
   378  		t.Fatalf("bad: %s", state.String())
   379  	}
   380  
   381  	actual := strings.TrimSpace(state.String())
   382  	expected := strings.TrimSpace(testTerraformApplyCancelStr)
   383  	if actual != expected {
   384  		t.Fatalf("bad: \n%s", actual)
   385  	}
   386  }
   387  
   388  func TestContext2Apply_compute(t *testing.T) {
   389  	m := testModule(t, "apply-compute")
   390  	p := testProvider("aws")
   391  	p.ApplyFn = testApplyFn
   392  	p.DiffFn = testDiffFn
   393  	ctx := testContext2(t, &ContextOpts{
   394  		Module: m,
   395  		Providers: map[string]ResourceProviderFactory{
   396  			"aws": testProviderFuncFixed(p),
   397  		},
   398  	})
   399  
   400  	if _, err := ctx.Plan(); err != nil {
   401  		t.Fatalf("err: %s", err)
   402  	}
   403  
   404  	ctx.variables = map[string]string{"value": "1"}
   405  
   406  	state, err := ctx.Apply()
   407  	if err != nil {
   408  		t.Fatalf("err: %s", err)
   409  	}
   410  
   411  	actual := strings.TrimSpace(state.String())
   412  	expected := strings.TrimSpace(testTerraformApplyComputeStr)
   413  	if actual != expected {
   414  		t.Fatalf("bad: \n%s", actual)
   415  	}
   416  }
   417  
   418  func TestContext2Apply_countDecrease(t *testing.T) {
   419  	m := testModule(t, "apply-count-dec")
   420  	p := testProvider("aws")
   421  	p.DiffFn = testDiffFn
   422  	s := &State{
   423  		Modules: []*ModuleState{
   424  			&ModuleState{
   425  				Path: rootModulePath,
   426  				Resources: map[string]*ResourceState{
   427  					"aws_instance.foo.0": &ResourceState{
   428  						Type: "aws_instance",
   429  						Primary: &InstanceState{
   430  							ID: "bar",
   431  							Attributes: map[string]string{
   432  								"foo":  "foo",
   433  								"type": "aws_instance",
   434  							},
   435  						},
   436  					},
   437  					"aws_instance.foo.1": &ResourceState{
   438  						Type: "aws_instance",
   439  						Primary: &InstanceState{
   440  							ID: "bar",
   441  							Attributes: map[string]string{
   442  								"foo":  "foo",
   443  								"type": "aws_instance",
   444  							},
   445  						},
   446  					},
   447  					"aws_instance.foo.2": &ResourceState{
   448  						Type: "aws_instance",
   449  						Primary: &InstanceState{
   450  							ID: "bar",
   451  							Attributes: map[string]string{
   452  								"foo":  "foo",
   453  								"type": "aws_instance",
   454  							},
   455  						},
   456  					},
   457  				},
   458  			},
   459  		},
   460  	}
   461  	ctx := testContext2(t, &ContextOpts{
   462  		Module: m,
   463  		Providers: map[string]ResourceProviderFactory{
   464  			"aws": testProviderFuncFixed(p),
   465  		},
   466  		State: s,
   467  	})
   468  
   469  	if _, err := ctx.Plan(); err != nil {
   470  		t.Fatalf("err: %s", err)
   471  	}
   472  
   473  	state, err := ctx.Apply()
   474  	if err != nil {
   475  		t.Fatalf("err: %s", err)
   476  	}
   477  
   478  	actual := strings.TrimSpace(state.String())
   479  	expected := strings.TrimSpace(testTerraformApplyCountDecStr)
   480  	if actual != expected {
   481  		t.Fatalf("bad: \n%s", actual)
   482  	}
   483  }
   484  
   485  func TestContext2Apply_countDecreaseToOne(t *testing.T) {
   486  	m := testModule(t, "apply-count-dec-one")
   487  	p := testProvider("aws")
   488  	p.ApplyFn = testApplyFn
   489  	p.DiffFn = testDiffFn
   490  	s := &State{
   491  		Modules: []*ModuleState{
   492  			&ModuleState{
   493  				Path: rootModulePath,
   494  				Resources: map[string]*ResourceState{
   495  					"aws_instance.foo.0": &ResourceState{
   496  						Type: "aws_instance",
   497  						Primary: &InstanceState{
   498  							ID: "bar",
   499  							Attributes: map[string]string{
   500  								"foo":  "foo",
   501  								"type": "aws_instance",
   502  							},
   503  						},
   504  					},
   505  					"aws_instance.foo.1": &ResourceState{
   506  						Type: "aws_instance",
   507  						Primary: &InstanceState{
   508  							ID: "bar",
   509  						},
   510  					},
   511  					"aws_instance.foo.2": &ResourceState{
   512  						Type: "aws_instance",
   513  						Primary: &InstanceState{
   514  							ID: "bar",
   515  						},
   516  					},
   517  				},
   518  			},
   519  		},
   520  	}
   521  	ctx := testContext2(t, &ContextOpts{
   522  		Module: m,
   523  		Providers: map[string]ResourceProviderFactory{
   524  			"aws": testProviderFuncFixed(p),
   525  		},
   526  		State: s,
   527  	})
   528  
   529  	if _, err := ctx.Plan(); err != nil {
   530  		t.Fatalf("err: %s", err)
   531  	}
   532  
   533  	state, err := ctx.Apply()
   534  	if err != nil {
   535  		t.Fatalf("err: %s", err)
   536  	}
   537  
   538  	actual := strings.TrimSpace(state.String())
   539  	expected := strings.TrimSpace(testTerraformApplyCountDecToOneStr)
   540  	if actual != expected {
   541  		t.Fatalf("bad: \n%s", actual)
   542  	}
   543  }
   544  
   545  // https://github.com/PeoplePerHour/terraform/pull/11
   546  //
   547  // This tests a case where both a "resource" and "resource.0" are in
   548  // the state file, which apparently is a reasonable backwards compatibility
   549  // concern found in the above 3rd party repo.
   550  func TestContext2Apply_countDecreaseToOneCorrupted(t *testing.T) {
   551  	m := testModule(t, "apply-count-dec-one")
   552  	p := testProvider("aws")
   553  	p.ApplyFn = testApplyFn
   554  	p.DiffFn = testDiffFn
   555  	s := &State{
   556  		Modules: []*ModuleState{
   557  			&ModuleState{
   558  				Path: rootModulePath,
   559  				Resources: map[string]*ResourceState{
   560  					"aws_instance.foo": &ResourceState{
   561  						Type: "aws_instance",
   562  						Primary: &InstanceState{
   563  							ID: "bar",
   564  							Attributes: map[string]string{
   565  								"foo":  "foo",
   566  								"type": "aws_instance",
   567  							},
   568  						},
   569  					},
   570  					"aws_instance.foo.0": &ResourceState{
   571  						Type: "aws_instance",
   572  						Primary: &InstanceState{
   573  							ID: "baz",
   574  							Attributes: map[string]string{
   575  								"type": "aws_instance",
   576  							},
   577  						},
   578  					},
   579  				},
   580  			},
   581  		},
   582  	}
   583  	ctx := testContext2(t, &ContextOpts{
   584  		Module: m,
   585  		Providers: map[string]ResourceProviderFactory{
   586  			"aws": testProviderFuncFixed(p),
   587  		},
   588  		State: s,
   589  	})
   590  
   591  	if p, err := ctx.Plan(); err != nil {
   592  		t.Fatalf("err: %s", err)
   593  	} else {
   594  		testStringMatch(t, p, testTerraformApplyCountDecToOneCorruptedPlanStr)
   595  	}
   596  
   597  	state, err := ctx.Apply()
   598  	if err != nil {
   599  		t.Fatalf("err: %s", err)
   600  	}
   601  
   602  	actual := strings.TrimSpace(state.String())
   603  	expected := strings.TrimSpace(testTerraformApplyCountDecToOneCorruptedStr)
   604  	if actual != expected {
   605  		t.Fatalf("bad: \n%s", actual)
   606  	}
   607  }
   608  
   609  func TestContext2Apply_countTainted(t *testing.T) {
   610  	m := testModule(t, "apply-count-tainted")
   611  	p := testProvider("aws")
   612  	p.DiffFn = testDiffFn
   613  	s := &State{
   614  		Modules: []*ModuleState{
   615  			&ModuleState{
   616  				Path: rootModulePath,
   617  				Resources: map[string]*ResourceState{
   618  					"aws_instance.foo.0": &ResourceState{
   619  						Type: "aws_instance",
   620  						Tainted: []*InstanceState{
   621  							&InstanceState{
   622  								ID: "bar",
   623  								Attributes: map[string]string{
   624  									"foo":  "foo",
   625  									"type": "aws_instance",
   626  								},
   627  							},
   628  						},
   629  					},
   630  				},
   631  			},
   632  		},
   633  	}
   634  	ctx := testContext2(t, &ContextOpts{
   635  		Module: m,
   636  		Providers: map[string]ResourceProviderFactory{
   637  			"aws": testProviderFuncFixed(p),
   638  		},
   639  		State: s,
   640  	})
   641  
   642  	if _, err := ctx.Plan(); err != nil {
   643  		t.Fatalf("err: %s", err)
   644  	}
   645  
   646  	state, err := ctx.Apply()
   647  	if err != nil {
   648  		t.Fatalf("err: %s", err)
   649  	}
   650  
   651  	actual := strings.TrimSpace(state.String())
   652  	expected := strings.TrimSpace(testTerraformApplyCountTaintedStr)
   653  	if actual != expected {
   654  		t.Fatalf("bad: \n%s", actual)
   655  	}
   656  }
   657  
   658  func TestContext2Apply_countVariable(t *testing.T) {
   659  	m := testModule(t, "apply-count-variable")
   660  	p := testProvider("aws")
   661  	p.ApplyFn = testApplyFn
   662  	p.DiffFn = testDiffFn
   663  	ctx := testContext2(t, &ContextOpts{
   664  		Module: m,
   665  		Providers: map[string]ResourceProviderFactory{
   666  			"aws": testProviderFuncFixed(p),
   667  		},
   668  	})
   669  
   670  	if _, err := ctx.Plan(); err != nil {
   671  		t.Fatalf("err: %s", err)
   672  	}
   673  
   674  	state, err := ctx.Apply()
   675  	if err != nil {
   676  		t.Fatalf("err: %s", err)
   677  	}
   678  
   679  	actual := strings.TrimSpace(state.String())
   680  	expected := strings.TrimSpace(testTerraformApplyCountVariableStr)
   681  	if actual != expected {
   682  		t.Fatalf("bad: \n%s", actual)
   683  	}
   684  }
   685  
   686  func TestContext2Apply_module(t *testing.T) {
   687  	m := testModule(t, "apply-module")
   688  	p := testProvider("aws")
   689  	p.ApplyFn = testApplyFn
   690  	p.DiffFn = testDiffFn
   691  	ctx := testContext2(t, &ContextOpts{
   692  		Module: m,
   693  		Providers: map[string]ResourceProviderFactory{
   694  			"aws": testProviderFuncFixed(p),
   695  		},
   696  	})
   697  
   698  	if _, err := ctx.Plan(); err != nil {
   699  		t.Fatalf("err: %s", err)
   700  	}
   701  
   702  	state, err := ctx.Apply()
   703  	if err != nil {
   704  		t.Fatalf("err: %s", err)
   705  	}
   706  
   707  	actual := strings.TrimSpace(state.String())
   708  	expected := strings.TrimSpace(testTerraformApplyModuleStr)
   709  	if actual != expected {
   710  		t.Fatalf("bad: \n%s", actual)
   711  	}
   712  }
   713  
   714  func TestContext2Apply_moduleDestroyOrder(t *testing.T) {
   715  	m := testModule(t, "apply-module-destroy-order")
   716  	p := testProvider("aws")
   717  	p.DiffFn = testDiffFn
   718  
   719  	// Create a custom apply function to track the order they were destroyed
   720  	var order []string
   721  	var orderLock sync.Mutex
   722  	p.ApplyFn = func(
   723  		info *InstanceInfo,
   724  		is *InstanceState,
   725  		id *InstanceDiff) (*InstanceState, error) {
   726  		orderLock.Lock()
   727  		defer orderLock.Unlock()
   728  
   729  		order = append(order, is.ID)
   730  		return nil, nil
   731  	}
   732  
   733  	state := &State{
   734  		Modules: []*ModuleState{
   735  			&ModuleState{
   736  				Path: rootModulePath,
   737  				Resources: map[string]*ResourceState{
   738  					"aws_instance.b": &ResourceState{
   739  						Type: "aws_instance",
   740  						Primary: &InstanceState{
   741  							ID: "b",
   742  						},
   743  					},
   744  				},
   745  			},
   746  
   747  			&ModuleState{
   748  				Path: []string{"root", "child"},
   749  				Resources: map[string]*ResourceState{
   750  					"aws_instance.a": &ResourceState{
   751  						Type: "aws_instance",
   752  						Primary: &InstanceState{
   753  							ID: "a",
   754  						},
   755  					},
   756  				},
   757  				Outputs: map[string]string{
   758  					"a_output": "a",
   759  				},
   760  			},
   761  		},
   762  	}
   763  
   764  	ctx := testContext2(t, &ContextOpts{
   765  		Module: m,
   766  		Providers: map[string]ResourceProviderFactory{
   767  			"aws": testProviderFuncFixed(p),
   768  		},
   769  		State:   state,
   770  		Destroy: true,
   771  	})
   772  
   773  	if _, err := ctx.Plan(); err != nil {
   774  		t.Fatalf("err: %s", err)
   775  	}
   776  
   777  	state, err := ctx.Apply()
   778  	if err != nil {
   779  		t.Fatalf("err: %s", err)
   780  	}
   781  
   782  	expected := []string{"b", "a"}
   783  	if !reflect.DeepEqual(order, expected) {
   784  		t.Fatalf("bad: %#v", order)
   785  	}
   786  
   787  	{
   788  		actual := strings.TrimSpace(state.String())
   789  		expected := strings.TrimSpace(testTerraformApplyModuleDestroyOrderStr)
   790  		if actual != expected {
   791  			t.Fatalf("bad: \n%s", actual)
   792  		}
   793  	}
   794  }
   795  
   796  func TestContext2Apply_moduleOrphanProvider(t *testing.T) {
   797  	m := testModule(t, "apply-module-orphan-provider-inherit")
   798  	p := testProvider("aws")
   799  	p.ApplyFn = testApplyFn
   800  	p.DiffFn = testDiffFn
   801  
   802  	p.ConfigureFn = func(c *ResourceConfig) error {
   803  		if _, ok := c.Get("value"); !ok {
   804  			return fmt.Errorf("value is not found")
   805  		}
   806  
   807  		return nil
   808  	}
   809  
   810  	// Create a state with an orphan module
   811  	state := &State{
   812  		Modules: []*ModuleState{
   813  			&ModuleState{
   814  				Path: []string{"root", "child"},
   815  				Resources: map[string]*ResourceState{
   816  					"aws_instance.bar": &ResourceState{
   817  						Type: "aws_instance",
   818  						Primary: &InstanceState{
   819  							ID: "bar",
   820  						},
   821  					},
   822  				},
   823  			},
   824  		},
   825  	}
   826  
   827  	ctx := testContext2(t, &ContextOpts{
   828  		Module: m,
   829  		State:  state,
   830  		Providers: map[string]ResourceProviderFactory{
   831  			"aws": testProviderFuncFixed(p),
   832  		},
   833  	})
   834  
   835  	if _, err := ctx.Plan(); err != nil {
   836  		t.Fatalf("err: %s", err)
   837  	}
   838  
   839  	if _, err := ctx.Apply(); err != nil {
   840  		t.Fatalf("err: %s", err)
   841  	}
   842  }
   843  
   844  // This tests an issue where all the providers in a module but not
   845  // in the root weren't being added to the root properly. In this test
   846  // case: aws is explicitly added to root, but "test" should be added to.
   847  // With the bug, it wasn't.
   848  func TestContext2Apply_moduleOnlyProvider(t *testing.T) {
   849  	m := testModule(t, "apply-module-only-provider")
   850  	p := testProvider("aws")
   851  	p.ApplyFn = testApplyFn
   852  	p.DiffFn = testDiffFn
   853  	pTest := testProvider("test")
   854  	pTest.ApplyFn = testApplyFn
   855  	pTest.DiffFn = testDiffFn
   856  
   857  	ctx := testContext2(t, &ContextOpts{
   858  		Module: m,
   859  		Providers: map[string]ResourceProviderFactory{
   860  			"aws":  testProviderFuncFixed(p),
   861  			"test": testProviderFuncFixed(pTest),
   862  		},
   863  	})
   864  
   865  	if _, err := ctx.Plan(); err != nil {
   866  		t.Fatalf("err: %s", err)
   867  	}
   868  
   869  	state, err := ctx.Apply()
   870  	if err != nil {
   871  		t.Fatalf("err: %s", err)
   872  	}
   873  
   874  	actual := strings.TrimSpace(state.String())
   875  	expected := strings.TrimSpace(testTerraformApplyModuleOnlyProviderStr)
   876  	if actual != expected {
   877  		t.Fatalf("bad: \n%s", actual)
   878  	}
   879  }
   880  
   881  func TestContext2Apply_moduleProviderAlias(t *testing.T) {
   882  	m := testModule(t, "apply-module-provider-alias")
   883  	p := testProvider("aws")
   884  	p.ApplyFn = testApplyFn
   885  	p.DiffFn = testDiffFn
   886  	ctx := testContext2(t, &ContextOpts{
   887  		Module: m,
   888  		Providers: map[string]ResourceProviderFactory{
   889  			"aws": testProviderFuncFixed(p),
   890  		},
   891  	})
   892  
   893  	if _, err := ctx.Plan(); err != nil {
   894  		t.Fatalf("err: %s", err)
   895  	}
   896  
   897  	state, err := ctx.Apply()
   898  	if err != nil {
   899  		t.Fatalf("err: %s", err)
   900  	}
   901  
   902  	actual := strings.TrimSpace(state.String())
   903  	expected := strings.TrimSpace(testTerraformApplyModuleProviderAliasStr)
   904  	if actual != expected {
   905  		t.Fatalf("bad: \n%s", actual)
   906  	}
   907  }
   908  
   909  func TestContext2Apply_moduleProviderAliasTargets(t *testing.T) {
   910  	m := testModule(t, "apply-module-provider-alias")
   911  	p := testProvider("aws")
   912  	p.ApplyFn = testApplyFn
   913  	p.DiffFn = testDiffFn
   914  	ctx := testContext2(t, &ContextOpts{
   915  		Module: m,
   916  		Providers: map[string]ResourceProviderFactory{
   917  			"aws": testProviderFuncFixed(p),
   918  		},
   919  		Targets: []string{"no.thing"},
   920  	})
   921  
   922  	if _, err := ctx.Plan(); err != nil {
   923  		t.Fatalf("err: %s", err)
   924  	}
   925  
   926  	state, err := ctx.Apply()
   927  	if err != nil {
   928  		t.Fatalf("err: %s", err)
   929  	}
   930  
   931  	actual := strings.TrimSpace(state.String())
   932  	expected := strings.TrimSpace(`
   933  <no state>
   934  	`)
   935  	if actual != expected {
   936  		t.Fatalf("bad: \n%s", actual)
   937  	}
   938  }
   939  
   940  func TestContext2Apply_moduleProviderCloseNested(t *testing.T) {
   941  	m := testModule(t, "apply-module-provider-close-nested")
   942  	p := testProvider("aws")
   943  	p.ApplyFn = testApplyFn
   944  	p.DiffFn = testDiffFn
   945  	ctx := testContext2(t, &ContextOpts{
   946  		Module: m,
   947  		Providers: map[string]ResourceProviderFactory{
   948  			"aws": testProviderFuncFixed(p),
   949  		},
   950  		State: &State{
   951  			Modules: []*ModuleState{
   952  				&ModuleState{
   953  					Path: []string{"root", "child", "subchild"},
   954  					Resources: map[string]*ResourceState{
   955  						"aws_instance.foo": &ResourceState{
   956  							Type: "aws_instance",
   957  							Primary: &InstanceState{
   958  								ID: "bar",
   959  							},
   960  						},
   961  					},
   962  				},
   963  			},
   964  		},
   965  		Destroy: true,
   966  	})
   967  
   968  	if _, err := ctx.Plan(); err != nil {
   969  		t.Fatalf("err: %s", err)
   970  	}
   971  
   972  	if _, err := ctx.Apply(); err != nil {
   973  		t.Fatalf("err: %s", err)
   974  	}
   975  }
   976  
   977  func TestContext2Apply_moduleVarResourceCount(t *testing.T) {
   978  	m := testModule(t, "apply-module-var-resource-count")
   979  	p := testProvider("aws")
   980  	p.ApplyFn = testApplyFn
   981  	p.DiffFn = testDiffFn
   982  	ctx := testContext2(t, &ContextOpts{
   983  		Module: m,
   984  		Providers: map[string]ResourceProviderFactory{
   985  			"aws": testProviderFuncFixed(p),
   986  		},
   987  		Variables: map[string]string{
   988  			"count": "2",
   989  		},
   990  		Destroy: true,
   991  	})
   992  
   993  	if _, err := ctx.Plan(); err != nil {
   994  		t.Fatalf("err: %s", err)
   995  	}
   996  
   997  	if _, err := ctx.Apply(); err != nil {
   998  		t.Fatalf("err: %s", err)
   999  	}
  1000  
  1001  	ctx = testContext2(t, &ContextOpts{
  1002  		Module: m,
  1003  		Providers: map[string]ResourceProviderFactory{
  1004  			"aws": testProviderFuncFixed(p),
  1005  		},
  1006  		Variables: map[string]string{
  1007  			"count": "5",
  1008  		},
  1009  	})
  1010  
  1011  	if _, err := ctx.Plan(); err != nil {
  1012  		t.Fatalf("err: %s", err)
  1013  	}
  1014  
  1015  	if _, err := ctx.Apply(); err != nil {
  1016  		t.Fatalf("err: %s", err)
  1017  	}
  1018  }
  1019  
  1020  // GH-819
  1021  func TestContext2Apply_moduleBool(t *testing.T) {
  1022  	m := testModule(t, "apply-module-bool")
  1023  	p := testProvider("aws")
  1024  	p.ApplyFn = testApplyFn
  1025  	p.DiffFn = testDiffFn
  1026  	ctx := testContext2(t, &ContextOpts{
  1027  		Module: m,
  1028  		Providers: map[string]ResourceProviderFactory{
  1029  			"aws": testProviderFuncFixed(p),
  1030  		},
  1031  	})
  1032  
  1033  	if _, err := ctx.Plan(); err != nil {
  1034  		t.Fatalf("err: %s", err)
  1035  	}
  1036  
  1037  	state, err := ctx.Apply()
  1038  	if err != nil {
  1039  		t.Fatalf("err: %s", err)
  1040  	}
  1041  
  1042  	actual := strings.TrimSpace(state.String())
  1043  	expected := strings.TrimSpace(testTerraformApplyModuleBoolStr)
  1044  	if actual != expected {
  1045  		t.Fatalf("bad: \n%s", actual)
  1046  	}
  1047  }
  1048  
  1049  func TestContext2Apply_multiProvider(t *testing.T) {
  1050  	m := testModule(t, "apply-multi-provider")
  1051  	p := testProvider("aws")
  1052  	p.ApplyFn = testApplyFn
  1053  	p.DiffFn = testDiffFn
  1054  
  1055  	pDO := testProvider("do")
  1056  	pDO.ApplyFn = testApplyFn
  1057  	pDO.DiffFn = testDiffFn
  1058  
  1059  	ctx := testContext2(t, &ContextOpts{
  1060  		Module: m,
  1061  		Providers: map[string]ResourceProviderFactory{
  1062  			"aws": testProviderFuncFixed(p),
  1063  			"do":  testProviderFuncFixed(pDO),
  1064  		},
  1065  	})
  1066  
  1067  	if _, err := ctx.Plan(); err != nil {
  1068  		t.Fatalf("err: %s", err)
  1069  	}
  1070  
  1071  	state, err := ctx.Apply()
  1072  	if err != nil {
  1073  		t.Fatalf("err: %s", err)
  1074  	}
  1075  
  1076  	mod := state.RootModule()
  1077  	if len(mod.Resources) < 2 {
  1078  		t.Fatalf("bad: %#v", mod.Resources)
  1079  	}
  1080  
  1081  	actual := strings.TrimSpace(state.String())
  1082  	expected := strings.TrimSpace(testTerraformApplyMultiProviderStr)
  1083  	if actual != expected {
  1084  		t.Fatalf("bad: \n%s", actual)
  1085  	}
  1086  }
  1087  
  1088  func TestContext2Apply_multiVar(t *testing.T) {
  1089  	m := testModule(t, "apply-multi-var")
  1090  	p := testProvider("aws")
  1091  	p.ApplyFn = testApplyFn
  1092  	p.DiffFn = testDiffFn
  1093  
  1094  	// First, apply with a count of 3
  1095  	ctx := testContext2(t, &ContextOpts{
  1096  		Module: m,
  1097  		Providers: map[string]ResourceProviderFactory{
  1098  			"aws": testProviderFuncFixed(p),
  1099  		},
  1100  		Variables: map[string]string{
  1101  			"count": "3",
  1102  		},
  1103  	})
  1104  
  1105  	if _, err := ctx.Plan(); err != nil {
  1106  		t.Fatalf("err: %s", err)
  1107  	}
  1108  
  1109  	state, err := ctx.Apply()
  1110  	if err != nil {
  1111  		t.Fatalf("err: %s", err)
  1112  	}
  1113  
  1114  	actual := state.RootModule().Outputs["output"]
  1115  	expected := "bar0,bar1,bar2"
  1116  	if actual != expected {
  1117  		t.Fatalf("bad: \n%s", actual)
  1118  	}
  1119  
  1120  	// Apply again, reduce the count to 1
  1121  	{
  1122  		ctx := testContext2(t, &ContextOpts{
  1123  			Module: m,
  1124  			State:  state,
  1125  			Providers: map[string]ResourceProviderFactory{
  1126  				"aws": testProviderFuncFixed(p),
  1127  			},
  1128  			Variables: map[string]string{
  1129  				"count": "1",
  1130  			},
  1131  		})
  1132  
  1133  		if _, err := ctx.Plan(); err != nil {
  1134  			t.Fatalf("err: %s", err)
  1135  		}
  1136  
  1137  		state, err := ctx.Apply()
  1138  		if err != nil {
  1139  			t.Fatalf("err: %s", err)
  1140  		}
  1141  
  1142  		actual := state.RootModule().Outputs["output"]
  1143  		expected := "bar0"
  1144  		if actual != expected {
  1145  			t.Fatalf("bad: \n%s", actual)
  1146  		}
  1147  	}
  1148  }
  1149  
  1150  func TestContext2Apply_nilDiff(t *testing.T) {
  1151  	m := testModule(t, "apply-good")
  1152  	p := testProvider("aws")
  1153  	p.ApplyFn = testApplyFn
  1154  	p.DiffFn = testDiffFn
  1155  	ctx := testContext2(t, &ContextOpts{
  1156  		Module: m,
  1157  		Providers: map[string]ResourceProviderFactory{
  1158  			"aws": testProviderFuncFixed(p),
  1159  		},
  1160  	})
  1161  
  1162  	if _, err := ctx.Plan(); err != nil {
  1163  		t.Fatalf("err: %s", err)
  1164  	}
  1165  
  1166  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  1167  		return nil, nil
  1168  	}
  1169  
  1170  	if _, err := ctx.Apply(); err == nil {
  1171  		t.Fatal("should error")
  1172  	}
  1173  }
  1174  
  1175  func TestContext2Apply_outputOrphan(t *testing.T) {
  1176  	m := testModule(t, "apply-output-orphan")
  1177  	p := testProvider("aws")
  1178  	p.ApplyFn = testApplyFn
  1179  	p.DiffFn = testDiffFn
  1180  
  1181  	state := &State{
  1182  		Modules: []*ModuleState{
  1183  			&ModuleState{
  1184  				Path: rootModulePath,
  1185  				Outputs: map[string]string{
  1186  					"foo": "bar",
  1187  					"bar": "baz",
  1188  				},
  1189  			},
  1190  		},
  1191  	}
  1192  
  1193  	ctx := testContext2(t, &ContextOpts{
  1194  		Module: m,
  1195  		Providers: map[string]ResourceProviderFactory{
  1196  			"aws": testProviderFuncFixed(p),
  1197  		},
  1198  		State: state,
  1199  	})
  1200  
  1201  	if _, err := ctx.Plan(); err != nil {
  1202  		t.Fatalf("err: %s", err)
  1203  	}
  1204  
  1205  	state, err := ctx.Apply()
  1206  	if err != nil {
  1207  		t.Fatalf("err: %s", err)
  1208  	}
  1209  
  1210  	actual := strings.TrimSpace(state.String())
  1211  	expected := strings.TrimSpace(testTerraformApplyOutputOrphanStr)
  1212  	if actual != expected {
  1213  		t.Fatalf("bad: \n%s", actual)
  1214  	}
  1215  }
  1216  
  1217  func TestContext2Apply_providerComputedVar(t *testing.T) {
  1218  	m := testModule(t, "apply-provider-computed")
  1219  	p := testProvider("aws")
  1220  	p.ApplyFn = testApplyFn
  1221  	p.DiffFn = testDiffFn
  1222  
  1223  	pTest := testProvider("test")
  1224  	pTest.ApplyFn = testApplyFn
  1225  	pTest.DiffFn = testDiffFn
  1226  
  1227  	ctx := testContext2(t, &ContextOpts{
  1228  		Module: m,
  1229  		Providers: map[string]ResourceProviderFactory{
  1230  			"aws":  testProviderFuncFixed(p),
  1231  			"test": testProviderFuncFixed(pTest),
  1232  		},
  1233  	})
  1234  
  1235  	p.ConfigureFn = func(c *ResourceConfig) error {
  1236  		if c.IsComputed("value") {
  1237  			return fmt.Errorf("value is computed")
  1238  		}
  1239  
  1240  		v, ok := c.Get("value")
  1241  		if !ok {
  1242  			return fmt.Errorf("value is not found")
  1243  		}
  1244  		if v != "yes" {
  1245  			return fmt.Errorf("value is not 'yes': %v", v)
  1246  		}
  1247  
  1248  		return nil
  1249  	}
  1250  
  1251  	if _, err := ctx.Plan(); err != nil {
  1252  		t.Fatalf("err: %s", err)
  1253  	}
  1254  
  1255  	if _, err := ctx.Apply(); err != nil {
  1256  		t.Fatalf("err: %s", err)
  1257  	}
  1258  }
  1259  
  1260  func TestContext2Apply_Provisioner_compute(t *testing.T) {
  1261  	m := testModule(t, "apply-provisioner-compute")
  1262  	p := testProvider("aws")
  1263  	pr := testProvisioner()
  1264  	p.ApplyFn = testApplyFn
  1265  	p.DiffFn = testDiffFn
  1266  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  1267  		val, ok := c.Config["foo"]
  1268  		if !ok || val != "computed_dynamical" {
  1269  			t.Fatalf("bad value for foo: %v %#v", val, c)
  1270  		}
  1271  
  1272  		return nil
  1273  	}
  1274  	ctx := testContext2(t, &ContextOpts{
  1275  		Module: m,
  1276  		Providers: map[string]ResourceProviderFactory{
  1277  			"aws": testProviderFuncFixed(p),
  1278  		},
  1279  		Provisioners: map[string]ResourceProvisionerFactory{
  1280  			"shell": testProvisionerFuncFixed(pr),
  1281  		},
  1282  		Variables: map[string]string{
  1283  			"value": "1",
  1284  		},
  1285  	})
  1286  
  1287  	if _, err := ctx.Plan(); err != nil {
  1288  		t.Fatalf("err: %s", err)
  1289  	}
  1290  
  1291  	state, err := ctx.Apply()
  1292  	if err != nil {
  1293  		t.Fatalf("err: %s", err)
  1294  	}
  1295  
  1296  	actual := strings.TrimSpace(state.String())
  1297  	expected := strings.TrimSpace(testTerraformApplyProvisionerStr)
  1298  	if actual != expected {
  1299  		t.Fatalf("bad: \n%s", actual)
  1300  	}
  1301  
  1302  	// Verify apply was invoked
  1303  	if !pr.ApplyCalled {
  1304  		t.Fatalf("provisioner not invoked")
  1305  	}
  1306  }
  1307  
  1308  func TestContext2Apply_provisionerCreateFail(t *testing.T) {
  1309  	m := testModule(t, "apply-provisioner-fail-create")
  1310  	p := testProvider("aws")
  1311  	pr := testProvisioner()
  1312  	p.DiffFn = testDiffFn
  1313  
  1314  	p.ApplyFn = func(
  1315  		info *InstanceInfo,
  1316  		is *InstanceState,
  1317  		id *InstanceDiff) (*InstanceState, error) {
  1318  		is.ID = "foo"
  1319  		return is, fmt.Errorf("error")
  1320  	}
  1321  
  1322  	ctx := testContext2(t, &ContextOpts{
  1323  		Module: m,
  1324  		Providers: map[string]ResourceProviderFactory{
  1325  			"aws": testProviderFuncFixed(p),
  1326  		},
  1327  		Provisioners: map[string]ResourceProvisionerFactory{
  1328  			"shell": testProvisionerFuncFixed(pr),
  1329  		},
  1330  	})
  1331  
  1332  	if _, err := ctx.Plan(); err != nil {
  1333  		t.Fatalf("err: %s", err)
  1334  	}
  1335  
  1336  	state, err := ctx.Apply()
  1337  	if err == nil {
  1338  		t.Fatal("should error")
  1339  	}
  1340  
  1341  	actual := strings.TrimSpace(state.String())
  1342  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailCreateStr)
  1343  	if actual != expected {
  1344  		t.Fatalf("bad: \n%s", actual)
  1345  	}
  1346  }
  1347  
  1348  func TestContext2Apply_provisionerCreateFailNoId(t *testing.T) {
  1349  	m := testModule(t, "apply-provisioner-fail-create")
  1350  	p := testProvider("aws")
  1351  	pr := testProvisioner()
  1352  	p.DiffFn = testDiffFn
  1353  
  1354  	p.ApplyFn = func(
  1355  		info *InstanceInfo,
  1356  		is *InstanceState,
  1357  		id *InstanceDiff) (*InstanceState, error) {
  1358  		return nil, fmt.Errorf("error")
  1359  	}
  1360  
  1361  	ctx := testContext2(t, &ContextOpts{
  1362  		Module: m,
  1363  		Providers: map[string]ResourceProviderFactory{
  1364  			"aws": testProviderFuncFixed(p),
  1365  		},
  1366  		Provisioners: map[string]ResourceProvisionerFactory{
  1367  			"shell": testProvisionerFuncFixed(pr),
  1368  		},
  1369  	})
  1370  
  1371  	if _, err := ctx.Plan(); err != nil {
  1372  		t.Fatalf("err: %s", err)
  1373  	}
  1374  
  1375  	state, err := ctx.Apply()
  1376  	if err == nil {
  1377  		t.Fatal("should error")
  1378  	}
  1379  
  1380  	actual := strings.TrimSpace(state.String())
  1381  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailCreateNoIdStr)
  1382  	if actual != expected {
  1383  		t.Fatalf("bad: \n%s", actual)
  1384  	}
  1385  }
  1386  
  1387  func TestContext2Apply_provisionerFail(t *testing.T) {
  1388  	m := testModule(t, "apply-provisioner-fail")
  1389  	p := testProvider("aws")
  1390  	pr := testProvisioner()
  1391  	p.ApplyFn = testApplyFn
  1392  	p.DiffFn = testDiffFn
  1393  
  1394  	pr.ApplyFn = func(*InstanceState, *ResourceConfig) error {
  1395  		return fmt.Errorf("EXPLOSION")
  1396  	}
  1397  
  1398  	ctx := testContext2(t, &ContextOpts{
  1399  		Module: m,
  1400  		Providers: map[string]ResourceProviderFactory{
  1401  			"aws": testProviderFuncFixed(p),
  1402  		},
  1403  		Provisioners: map[string]ResourceProvisionerFactory{
  1404  			"shell": testProvisionerFuncFixed(pr),
  1405  		},
  1406  		Variables: map[string]string{
  1407  			"value": "1",
  1408  		},
  1409  	})
  1410  
  1411  	if _, err := ctx.Plan(); err != nil {
  1412  		t.Fatalf("err: %s", err)
  1413  	}
  1414  
  1415  	state, err := ctx.Apply()
  1416  	if err == nil {
  1417  		t.Fatal("should error")
  1418  	}
  1419  
  1420  	actual := strings.TrimSpace(state.String())
  1421  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailStr)
  1422  	if actual != expected {
  1423  		t.Fatalf("bad: \n%s", actual)
  1424  	}
  1425  }
  1426  
  1427  func TestContext2Apply_provisionerFail_createBeforeDestroy(t *testing.T) {
  1428  	m := testModule(t, "apply-provisioner-fail-create-before")
  1429  	p := testProvider("aws")
  1430  	pr := testProvisioner()
  1431  	p.ApplyFn = testApplyFn
  1432  	p.DiffFn = testDiffFn
  1433  	pr.ApplyFn = func(*InstanceState, *ResourceConfig) error {
  1434  		return fmt.Errorf("EXPLOSION")
  1435  	}
  1436  
  1437  	state := &State{
  1438  		Modules: []*ModuleState{
  1439  			&ModuleState{
  1440  				Path: rootModulePath,
  1441  				Resources: map[string]*ResourceState{
  1442  					"aws_instance.bar": &ResourceState{
  1443  						Type: "aws_instance",
  1444  						Primary: &InstanceState{
  1445  							ID: "bar",
  1446  							Attributes: map[string]string{
  1447  								"require_new": "abc",
  1448  							},
  1449  						},
  1450  					},
  1451  				},
  1452  			},
  1453  		},
  1454  	}
  1455  	ctx := testContext2(t, &ContextOpts{
  1456  		Module: m,
  1457  		Providers: map[string]ResourceProviderFactory{
  1458  			"aws": testProviderFuncFixed(p),
  1459  		},
  1460  		Provisioners: map[string]ResourceProvisionerFactory{
  1461  			"shell": testProvisionerFuncFixed(pr),
  1462  		},
  1463  		State: state,
  1464  	})
  1465  
  1466  	if _, err := ctx.Plan(); err != nil {
  1467  		t.Fatalf("err: %s", err)
  1468  	}
  1469  
  1470  	state, err := ctx.Apply()
  1471  	if err == nil {
  1472  		t.Fatal("should error")
  1473  	}
  1474  
  1475  	actual := strings.TrimSpace(state.String())
  1476  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailCreateBeforeDestroyStr)
  1477  	if actual != expected {
  1478  		t.Fatalf("bad: \n%s", actual)
  1479  	}
  1480  }
  1481  
  1482  func TestContext2Apply_error_createBeforeDestroy(t *testing.T) {
  1483  	m := testModule(t, "apply-error-create-before")
  1484  	p := testProvider("aws")
  1485  	state := &State{
  1486  		Modules: []*ModuleState{
  1487  			&ModuleState{
  1488  				Path: rootModulePath,
  1489  				Resources: map[string]*ResourceState{
  1490  					"aws_instance.bar": &ResourceState{
  1491  						Type: "aws_instance",
  1492  						Primary: &InstanceState{
  1493  							ID: "bar",
  1494  							Attributes: map[string]string{
  1495  								"require_new": "abc",
  1496  							},
  1497  						},
  1498  					},
  1499  				},
  1500  			},
  1501  		},
  1502  	}
  1503  	ctx := testContext2(t, &ContextOpts{
  1504  		Module: m,
  1505  		Providers: map[string]ResourceProviderFactory{
  1506  			"aws": testProviderFuncFixed(p),
  1507  		},
  1508  		State: state,
  1509  	})
  1510  	p.ApplyFn = func(info *InstanceInfo, is *InstanceState, id *InstanceDiff) (*InstanceState, error) {
  1511  		return nil, fmt.Errorf("error")
  1512  	}
  1513  	p.DiffFn = testDiffFn
  1514  
  1515  	if _, err := ctx.Plan(); err != nil {
  1516  		t.Fatalf("err: %s", err)
  1517  	}
  1518  
  1519  	state, err := ctx.Apply()
  1520  	if err == nil {
  1521  		t.Fatal("should have error")
  1522  	}
  1523  
  1524  	actual := strings.TrimSpace(state.String())
  1525  	expected := strings.TrimSpace(testTerraformApplyErrorCreateBeforeDestroyStr)
  1526  	if actual != expected {
  1527  		t.Fatalf("bad: \n%s\n\nExpected:\n\n%s", actual, expected)
  1528  	}
  1529  }
  1530  
  1531  func TestContext2Apply_errorDestroy_createBeforeDestroy(t *testing.T) {
  1532  	m := testModule(t, "apply-error-create-before")
  1533  	p := testProvider("aws")
  1534  	state := &State{
  1535  		Modules: []*ModuleState{
  1536  			&ModuleState{
  1537  				Path: rootModulePath,
  1538  				Resources: map[string]*ResourceState{
  1539  					"aws_instance.bar": &ResourceState{
  1540  						Type: "aws_instance",
  1541  						Primary: &InstanceState{
  1542  							ID: "bar",
  1543  							Attributes: map[string]string{
  1544  								"require_new": "abc",
  1545  							},
  1546  						},
  1547  					},
  1548  				},
  1549  			},
  1550  		},
  1551  	}
  1552  	ctx := testContext2(t, &ContextOpts{
  1553  		Module: m,
  1554  		Providers: map[string]ResourceProviderFactory{
  1555  			"aws": testProviderFuncFixed(p),
  1556  		},
  1557  		State: state,
  1558  	})
  1559  	p.ApplyFn = func(info *InstanceInfo, is *InstanceState, id *InstanceDiff) (*InstanceState, error) {
  1560  		// Fail the destroy!
  1561  		if id.Destroy {
  1562  			return is, fmt.Errorf("error")
  1563  		}
  1564  
  1565  		// Create should work
  1566  		is = &InstanceState{
  1567  			ID: "foo",
  1568  		}
  1569  		return is, nil
  1570  	}
  1571  	p.DiffFn = testDiffFn
  1572  
  1573  	if _, err := ctx.Plan(); err != nil {
  1574  		t.Fatalf("err: %s", err)
  1575  	}
  1576  
  1577  	state, err := ctx.Apply()
  1578  	if err == nil {
  1579  		t.Fatal("should have error")
  1580  	}
  1581  
  1582  	actual := strings.TrimSpace(state.String())
  1583  	expected := strings.TrimSpace(testTerraformApplyErrorDestroyCreateBeforeDestroyStr)
  1584  	if actual != expected {
  1585  		t.Fatalf("bad: actual:\n%s\n\nexpected:\n%s", actual, expected)
  1586  	}
  1587  }
  1588  
  1589  func TestContext2Apply_multiDepose_createBeforeDestroy(t *testing.T) {
  1590  	m := testModule(t, "apply-multi-depose-create-before-destroy")
  1591  	p := testProvider("aws")
  1592  	p.DiffFn = testDiffFn
  1593  	ps := map[string]ResourceProviderFactory{"aws": testProviderFuncFixed(p)}
  1594  	state := &State{
  1595  		Modules: []*ModuleState{
  1596  			&ModuleState{
  1597  				Path: rootModulePath,
  1598  				Resources: map[string]*ResourceState{
  1599  					"aws_instance.web": &ResourceState{
  1600  						Type:    "aws_instance",
  1601  						Primary: &InstanceState{ID: "foo"},
  1602  					},
  1603  				},
  1604  			},
  1605  		},
  1606  	}
  1607  
  1608  	ctx := testContext2(t, &ContextOpts{
  1609  		Module:    m,
  1610  		Providers: ps,
  1611  		State:     state,
  1612  	})
  1613  	createdInstanceId := "bar"
  1614  	// Create works
  1615  	createFunc := func(is *InstanceState) (*InstanceState, error) {
  1616  		return &InstanceState{ID: createdInstanceId}, nil
  1617  	}
  1618  	// Destroy starts broken
  1619  	destroyFunc := func(is *InstanceState) (*InstanceState, error) {
  1620  		return is, fmt.Errorf("destroy failed")
  1621  	}
  1622  	p.ApplyFn = func(info *InstanceInfo, is *InstanceState, id *InstanceDiff) (*InstanceState, error) {
  1623  		if id.Destroy {
  1624  			return destroyFunc(is)
  1625  		} else {
  1626  			return createFunc(is)
  1627  		}
  1628  	}
  1629  
  1630  	if _, err := ctx.Plan(); err != nil {
  1631  		t.Fatalf("err: %s", err)
  1632  	}
  1633  
  1634  	// Destroy is broken, so even though CBD successfully replaces the instance,
  1635  	// we'll have to save the Deposed instance to destroy later
  1636  	state, err := ctx.Apply()
  1637  	if err == nil {
  1638  		t.Fatal("should have error")
  1639  	}
  1640  
  1641  	checkStateString(t, state, `
  1642  aws_instance.web: (1 deposed)
  1643    ID = bar
  1644    Deposed ID 1 = foo
  1645  	`)
  1646  
  1647  	createdInstanceId = "baz"
  1648  	ctx = testContext2(t, &ContextOpts{
  1649  		Module:    m,
  1650  		Providers: ps,
  1651  		State:     state,
  1652  	})
  1653  
  1654  	if _, err := ctx.Plan(); err != nil {
  1655  		t.Fatalf("err: %s", err)
  1656  	}
  1657  
  1658  	// We're replacing the primary instance once again. Destroy is _still_
  1659  	// broken, so the Deposed list gets longer
  1660  	state, err = ctx.Apply()
  1661  	if err == nil {
  1662  		t.Fatal("should have error")
  1663  	}
  1664  
  1665  	checkStateString(t, state, `
  1666  aws_instance.web: (2 deposed)
  1667    ID = baz
  1668    Deposed ID 1 = foo
  1669    Deposed ID 2 = bar
  1670  	`)
  1671  
  1672  	// Destroy partially fixed!
  1673  	destroyFunc = func(is *InstanceState) (*InstanceState, error) {
  1674  		if is.ID == "foo" || is.ID == "baz" {
  1675  			return nil, nil
  1676  		} else {
  1677  			return is, fmt.Errorf("destroy partially failed")
  1678  		}
  1679  	}
  1680  
  1681  	createdInstanceId = "qux"
  1682  	if _, err := ctx.Plan(); err != nil {
  1683  		t.Fatalf("err: %s", err)
  1684  	}
  1685  	state, err = ctx.Apply()
  1686  	// Expect error because 1/2 of Deposed destroys failed
  1687  	if err == nil {
  1688  		t.Fatal("should have error")
  1689  	}
  1690  
  1691  	// foo and baz are now gone, bar sticks around
  1692  	checkStateString(t, state, `
  1693  aws_instance.web: (1 deposed)
  1694    ID = qux
  1695    Deposed ID 1 = bar
  1696  	`)
  1697  
  1698  	// Destroy working fully!
  1699  	destroyFunc = func(is *InstanceState) (*InstanceState, error) {
  1700  		return nil, nil
  1701  	}
  1702  
  1703  	createdInstanceId = "quux"
  1704  	if _, err := ctx.Plan(); err != nil {
  1705  		t.Fatalf("err: %s", err)
  1706  	}
  1707  	state, err = ctx.Apply()
  1708  	if err != nil {
  1709  		t.Fatal("should not have error:", err)
  1710  	}
  1711  
  1712  	// And finally the state is clean
  1713  	checkStateString(t, state, `
  1714  aws_instance.web:
  1715    ID = quux
  1716  	`)
  1717  }
  1718  
  1719  func TestContext2Apply_provisionerResourceRef(t *testing.T) {
  1720  	m := testModule(t, "apply-provisioner-resource-ref")
  1721  	p := testProvider("aws")
  1722  	pr := testProvisioner()
  1723  	p.ApplyFn = testApplyFn
  1724  	p.DiffFn = testDiffFn
  1725  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  1726  		val, ok := c.Config["foo"]
  1727  		if !ok || val != "2" {
  1728  			t.Fatalf("bad value for foo: %v %#v", val, c)
  1729  		}
  1730  
  1731  		return nil
  1732  	}
  1733  
  1734  	ctx := testContext2(t, &ContextOpts{
  1735  		Module: m,
  1736  		Providers: map[string]ResourceProviderFactory{
  1737  			"aws": testProviderFuncFixed(p),
  1738  		},
  1739  		Provisioners: map[string]ResourceProvisionerFactory{
  1740  			"shell": testProvisionerFuncFixed(pr),
  1741  		},
  1742  	})
  1743  
  1744  	if _, err := ctx.Plan(); err != nil {
  1745  		t.Fatalf("err: %s", err)
  1746  	}
  1747  
  1748  	state, err := ctx.Apply()
  1749  	if err != nil {
  1750  		t.Fatalf("err: %s", err)
  1751  	}
  1752  
  1753  	actual := strings.TrimSpace(state.String())
  1754  	expected := strings.TrimSpace(testTerraformApplyProvisionerResourceRefStr)
  1755  	if actual != expected {
  1756  		t.Fatalf("bad: \n%s", actual)
  1757  	}
  1758  
  1759  	// Verify apply was invoked
  1760  	if !pr.ApplyCalled {
  1761  		t.Fatalf("provisioner not invoked")
  1762  	}
  1763  }
  1764  
  1765  func TestContext2Apply_provisionerSelfRef(t *testing.T) {
  1766  	m := testModule(t, "apply-provisioner-self-ref")
  1767  	p := testProvider("aws")
  1768  	pr := testProvisioner()
  1769  	p.ApplyFn = testApplyFn
  1770  	p.DiffFn = testDiffFn
  1771  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  1772  		val, ok := c.Config["command"]
  1773  		if !ok || val != "bar" {
  1774  			t.Fatalf("bad value for command: %v %#v", val, c)
  1775  		}
  1776  
  1777  		return nil
  1778  	}
  1779  
  1780  	ctx := testContext2(t, &ContextOpts{
  1781  		Module: m,
  1782  		Providers: map[string]ResourceProviderFactory{
  1783  			"aws": testProviderFuncFixed(p),
  1784  		},
  1785  		Provisioners: map[string]ResourceProvisionerFactory{
  1786  			"shell": testProvisionerFuncFixed(pr),
  1787  		},
  1788  	})
  1789  
  1790  	if _, err := ctx.Plan(); err != nil {
  1791  		t.Fatalf("err: %s", err)
  1792  	}
  1793  
  1794  	state, err := ctx.Apply()
  1795  	if err != nil {
  1796  		t.Fatalf("err: %s", err)
  1797  	}
  1798  
  1799  	actual := strings.TrimSpace(state.String())
  1800  	expected := strings.TrimSpace(testTerraformApplyProvisionerSelfRefStr)
  1801  	if actual != expected {
  1802  		t.Fatalf("bad: \n%s", actual)
  1803  	}
  1804  
  1805  	// Verify apply was invoked
  1806  	if !pr.ApplyCalled {
  1807  		t.Fatalf("provisioner not invoked")
  1808  	}
  1809  }
  1810  
  1811  func TestContext2Apply_provisionerMultiSelfRef(t *testing.T) {
  1812  	var lock sync.Mutex
  1813  	commands := make([]string, 0, 5)
  1814  
  1815  	m := testModule(t, "apply-provisioner-multi-self-ref")
  1816  	p := testProvider("aws")
  1817  	pr := testProvisioner()
  1818  	p.ApplyFn = testApplyFn
  1819  	p.DiffFn = testDiffFn
  1820  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  1821  		lock.Lock()
  1822  		defer lock.Unlock()
  1823  
  1824  		val, ok := c.Config["command"]
  1825  		if !ok {
  1826  			t.Fatalf("bad value for command: %v %#v", val, c)
  1827  		}
  1828  
  1829  		commands = append(commands, val.(string))
  1830  		return nil
  1831  	}
  1832  
  1833  	ctx := testContext2(t, &ContextOpts{
  1834  		Module: m,
  1835  		Providers: map[string]ResourceProviderFactory{
  1836  			"aws": testProviderFuncFixed(p),
  1837  		},
  1838  		Provisioners: map[string]ResourceProvisionerFactory{
  1839  			"shell": testProvisionerFuncFixed(pr),
  1840  		},
  1841  	})
  1842  
  1843  	if _, err := ctx.Plan(); err != nil {
  1844  		t.Fatalf("err: %s", err)
  1845  	}
  1846  
  1847  	state, err := ctx.Apply()
  1848  	if err != nil {
  1849  		t.Fatalf("err: %s", err)
  1850  	}
  1851  
  1852  	actual := strings.TrimSpace(state.String())
  1853  	expected := strings.TrimSpace(testTerraformApplyProvisionerMultiSelfRefStr)
  1854  	if actual != expected {
  1855  		t.Fatalf("bad: \n%s", actual)
  1856  	}
  1857  
  1858  	// Verify apply was invoked
  1859  	if !pr.ApplyCalled {
  1860  		t.Fatalf("provisioner not invoked")
  1861  	}
  1862  
  1863  	// Verify our result
  1864  	sort.Strings(commands)
  1865  	expectedCommands := []string{"number 0", "number 1", "number 2"}
  1866  	if !reflect.DeepEqual(commands, expectedCommands) {
  1867  		t.Fatalf("bad: %#v", commands)
  1868  	}
  1869  }
  1870  
  1871  // Provisioner should NOT run on a diff, only create
  1872  func TestContext2Apply_Provisioner_Diff(t *testing.T) {
  1873  	m := testModule(t, "apply-provisioner-diff")
  1874  	p := testProvider("aws")
  1875  	pr := testProvisioner()
  1876  	p.ApplyFn = testApplyFn
  1877  	p.DiffFn = testDiffFn
  1878  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  1879  		return nil
  1880  	}
  1881  	ctx := testContext2(t, &ContextOpts{
  1882  		Module: m,
  1883  		Providers: map[string]ResourceProviderFactory{
  1884  			"aws": testProviderFuncFixed(p),
  1885  		},
  1886  		Provisioners: map[string]ResourceProvisionerFactory{
  1887  			"shell": testProvisionerFuncFixed(pr),
  1888  		},
  1889  	})
  1890  
  1891  	if _, err := ctx.Plan(); err != nil {
  1892  		t.Fatalf("err: %s", err)
  1893  	}
  1894  
  1895  	state, err := ctx.Apply()
  1896  	if err != nil {
  1897  		t.Fatalf("err: %s", err)
  1898  	}
  1899  
  1900  	actual := strings.TrimSpace(state.String())
  1901  	expected := strings.TrimSpace(testTerraformApplyProvisionerDiffStr)
  1902  	if actual != expected {
  1903  		t.Fatalf("bad: \n%s", actual)
  1904  	}
  1905  
  1906  	// Verify apply was invoked
  1907  	if !pr.ApplyCalled {
  1908  		t.Fatalf("provisioner not invoked")
  1909  	}
  1910  	pr.ApplyCalled = false
  1911  
  1912  	// Change the state to force a diff
  1913  	mod := state.RootModule()
  1914  	mod.Resources["aws_instance.bar"].Primary.Attributes["foo"] = "baz"
  1915  
  1916  	// Re-create context with state
  1917  	ctx = testContext2(t, &ContextOpts{
  1918  		Module: m,
  1919  		Providers: map[string]ResourceProviderFactory{
  1920  			"aws": testProviderFuncFixed(p),
  1921  		},
  1922  		Provisioners: map[string]ResourceProvisionerFactory{
  1923  			"shell": testProvisionerFuncFixed(pr),
  1924  		},
  1925  		State: state,
  1926  	})
  1927  
  1928  	if _, err := ctx.Plan(); err != nil {
  1929  		t.Fatalf("err: %s", err)
  1930  	}
  1931  
  1932  	state2, err := ctx.Apply()
  1933  	if err != nil {
  1934  		t.Fatalf("err: %s", err)
  1935  	}
  1936  
  1937  	actual = strings.TrimSpace(state2.String())
  1938  	if actual != expected {
  1939  		t.Fatalf("bad: \n%s", actual)
  1940  	}
  1941  
  1942  	// Verify apply was NOT invoked
  1943  	if pr.ApplyCalled {
  1944  		t.Fatalf("provisioner invoked")
  1945  	}
  1946  }
  1947  
  1948  func TestContext2Apply_outputDiffVars(t *testing.T) {
  1949  	m := testModule(t, "apply-good")
  1950  	p := testProvider("aws")
  1951  	s := &State{
  1952  		Modules: []*ModuleState{
  1953  			&ModuleState{
  1954  				Path: rootModulePath,
  1955  				Resources: map[string]*ResourceState{
  1956  					"aws_instance.baz": &ResourceState{
  1957  						Type: "aws_instance",
  1958  						Primary: &InstanceState{
  1959  							ID: "bar",
  1960  						},
  1961  					},
  1962  				},
  1963  			},
  1964  		},
  1965  	}
  1966  	ctx := testContext2(t, &ContextOpts{
  1967  		Module: m,
  1968  		Providers: map[string]ResourceProviderFactory{
  1969  			"aws": testProviderFuncFixed(p),
  1970  		},
  1971  		State: s,
  1972  	})
  1973  
  1974  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  1975  		for k, ad := range d.Attributes {
  1976  			if ad.NewComputed {
  1977  				return nil, fmt.Errorf("%s: computed", k)
  1978  			}
  1979  		}
  1980  
  1981  		result := s.MergeDiff(d)
  1982  		result.ID = "foo"
  1983  		return result, nil
  1984  	}
  1985  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  1986  		return &InstanceDiff{
  1987  			Attributes: map[string]*ResourceAttrDiff{
  1988  				"foo": &ResourceAttrDiff{
  1989  					NewComputed: true,
  1990  					Type:        DiffAttrOutput,
  1991  				},
  1992  				"bar": &ResourceAttrDiff{
  1993  					New: "baz",
  1994  				},
  1995  			},
  1996  		}, nil
  1997  	}
  1998  
  1999  	if _, err := ctx.Plan(); err != nil {
  2000  		t.Fatalf("err: %s", err)
  2001  	}
  2002  	if _, err := ctx.Apply(); err != nil {
  2003  		t.Fatalf("err: %s", err)
  2004  	}
  2005  }
  2006  
  2007  func TestContext2Apply_Provisioner_ConnInfo(t *testing.T) {
  2008  	m := testModule(t, "apply-provisioner-conninfo")
  2009  	p := testProvider("aws")
  2010  	pr := testProvisioner()
  2011  
  2012  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  2013  		if s.Ephemeral.ConnInfo == nil {
  2014  			t.Fatalf("ConnInfo not initialized")
  2015  		}
  2016  
  2017  		result, _ := testApplyFn(info, s, d)
  2018  		result.Ephemeral.ConnInfo = map[string]string{
  2019  			"type": "ssh",
  2020  			"host": "127.0.0.1",
  2021  			"port": "22",
  2022  		}
  2023  		return result, nil
  2024  	}
  2025  	p.DiffFn = testDiffFn
  2026  
  2027  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  2028  		conn := rs.Ephemeral.ConnInfo
  2029  		if conn["type"] != "telnet" {
  2030  			t.Fatalf("Bad: %#v", conn)
  2031  		}
  2032  		if conn["host"] != "127.0.0.1" {
  2033  			t.Fatalf("Bad: %#v", conn)
  2034  		}
  2035  		if conn["port"] != "2222" {
  2036  			t.Fatalf("Bad: %#v", conn)
  2037  		}
  2038  		if conn["user"] != "superuser" {
  2039  			t.Fatalf("Bad: %#v", conn)
  2040  		}
  2041  		if conn["pass"] != "test" {
  2042  			t.Fatalf("Bad: %#v", conn)
  2043  		}
  2044  
  2045  		return nil
  2046  	}
  2047  
  2048  	ctx := testContext2(t, &ContextOpts{
  2049  		Module: m,
  2050  		Providers: map[string]ResourceProviderFactory{
  2051  			"aws": testProviderFuncFixed(p),
  2052  		},
  2053  		Provisioners: map[string]ResourceProvisionerFactory{
  2054  			"shell": testProvisionerFuncFixed(pr),
  2055  		},
  2056  		Variables: map[string]string{
  2057  			"value": "1",
  2058  			"pass":  "test",
  2059  		},
  2060  	})
  2061  
  2062  	if _, err := ctx.Plan(); err != nil {
  2063  		t.Fatalf("err: %s", err)
  2064  	}
  2065  
  2066  	state, err := ctx.Apply()
  2067  	if err != nil {
  2068  		t.Fatalf("err: %s", err)
  2069  	}
  2070  
  2071  	actual := strings.TrimSpace(state.String())
  2072  	expected := strings.TrimSpace(testTerraformApplyProvisionerStr)
  2073  	if actual != expected {
  2074  		t.Fatalf("bad: \n%s", actual)
  2075  	}
  2076  
  2077  	// Verify apply was invoked
  2078  	if !pr.ApplyCalled {
  2079  		t.Fatalf("provisioner not invoked")
  2080  	}
  2081  }
  2082  
  2083  func TestContext2Apply_destroy(t *testing.T) {
  2084  	m := testModule(t, "apply-destroy")
  2085  	h := new(HookRecordApplyOrder)
  2086  	p := testProvider("aws")
  2087  	p.ApplyFn = testApplyFn
  2088  	p.DiffFn = testDiffFn
  2089  	ctx := testContext2(t, &ContextOpts{
  2090  		Module: m,
  2091  		Hooks:  []Hook{h},
  2092  		Providers: map[string]ResourceProviderFactory{
  2093  			"aws": testProviderFuncFixed(p),
  2094  		},
  2095  	})
  2096  
  2097  	// First plan and apply a create operation
  2098  	if _, err := ctx.Plan(); err != nil {
  2099  		t.Fatalf("err: %s", err)
  2100  	}
  2101  
  2102  	state, err := ctx.Apply()
  2103  	if err != nil {
  2104  		t.Fatalf("err: %s", err)
  2105  	}
  2106  
  2107  	// Next, plan and apply a destroy operation
  2108  	h.Active = true
  2109  	ctx = testContext2(t, &ContextOpts{
  2110  		Destroy: true,
  2111  		State:   state,
  2112  		Module:  m,
  2113  		Hooks:   []Hook{h},
  2114  		Providers: map[string]ResourceProviderFactory{
  2115  			"aws": testProviderFuncFixed(p),
  2116  		},
  2117  	})
  2118  
  2119  	if _, err := ctx.Plan(); err != nil {
  2120  		t.Fatalf("err: %s", err)
  2121  	}
  2122  
  2123  	state, err = ctx.Apply()
  2124  	if err != nil {
  2125  		t.Fatalf("err: %s", err)
  2126  	}
  2127  
  2128  	// Test that things were destroyed
  2129  	actual := strings.TrimSpace(state.String())
  2130  	expected := strings.TrimSpace(testTerraformApplyDestroyStr)
  2131  	if actual != expected {
  2132  		t.Fatalf("bad: \n%s", actual)
  2133  	}
  2134  
  2135  	// Test that things were destroyed _in the right order_
  2136  	expected2 := []string{"aws_instance.bar", "aws_instance.foo"}
  2137  	actual2 := h.IDs
  2138  	if !reflect.DeepEqual(actual2, expected2) {
  2139  		t.Fatalf("expected: %#v\n\ngot:%#v", expected2, actual2)
  2140  	}
  2141  }
  2142  
  2143  func TestContext2Apply_destroyNestedModule(t *testing.T) {
  2144  	m := testModule(t, "apply-destroy-nested-module")
  2145  	p := testProvider("aws")
  2146  	p.ApplyFn = testApplyFn
  2147  	p.DiffFn = testDiffFn
  2148  
  2149  	s := &State{
  2150  		Modules: []*ModuleState{
  2151  			&ModuleState{
  2152  				Path: []string{"root", "child", "subchild"},
  2153  				Resources: map[string]*ResourceState{
  2154  					"aws_instance.bar": &ResourceState{
  2155  						Type: "aws_instance",
  2156  						Primary: &InstanceState{
  2157  							ID: "bar",
  2158  						},
  2159  					},
  2160  				},
  2161  			},
  2162  		},
  2163  	}
  2164  
  2165  	ctx := testContext2(t, &ContextOpts{
  2166  		Module: m,
  2167  		Providers: map[string]ResourceProviderFactory{
  2168  			"aws": testProviderFuncFixed(p),
  2169  		},
  2170  		State: s,
  2171  	})
  2172  
  2173  	// First plan and apply a create operation
  2174  	if _, err := ctx.Plan(); err != nil {
  2175  		t.Fatalf("err: %s", err)
  2176  	}
  2177  
  2178  	state, err := ctx.Apply()
  2179  	if err != nil {
  2180  		t.Fatalf("err: %s", err)
  2181  	}
  2182  
  2183  	// Test that things were destroyed
  2184  	actual := strings.TrimSpace(state.String())
  2185  	expected := strings.TrimSpace(testTerraformApplyDestroyNestedModuleStr)
  2186  	if actual != expected {
  2187  		t.Fatalf("bad: \n%s", actual)
  2188  	}
  2189  }
  2190  
  2191  func TestContext2Apply_destroyDeeplyNestedModule(t *testing.T) {
  2192  	m := testModule(t, "apply-destroy-deeply-nested-module")
  2193  	p := testProvider("aws")
  2194  	p.ApplyFn = testApplyFn
  2195  	p.DiffFn = testDiffFn
  2196  
  2197  	s := &State{
  2198  		Modules: []*ModuleState{
  2199  			&ModuleState{
  2200  				Path: []string{"root", "child", "subchild", "subsubchild"},
  2201  				Resources: map[string]*ResourceState{
  2202  					"aws_instance.bar": &ResourceState{
  2203  						Type: "aws_instance",
  2204  						Primary: &InstanceState{
  2205  							ID: "bar",
  2206  						},
  2207  					},
  2208  				},
  2209  			},
  2210  		},
  2211  	}
  2212  
  2213  	ctx := testContext2(t, &ContextOpts{
  2214  		Module: m,
  2215  		Providers: map[string]ResourceProviderFactory{
  2216  			"aws": testProviderFuncFixed(p),
  2217  		},
  2218  		State: s,
  2219  	})
  2220  
  2221  	// First plan and apply a create operation
  2222  	if _, err := ctx.Plan(); err != nil {
  2223  		t.Fatalf("err: %s", err)
  2224  	}
  2225  
  2226  	state, err := ctx.Apply()
  2227  	if err != nil {
  2228  		t.Fatalf("err: %s", err)
  2229  	}
  2230  
  2231  	// Test that things were destroyed
  2232  	actual := strings.TrimSpace(state.String())
  2233  	expected := strings.TrimSpace(`
  2234  module.child.subchild.subsubchild:
  2235    <no state>
  2236  	`)
  2237  	if actual != expected {
  2238  		t.Fatalf("bad: \n%s", actual)
  2239  	}
  2240  }
  2241  
  2242  func TestContext2Apply_destroyOutputs(t *testing.T) {
  2243  	m := testModule(t, "apply-destroy-outputs")
  2244  	h := new(HookRecordApplyOrder)
  2245  	p := testProvider("aws")
  2246  	p.ApplyFn = testApplyFn
  2247  	p.DiffFn = testDiffFn
  2248  	ctx := testContext2(t, &ContextOpts{
  2249  		Module: m,
  2250  		Hooks:  []Hook{h},
  2251  		Providers: map[string]ResourceProviderFactory{
  2252  			"aws": testProviderFuncFixed(p),
  2253  		},
  2254  	})
  2255  
  2256  	// First plan and apply a create operation
  2257  	if _, err := ctx.Plan(); err != nil {
  2258  		t.Fatalf("err: %s", err)
  2259  	}
  2260  
  2261  	state, err := ctx.Apply()
  2262  
  2263  	if err != nil {
  2264  		t.Fatalf("err: %s", err)
  2265  	}
  2266  
  2267  	// Next, plan and apply a destroy operation
  2268  	h.Active = true
  2269  	ctx = testContext2(t, &ContextOpts{
  2270  		Destroy: true,
  2271  		State:   state,
  2272  		Module:  m,
  2273  		Hooks:   []Hook{h},
  2274  		Providers: map[string]ResourceProviderFactory{
  2275  			"aws": testProviderFuncFixed(p),
  2276  		},
  2277  	})
  2278  
  2279  	if _, err := ctx.Plan(); err != nil {
  2280  		t.Fatalf("err: %s", err)
  2281  	}
  2282  
  2283  	state, err = ctx.Apply()
  2284  	if err != nil {
  2285  		t.Fatalf("err: %s", err)
  2286  	}
  2287  
  2288  	mod := state.RootModule()
  2289  	if len(mod.Resources) > 0 {
  2290  		t.Fatalf("bad: %#v", mod)
  2291  	}
  2292  }
  2293  
  2294  func TestContext2Apply_destroyOrphan(t *testing.T) {
  2295  	m := testModule(t, "apply-error")
  2296  	p := testProvider("aws")
  2297  	s := &State{
  2298  		Modules: []*ModuleState{
  2299  			&ModuleState{
  2300  				Path: rootModulePath,
  2301  				Resources: map[string]*ResourceState{
  2302  					"aws_instance.baz": &ResourceState{
  2303  						Type: "aws_instance",
  2304  						Primary: &InstanceState{
  2305  							ID: "bar",
  2306  						},
  2307  					},
  2308  				},
  2309  			},
  2310  		},
  2311  	}
  2312  	ctx := testContext2(t, &ContextOpts{
  2313  		Module: m,
  2314  		Providers: map[string]ResourceProviderFactory{
  2315  			"aws": testProviderFuncFixed(p),
  2316  		},
  2317  		State: s,
  2318  	})
  2319  
  2320  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  2321  		if d.Destroy {
  2322  			return nil, nil
  2323  		}
  2324  
  2325  		result := s.MergeDiff(d)
  2326  		result.ID = "foo"
  2327  		return result, nil
  2328  	}
  2329  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  2330  		return &InstanceDiff{
  2331  			Attributes: map[string]*ResourceAttrDiff{
  2332  				"num": &ResourceAttrDiff{
  2333  					New: "bar",
  2334  				},
  2335  			},
  2336  		}, nil
  2337  	}
  2338  
  2339  	if _, err := ctx.Plan(); err != nil {
  2340  		t.Fatalf("err: %s", err)
  2341  	}
  2342  
  2343  	state, err := ctx.Apply()
  2344  	if err != nil {
  2345  		t.Fatalf("err: %s", err)
  2346  	}
  2347  
  2348  	mod := state.RootModule()
  2349  	if _, ok := mod.Resources["aws_instance.baz"]; ok {
  2350  		t.Fatalf("bad: %#v", mod.Resources)
  2351  	}
  2352  }
  2353  
  2354  func TestContext2Apply_destroyTaintedProvisioner(t *testing.T) {
  2355  	m := testModule(t, "apply-destroy-provisioner")
  2356  	p := testProvider("aws")
  2357  	pr := testProvisioner()
  2358  	p.ApplyFn = testApplyFn
  2359  	p.DiffFn = testDiffFn
  2360  
  2361  	called := false
  2362  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  2363  		called = true
  2364  		return nil
  2365  	}
  2366  
  2367  	s := &State{
  2368  		Modules: []*ModuleState{
  2369  			&ModuleState{
  2370  				Path: rootModulePath,
  2371  				Resources: map[string]*ResourceState{
  2372  					"aws_instance.foo": &ResourceState{
  2373  						Type: "aws_instance",
  2374  						Tainted: []*InstanceState{
  2375  							&InstanceState{
  2376  								ID: "bar",
  2377  								Attributes: map[string]string{
  2378  									"id": "bar",
  2379  								},
  2380  							},
  2381  						},
  2382  					},
  2383  				},
  2384  			},
  2385  		},
  2386  	}
  2387  
  2388  	ctx := testContext2(t, &ContextOpts{
  2389  		Module: m,
  2390  		Providers: map[string]ResourceProviderFactory{
  2391  			"aws": testProviderFuncFixed(p),
  2392  		},
  2393  		Provisioners: map[string]ResourceProvisionerFactory{
  2394  			"shell": testProvisionerFuncFixed(pr),
  2395  		},
  2396  		State:   s,
  2397  		Destroy: true,
  2398  	})
  2399  
  2400  	if _, err := ctx.Plan(); err != nil {
  2401  		t.Fatalf("err: %s", err)
  2402  	}
  2403  
  2404  	state, err := ctx.Apply()
  2405  	if err != nil {
  2406  		t.Fatalf("err: %s", err)
  2407  	}
  2408  
  2409  	if called {
  2410  		t.Fatal("provisioner should not be called")
  2411  	}
  2412  
  2413  	actual := strings.TrimSpace(state.String())
  2414  	expected := strings.TrimSpace("<no state>")
  2415  	if actual != expected {
  2416  		t.Fatalf("bad: \n%s", actual)
  2417  	}
  2418  }
  2419  
  2420  func TestContext2Apply_error(t *testing.T) {
  2421  	errored := false
  2422  
  2423  	m := testModule(t, "apply-error")
  2424  	p := testProvider("aws")
  2425  	ctx := testContext2(t, &ContextOpts{
  2426  		Module: m,
  2427  		Providers: map[string]ResourceProviderFactory{
  2428  			"aws": testProviderFuncFixed(p),
  2429  		},
  2430  	})
  2431  
  2432  	p.ApplyFn = func(*InstanceInfo, *InstanceState, *InstanceDiff) (*InstanceState, error) {
  2433  		if errored {
  2434  			state := &InstanceState{
  2435  				ID: "bar",
  2436  			}
  2437  			return state, fmt.Errorf("error")
  2438  		}
  2439  		errored = true
  2440  
  2441  		return &InstanceState{
  2442  			ID: "foo",
  2443  			Attributes: map[string]string{
  2444  				"num": "2",
  2445  			},
  2446  		}, nil
  2447  	}
  2448  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  2449  		return &InstanceDiff{
  2450  			Attributes: map[string]*ResourceAttrDiff{
  2451  				"num": &ResourceAttrDiff{
  2452  					New: "bar",
  2453  				},
  2454  			},
  2455  		}, nil
  2456  	}
  2457  
  2458  	if _, err := ctx.Plan(); err != nil {
  2459  		t.Fatalf("err: %s", err)
  2460  	}
  2461  
  2462  	state, err := ctx.Apply()
  2463  	if err == nil {
  2464  		t.Fatal("should have error")
  2465  	}
  2466  
  2467  	actual := strings.TrimSpace(state.String())
  2468  	expected := strings.TrimSpace(testTerraformApplyErrorStr)
  2469  	if actual != expected {
  2470  		t.Fatalf("bad: \n%s", actual)
  2471  	}
  2472  }
  2473  
  2474  func TestContext2Apply_errorPartial(t *testing.T) {
  2475  	errored := false
  2476  
  2477  	m := testModule(t, "apply-error")
  2478  	p := testProvider("aws")
  2479  	s := &State{
  2480  		Modules: []*ModuleState{
  2481  			&ModuleState{
  2482  				Path: rootModulePath,
  2483  				Resources: map[string]*ResourceState{
  2484  					"aws_instance.bar": &ResourceState{
  2485  						Type: "aws_instance",
  2486  						Primary: &InstanceState{
  2487  							ID: "bar",
  2488  						},
  2489  					},
  2490  				},
  2491  			},
  2492  		},
  2493  	}
  2494  	ctx := testContext2(t, &ContextOpts{
  2495  		Module: m,
  2496  		Providers: map[string]ResourceProviderFactory{
  2497  			"aws": testProviderFuncFixed(p),
  2498  		},
  2499  		State: s,
  2500  	})
  2501  
  2502  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  2503  		if errored {
  2504  			return s, fmt.Errorf("error")
  2505  		}
  2506  		errored = true
  2507  
  2508  		return &InstanceState{
  2509  			ID: "foo",
  2510  			Attributes: map[string]string{
  2511  				"num": "2",
  2512  			},
  2513  		}, nil
  2514  	}
  2515  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  2516  		return &InstanceDiff{
  2517  			Attributes: map[string]*ResourceAttrDiff{
  2518  				"num": &ResourceAttrDiff{
  2519  					New: "bar",
  2520  				},
  2521  			},
  2522  		}, nil
  2523  	}
  2524  
  2525  	if _, err := ctx.Plan(); err != nil {
  2526  		t.Fatalf("err: %s", err)
  2527  	}
  2528  
  2529  	state, err := ctx.Apply()
  2530  	if err == nil {
  2531  		t.Fatal("should have error")
  2532  	}
  2533  
  2534  	mod := state.RootModule()
  2535  	if len(mod.Resources) != 2 {
  2536  		t.Fatalf("bad: %#v", mod.Resources)
  2537  	}
  2538  
  2539  	actual := strings.TrimSpace(state.String())
  2540  	expected := strings.TrimSpace(testTerraformApplyErrorPartialStr)
  2541  	if actual != expected {
  2542  		t.Fatalf("bad: \n%s", actual)
  2543  	}
  2544  }
  2545  
  2546  func TestContext2Apply_hook(t *testing.T) {
  2547  	m := testModule(t, "apply-good")
  2548  	h := new(MockHook)
  2549  	p := testProvider("aws")
  2550  	p.ApplyFn = testApplyFn
  2551  	p.DiffFn = testDiffFn
  2552  	ctx := testContext2(t, &ContextOpts{
  2553  		Module: m,
  2554  		Hooks:  []Hook{h},
  2555  		Providers: map[string]ResourceProviderFactory{
  2556  			"aws": testProviderFuncFixed(p),
  2557  		},
  2558  	})
  2559  
  2560  	if _, err := ctx.Plan(); err != nil {
  2561  		t.Fatalf("err: %s", err)
  2562  	}
  2563  
  2564  	if _, err := ctx.Apply(); err != nil {
  2565  		t.Fatalf("err: %s", err)
  2566  	}
  2567  
  2568  	if !h.PreApplyCalled {
  2569  		t.Fatal("should be called")
  2570  	}
  2571  	if !h.PostApplyCalled {
  2572  		t.Fatal("should be called")
  2573  	}
  2574  	if !h.PostStateUpdateCalled {
  2575  		t.Fatalf("should call post state update")
  2576  	}
  2577  }
  2578  
  2579  func TestContext2Apply_hookOrphan(t *testing.T) {
  2580  	m := testModule(t, "apply-blank")
  2581  	h := new(MockHook)
  2582  	p := testProvider("aws")
  2583  	p.ApplyFn = testApplyFn
  2584  	p.DiffFn = testDiffFn
  2585  
  2586  	state := &State{
  2587  		Modules: []*ModuleState{
  2588  			&ModuleState{
  2589  				Path: rootModulePath,
  2590  				Resources: map[string]*ResourceState{
  2591  					"aws_instance.bar": &ResourceState{
  2592  						Type: "aws_instance",
  2593  						Primary: &InstanceState{
  2594  							ID: "bar",
  2595  						},
  2596  					},
  2597  				},
  2598  			},
  2599  		},
  2600  	}
  2601  
  2602  	ctx := testContext2(t, &ContextOpts{
  2603  		Module: m,
  2604  		State:  state,
  2605  		Hooks:  []Hook{h},
  2606  		Providers: map[string]ResourceProviderFactory{
  2607  			"aws": testProviderFuncFixed(p),
  2608  		},
  2609  	})
  2610  
  2611  	if _, err := ctx.Plan(); err != nil {
  2612  		t.Fatalf("err: %s", err)
  2613  	}
  2614  
  2615  	if _, err := ctx.Apply(); err != nil {
  2616  		t.Fatalf("err: %s", err)
  2617  	}
  2618  
  2619  	if !h.PreApplyCalled {
  2620  		t.Fatal("should be called")
  2621  	}
  2622  	if !h.PostApplyCalled {
  2623  		t.Fatal("should be called")
  2624  	}
  2625  	if !h.PostStateUpdateCalled {
  2626  		t.Fatalf("should call post state update")
  2627  	}
  2628  }
  2629  
  2630  func TestContext2Apply_idAttr(t *testing.T) {
  2631  	m := testModule(t, "apply-idattr")
  2632  	p := testProvider("aws")
  2633  	ctx := testContext2(t, &ContextOpts{
  2634  		Module: m,
  2635  		Providers: map[string]ResourceProviderFactory{
  2636  			"aws": testProviderFuncFixed(p),
  2637  		},
  2638  	})
  2639  
  2640  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  2641  		result := s.MergeDiff(d)
  2642  		result.ID = "foo"
  2643  		result.Attributes = map[string]string{
  2644  			"id": "bar",
  2645  		}
  2646  
  2647  		return result, nil
  2648  	}
  2649  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  2650  		return &InstanceDiff{
  2651  			Attributes: map[string]*ResourceAttrDiff{
  2652  				"num": &ResourceAttrDiff{
  2653  					New: "bar",
  2654  				},
  2655  			},
  2656  		}, nil
  2657  	}
  2658  
  2659  	if _, err := ctx.Plan(); err != nil {
  2660  		t.Fatalf("err: %s", err)
  2661  	}
  2662  
  2663  	state, err := ctx.Apply()
  2664  	if err != nil {
  2665  		t.Fatalf("err: %s", err)
  2666  	}
  2667  
  2668  	mod := state.RootModule()
  2669  	rs, ok := mod.Resources["aws_instance.foo"]
  2670  	if !ok {
  2671  		t.Fatal("not in state")
  2672  	}
  2673  	if rs.Primary.ID != "foo" {
  2674  		t.Fatalf("bad: %#v", rs.Primary.ID)
  2675  	}
  2676  	if rs.Primary.Attributes["id"] != "foo" {
  2677  		t.Fatalf("bad: %#v", rs.Primary.Attributes)
  2678  	}
  2679  }
  2680  
  2681  func TestContext2Apply_output(t *testing.T) {
  2682  	m := testModule(t, "apply-output")
  2683  	p := testProvider("aws")
  2684  	p.ApplyFn = testApplyFn
  2685  	p.DiffFn = testDiffFn
  2686  	ctx := testContext2(t, &ContextOpts{
  2687  		Module: m,
  2688  		Providers: map[string]ResourceProviderFactory{
  2689  			"aws": testProviderFuncFixed(p),
  2690  		},
  2691  	})
  2692  
  2693  	if _, err := ctx.Plan(); err != nil {
  2694  		t.Fatalf("err: %s", err)
  2695  	}
  2696  
  2697  	state, err := ctx.Apply()
  2698  	if err != nil {
  2699  		t.Fatalf("err: %s", err)
  2700  	}
  2701  
  2702  	actual := strings.TrimSpace(state.String())
  2703  	expected := strings.TrimSpace(testTerraformApplyOutputStr)
  2704  	if actual != expected {
  2705  		t.Fatalf("bad: \n%s", actual)
  2706  	}
  2707  }
  2708  
  2709  func TestContext2Apply_outputInvalid(t *testing.T) {
  2710  	m := testModule(t, "apply-output-invalid")
  2711  	p := testProvider("aws")
  2712  	p.ApplyFn = testApplyFn
  2713  	p.DiffFn = testDiffFn
  2714  	ctx := testContext2(t, &ContextOpts{
  2715  		Module: m,
  2716  		Providers: map[string]ResourceProviderFactory{
  2717  			"aws": testProviderFuncFixed(p),
  2718  		},
  2719  	})
  2720  
  2721  	_, err := ctx.Plan()
  2722  	if err == nil {
  2723  		t.Fatalf("err: %s", err)
  2724  	}
  2725  	if !strings.Contains(err.Error(), "is not a string") {
  2726  		t.Fatalf("err: %s", err)
  2727  	}
  2728  }
  2729  
  2730  func TestContext2Apply_outputList(t *testing.T) {
  2731  	m := testModule(t, "apply-output-list")
  2732  	p := testProvider("aws")
  2733  	p.ApplyFn = testApplyFn
  2734  	p.DiffFn = testDiffFn
  2735  	ctx := testContext2(t, &ContextOpts{
  2736  		Module: m,
  2737  		Providers: map[string]ResourceProviderFactory{
  2738  			"aws": testProviderFuncFixed(p),
  2739  		},
  2740  	})
  2741  
  2742  	if _, err := ctx.Plan(); err != nil {
  2743  		t.Fatalf("err: %s", err)
  2744  	}
  2745  
  2746  	state, err := ctx.Apply()
  2747  	if err != nil {
  2748  		t.Fatalf("err: %s", err)
  2749  	}
  2750  
  2751  	actual := strings.TrimSpace(state.String())
  2752  	expected := strings.TrimSpace(testTerraformApplyOutputListStr)
  2753  	if actual != expected {
  2754  		t.Fatalf("bad: \n%s", actual)
  2755  	}
  2756  }
  2757  
  2758  func TestContext2Apply_outputMulti(t *testing.T) {
  2759  	m := testModule(t, "apply-output-multi")
  2760  	p := testProvider("aws")
  2761  	p.ApplyFn = testApplyFn
  2762  	p.DiffFn = testDiffFn
  2763  	ctx := testContext2(t, &ContextOpts{
  2764  		Module: m,
  2765  		Providers: map[string]ResourceProviderFactory{
  2766  			"aws": testProviderFuncFixed(p),
  2767  		},
  2768  	})
  2769  
  2770  	if _, err := ctx.Plan(); err != nil {
  2771  		t.Fatalf("err: %s", err)
  2772  	}
  2773  
  2774  	state, err := ctx.Apply()
  2775  	if err != nil {
  2776  		t.Fatalf("err: %s", err)
  2777  	}
  2778  
  2779  	actual := strings.TrimSpace(state.String())
  2780  	expected := strings.TrimSpace(testTerraformApplyOutputMultiStr)
  2781  	if actual != expected {
  2782  		t.Fatalf("bad: \n%s", actual)
  2783  	}
  2784  }
  2785  
  2786  func TestContext2Apply_outputMultiIndex(t *testing.T) {
  2787  	m := testModule(t, "apply-output-multi-index")
  2788  	p := testProvider("aws")
  2789  	p.ApplyFn = testApplyFn
  2790  	p.DiffFn = testDiffFn
  2791  	ctx := testContext2(t, &ContextOpts{
  2792  		Module: m,
  2793  		Providers: map[string]ResourceProviderFactory{
  2794  			"aws": testProviderFuncFixed(p),
  2795  		},
  2796  	})
  2797  
  2798  	if _, err := ctx.Plan(); err != nil {
  2799  		t.Fatalf("err: %s", err)
  2800  	}
  2801  
  2802  	state, err := ctx.Apply()
  2803  	if err != nil {
  2804  		t.Fatalf("err: %s", err)
  2805  	}
  2806  
  2807  	actual := strings.TrimSpace(state.String())
  2808  	expected := strings.TrimSpace(testTerraformApplyOutputMultiIndexStr)
  2809  	if actual != expected {
  2810  		t.Fatalf("bad: \n%s", actual)
  2811  	}
  2812  }
  2813  
  2814  func TestContext2Apply_taint(t *testing.T) {
  2815  	m := testModule(t, "apply-taint")
  2816  	p := testProvider("aws")
  2817  
  2818  	// destroyCount tests against regression of
  2819  	// https://github.com/hashicorp/terraform/issues/1056
  2820  	var destroyCount = int32(0)
  2821  	var once sync.Once
  2822  	simulateProviderDelay := func() {
  2823  		time.Sleep(10 * time.Millisecond)
  2824  	}
  2825  
  2826  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  2827  		once.Do(simulateProviderDelay)
  2828  		if d.Destroy {
  2829  			atomic.AddInt32(&destroyCount, 1)
  2830  		}
  2831  		return testApplyFn(info, s, d)
  2832  	}
  2833  	p.DiffFn = testDiffFn
  2834  	s := &State{
  2835  		Modules: []*ModuleState{
  2836  			&ModuleState{
  2837  				Path: rootModulePath,
  2838  				Resources: map[string]*ResourceState{
  2839  					"aws_instance.bar": &ResourceState{
  2840  						Type: "aws_instance",
  2841  						Tainted: []*InstanceState{
  2842  							&InstanceState{
  2843  								ID: "baz",
  2844  								Attributes: map[string]string{
  2845  									"num":  "2",
  2846  									"type": "aws_instance",
  2847  								},
  2848  							},
  2849  						},
  2850  					},
  2851  				},
  2852  			},
  2853  		},
  2854  	}
  2855  	ctx := testContext2(t, &ContextOpts{
  2856  		Module: m,
  2857  		Providers: map[string]ResourceProviderFactory{
  2858  			"aws": testProviderFuncFixed(p),
  2859  		},
  2860  		State: s,
  2861  	})
  2862  
  2863  	if _, err := ctx.Plan(); err != nil {
  2864  		t.Fatalf("err: %s", err)
  2865  	}
  2866  
  2867  	state, err := ctx.Apply()
  2868  	if err != nil {
  2869  		t.Fatalf("err: %s", err)
  2870  	}
  2871  
  2872  	actual := strings.TrimSpace(state.String())
  2873  	expected := strings.TrimSpace(testTerraformApplyTaintStr)
  2874  	if actual != expected {
  2875  		t.Fatalf("bad:\n%s", actual)
  2876  	}
  2877  
  2878  	if destroyCount != 1 {
  2879  		t.Fatalf("Expected 1 destroy, got %d", destroyCount)
  2880  	}
  2881  }
  2882  
  2883  func TestContext2Apply_taintDep(t *testing.T) {
  2884  	m := testModule(t, "apply-taint-dep")
  2885  	p := testProvider("aws")
  2886  	p.ApplyFn = testApplyFn
  2887  	p.DiffFn = testDiffFn
  2888  	s := &State{
  2889  		Modules: []*ModuleState{
  2890  			&ModuleState{
  2891  				Path: rootModulePath,
  2892  				Resources: map[string]*ResourceState{
  2893  					"aws_instance.foo": &ResourceState{
  2894  						Type: "aws_instance",
  2895  						Tainted: []*InstanceState{
  2896  							&InstanceState{
  2897  								ID: "baz",
  2898  								Attributes: map[string]string{
  2899  									"num":  "2",
  2900  									"type": "aws_instance",
  2901  								},
  2902  							},
  2903  						},
  2904  					},
  2905  					"aws_instance.bar": &ResourceState{
  2906  						Type: "aws_instance",
  2907  						Primary: &InstanceState{
  2908  							ID: "bar",
  2909  							Attributes: map[string]string{
  2910  								"foo":  "baz",
  2911  								"num":  "2",
  2912  								"type": "aws_instance",
  2913  							},
  2914  						},
  2915  					},
  2916  				},
  2917  			},
  2918  		},
  2919  	}
  2920  	ctx := testContext2(t, &ContextOpts{
  2921  		Module: m,
  2922  		Providers: map[string]ResourceProviderFactory{
  2923  			"aws": testProviderFuncFixed(p),
  2924  		},
  2925  		State: s,
  2926  	})
  2927  
  2928  	if p, err := ctx.Plan(); err != nil {
  2929  		t.Fatalf("err: %s", err)
  2930  	} else {
  2931  		t.Logf("plan: %s", p)
  2932  	}
  2933  
  2934  	state, err := ctx.Apply()
  2935  	if err != nil {
  2936  		t.Fatalf("err: %s", err)
  2937  	}
  2938  
  2939  	actual := strings.TrimSpace(state.String())
  2940  	expected := strings.TrimSpace(testTerraformApplyTaintDepStr)
  2941  	if actual != expected {
  2942  		t.Fatalf("bad:\n%s", actual)
  2943  	}
  2944  }
  2945  
  2946  func TestContext2Apply_taintDepRequiresNew(t *testing.T) {
  2947  	m := testModule(t, "apply-taint-dep-requires-new")
  2948  	p := testProvider("aws")
  2949  	p.ApplyFn = testApplyFn
  2950  	p.DiffFn = testDiffFn
  2951  	s := &State{
  2952  		Modules: []*ModuleState{
  2953  			&ModuleState{
  2954  				Path: rootModulePath,
  2955  				Resources: map[string]*ResourceState{
  2956  					"aws_instance.foo": &ResourceState{
  2957  						Type: "aws_instance",
  2958  						Tainted: []*InstanceState{
  2959  							&InstanceState{
  2960  								ID: "baz",
  2961  								Attributes: map[string]string{
  2962  									"num":  "2",
  2963  									"type": "aws_instance",
  2964  								},
  2965  							},
  2966  						},
  2967  					},
  2968  					"aws_instance.bar": &ResourceState{
  2969  						Type: "aws_instance",
  2970  						Primary: &InstanceState{
  2971  							ID: "bar",
  2972  							Attributes: map[string]string{
  2973  								"foo":  "baz",
  2974  								"num":  "2",
  2975  								"type": "aws_instance",
  2976  							},
  2977  						},
  2978  					},
  2979  				},
  2980  			},
  2981  		},
  2982  	}
  2983  	ctx := testContext2(t, &ContextOpts{
  2984  		Module: m,
  2985  		Providers: map[string]ResourceProviderFactory{
  2986  			"aws": testProviderFuncFixed(p),
  2987  		},
  2988  		State: s,
  2989  	})
  2990  
  2991  	if p, err := ctx.Plan(); err != nil {
  2992  		t.Fatalf("err: %s", err)
  2993  	} else {
  2994  		t.Logf("plan: %s", p)
  2995  	}
  2996  
  2997  	state, err := ctx.Apply()
  2998  	if err != nil {
  2999  		t.Fatalf("err: %s", err)
  3000  	}
  3001  
  3002  	actual := strings.TrimSpace(state.String())
  3003  	expected := strings.TrimSpace(testTerraformApplyTaintDepRequireNewStr)
  3004  	if actual != expected {
  3005  		t.Fatalf("bad:\n%s", actual)
  3006  	}
  3007  }
  3008  
  3009  func TestContext2Apply_targeted(t *testing.T) {
  3010  	m := testModule(t, "apply-targeted")
  3011  	p := testProvider("aws")
  3012  	p.ApplyFn = testApplyFn
  3013  	p.DiffFn = testDiffFn
  3014  	ctx := testContext2(t, &ContextOpts{
  3015  		Module: m,
  3016  		Providers: map[string]ResourceProviderFactory{
  3017  			"aws": testProviderFuncFixed(p),
  3018  		},
  3019  		Targets: []string{"aws_instance.foo"},
  3020  	})
  3021  
  3022  	if _, err := ctx.Plan(); err != nil {
  3023  		t.Fatalf("err: %s", err)
  3024  	}
  3025  
  3026  	state, err := ctx.Apply()
  3027  	if err != nil {
  3028  		t.Fatalf("err: %s", err)
  3029  	}
  3030  
  3031  	mod := state.RootModule()
  3032  	if len(mod.Resources) != 1 {
  3033  		t.Fatalf("expected 1 resource, got: %#v", mod.Resources)
  3034  	}
  3035  
  3036  	checkStateString(t, state, `
  3037  aws_instance.foo:
  3038    ID = foo
  3039    num = 2
  3040    type = aws_instance
  3041  	`)
  3042  }
  3043  
  3044  func TestContext2Apply_targetedCount(t *testing.T) {
  3045  	m := testModule(t, "apply-targeted-count")
  3046  	p := testProvider("aws")
  3047  	p.ApplyFn = testApplyFn
  3048  	p.DiffFn = testDiffFn
  3049  	ctx := testContext2(t, &ContextOpts{
  3050  		Module: m,
  3051  		Providers: map[string]ResourceProviderFactory{
  3052  			"aws": testProviderFuncFixed(p),
  3053  		},
  3054  		Targets: []string{"aws_instance.foo"},
  3055  	})
  3056  
  3057  	if _, err := ctx.Plan(); err != nil {
  3058  		t.Fatalf("err: %s", err)
  3059  	}
  3060  
  3061  	state, err := ctx.Apply()
  3062  	if err != nil {
  3063  		t.Fatalf("err: %s", err)
  3064  	}
  3065  
  3066  	checkStateString(t, state, `
  3067  aws_instance.foo.0:
  3068    ID = foo
  3069  aws_instance.foo.1:
  3070    ID = foo
  3071  aws_instance.foo.2:
  3072    ID = foo
  3073  	`)
  3074  }
  3075  
  3076  func TestContext2Apply_targetedCountIndex(t *testing.T) {
  3077  	m := testModule(t, "apply-targeted-count")
  3078  	p := testProvider("aws")
  3079  	p.ApplyFn = testApplyFn
  3080  	p.DiffFn = testDiffFn
  3081  	ctx := testContext2(t, &ContextOpts{
  3082  		Module: m,
  3083  		Providers: map[string]ResourceProviderFactory{
  3084  			"aws": testProviderFuncFixed(p),
  3085  		},
  3086  		Targets: []string{"aws_instance.foo[1]"},
  3087  	})
  3088  
  3089  	if _, err := ctx.Plan(); err != nil {
  3090  		t.Fatalf("err: %s", err)
  3091  	}
  3092  
  3093  	state, err := ctx.Apply()
  3094  	if err != nil {
  3095  		t.Fatalf("err: %s", err)
  3096  	}
  3097  
  3098  	checkStateString(t, state, `
  3099  aws_instance.foo.1:
  3100    ID = foo
  3101  	`)
  3102  }
  3103  
  3104  func TestContext2Apply_targetedDestroy(t *testing.T) {
  3105  	m := testModule(t, "apply-targeted")
  3106  	p := testProvider("aws")
  3107  	p.ApplyFn = testApplyFn
  3108  	p.DiffFn = testDiffFn
  3109  	ctx := testContext2(t, &ContextOpts{
  3110  		Module: m,
  3111  		Providers: map[string]ResourceProviderFactory{
  3112  			"aws": testProviderFuncFixed(p),
  3113  		},
  3114  		State: &State{
  3115  			Modules: []*ModuleState{
  3116  				&ModuleState{
  3117  					Path: rootModulePath,
  3118  					Resources: map[string]*ResourceState{
  3119  						"aws_instance.foo": resourceState("aws_instance", "i-bcd345"),
  3120  						"aws_instance.bar": resourceState("aws_instance", "i-abc123"),
  3121  					},
  3122  				},
  3123  			},
  3124  		},
  3125  		Targets: []string{"aws_instance.foo"},
  3126  		Destroy: true,
  3127  	})
  3128  
  3129  	if _, err := ctx.Plan(); err != nil {
  3130  		t.Fatalf("err: %s", err)
  3131  	}
  3132  
  3133  	state, err := ctx.Apply()
  3134  	if err != nil {
  3135  		t.Fatalf("err: %s", err)
  3136  	}
  3137  
  3138  	mod := state.RootModule()
  3139  	if len(mod.Resources) != 1 {
  3140  		t.Fatalf("expected 1 resource, got: %#v", mod.Resources)
  3141  	}
  3142  
  3143  	checkStateString(t, state, `
  3144  aws_instance.bar:
  3145    ID = i-abc123
  3146  	`)
  3147  }
  3148  
  3149  func TestContext2Apply_targetedDestroyCountIndex(t *testing.T) {
  3150  	m := testModule(t, "apply-targeted-count")
  3151  	p := testProvider("aws")
  3152  	p.ApplyFn = testApplyFn
  3153  	p.DiffFn = testDiffFn
  3154  	ctx := testContext2(t, &ContextOpts{
  3155  		Module: m,
  3156  		Providers: map[string]ResourceProviderFactory{
  3157  			"aws": testProviderFuncFixed(p),
  3158  		},
  3159  		State: &State{
  3160  			Modules: []*ModuleState{
  3161  				&ModuleState{
  3162  					Path: rootModulePath,
  3163  					Resources: map[string]*ResourceState{
  3164  						"aws_instance.foo.0": resourceState("aws_instance", "i-bcd345"),
  3165  						"aws_instance.foo.1": resourceState("aws_instance", "i-bcd345"),
  3166  						"aws_instance.foo.2": resourceState("aws_instance", "i-bcd345"),
  3167  						"aws_instance.bar.0": resourceState("aws_instance", "i-abc123"),
  3168  						"aws_instance.bar.1": resourceState("aws_instance", "i-abc123"),
  3169  						"aws_instance.bar.2": resourceState("aws_instance", "i-abc123"),
  3170  					},
  3171  				},
  3172  			},
  3173  		},
  3174  		Targets: []string{
  3175  			"aws_instance.foo[2]",
  3176  			"aws_instance.bar[1]",
  3177  		},
  3178  		Destroy: true,
  3179  	})
  3180  
  3181  	if _, err := ctx.Plan(); err != nil {
  3182  		t.Fatalf("err: %s", err)
  3183  	}
  3184  
  3185  	state, err := ctx.Apply()
  3186  	if err != nil {
  3187  		t.Fatalf("err: %s", err)
  3188  	}
  3189  
  3190  	checkStateString(t, state, `
  3191  aws_instance.bar.0:
  3192    ID = i-abc123
  3193  aws_instance.bar.2:
  3194    ID = i-abc123
  3195  aws_instance.foo.0:
  3196    ID = i-bcd345
  3197  aws_instance.foo.1:
  3198    ID = i-bcd345
  3199  	`)
  3200  }
  3201  
  3202  func TestContext2Apply_targetedModule(t *testing.T) {
  3203  	m := testModule(t, "apply-targeted-module")
  3204  	p := testProvider("aws")
  3205  	p.ApplyFn = testApplyFn
  3206  	p.DiffFn = testDiffFn
  3207  	ctx := testContext2(t, &ContextOpts{
  3208  		Module: m,
  3209  		Providers: map[string]ResourceProviderFactory{
  3210  			"aws": testProviderFuncFixed(p),
  3211  		},
  3212  		Targets: []string{"module.child"},
  3213  	})
  3214  
  3215  	if _, err := ctx.Plan(); err != nil {
  3216  		t.Fatalf("err: %s", err)
  3217  	}
  3218  
  3219  	state, err := ctx.Apply()
  3220  	if err != nil {
  3221  		t.Fatalf("err: %s", err)
  3222  	}
  3223  
  3224  	mod := state.ModuleByPath([]string{"root", "child"})
  3225  	if mod == nil {
  3226  		t.Fatalf("no child module found in the state!\n\n%#v", state)
  3227  	}
  3228  	if len(mod.Resources) != 2 {
  3229  		t.Fatalf("expected 2 resources, got: %#v", mod.Resources)
  3230  	}
  3231  
  3232  	checkStateString(t, state, `
  3233  <no state>
  3234  module.child:
  3235    aws_instance.bar:
  3236      ID = foo
  3237      num = 2
  3238      type = aws_instance
  3239    aws_instance.foo:
  3240      ID = foo
  3241      num = 2
  3242      type = aws_instance
  3243  	`)
  3244  }
  3245  
  3246  // GH-1858
  3247  func TestContext2Apply_targetedModuleDep(t *testing.T) {
  3248  	m := testModule(t, "apply-targeted-module-dep")
  3249  	p := testProvider("aws")
  3250  	p.ApplyFn = testApplyFn
  3251  	p.DiffFn = testDiffFn
  3252  	ctx := testContext2(t, &ContextOpts{
  3253  		Module: m,
  3254  		Providers: map[string]ResourceProviderFactory{
  3255  			"aws": testProviderFuncFixed(p),
  3256  		},
  3257  		Targets: []string{"aws_instance.foo"},
  3258  	})
  3259  
  3260  	if _, err := ctx.Plan(); err != nil {
  3261  		t.Fatalf("err: %s", err)
  3262  	}
  3263  
  3264  	state, err := ctx.Apply()
  3265  	if err != nil {
  3266  		t.Fatalf("err: %s", err)
  3267  	}
  3268  
  3269  	checkStateString(t, state, `
  3270  aws_instance.foo:
  3271    ID = foo
  3272    foo = foo
  3273    type = aws_instance
  3274  
  3275    Dependencies:
  3276      module.child
  3277  
  3278  module.child:
  3279    aws_instance.mod:
  3280      ID = foo
  3281  
  3282    Outputs:
  3283  
  3284    output = foo
  3285  	`)
  3286  }
  3287  
  3288  func TestContext2Apply_targetedModuleResource(t *testing.T) {
  3289  	m := testModule(t, "apply-targeted-module-resource")
  3290  	p := testProvider("aws")
  3291  	p.ApplyFn = testApplyFn
  3292  	p.DiffFn = testDiffFn
  3293  	ctx := testContext2(t, &ContextOpts{
  3294  		Module: m,
  3295  		Providers: map[string]ResourceProviderFactory{
  3296  			"aws": testProviderFuncFixed(p),
  3297  		},
  3298  		Targets: []string{"module.child.aws_instance.foo"},
  3299  	})
  3300  
  3301  	if _, err := ctx.Plan(); err != nil {
  3302  		t.Fatalf("err: %s", err)
  3303  	}
  3304  
  3305  	state, err := ctx.Apply()
  3306  	if err != nil {
  3307  		t.Fatalf("err: %s", err)
  3308  	}
  3309  
  3310  	mod := state.ModuleByPath([]string{"root", "child"})
  3311  	if len(mod.Resources) != 1 {
  3312  		t.Fatalf("expected 1 resource, got: %#v", mod.Resources)
  3313  	}
  3314  
  3315  	checkStateString(t, state, `
  3316  <no state>
  3317  module.child:
  3318    aws_instance.foo:
  3319      ID = foo
  3320      num = 2
  3321      type = aws_instance
  3322  	`)
  3323  }
  3324  
  3325  func TestContext2Apply_unknownAttribute(t *testing.T) {
  3326  	m := testModule(t, "apply-unknown")
  3327  	p := testProvider("aws")
  3328  	p.ApplyFn = testApplyFn
  3329  	p.DiffFn = testDiffFn
  3330  	ctx := testContext2(t, &ContextOpts{
  3331  		Module: m,
  3332  		Providers: map[string]ResourceProviderFactory{
  3333  			"aws": testProviderFuncFixed(p),
  3334  		},
  3335  	})
  3336  
  3337  	if _, err := ctx.Plan(); err != nil {
  3338  		t.Fatalf("err: %s", err)
  3339  	}
  3340  
  3341  	state, err := ctx.Apply()
  3342  	if err == nil {
  3343  		t.Fatal("should error")
  3344  	}
  3345  
  3346  	actual := strings.TrimSpace(state.String())
  3347  	expected := strings.TrimSpace(testTerraformApplyUnknownAttrStr)
  3348  	if actual != expected {
  3349  		t.Fatalf("bad: \n%s", actual)
  3350  	}
  3351  }
  3352  
  3353  func TestContext2Apply_unknownAttributeInterpolate(t *testing.T) {
  3354  	m := testModule(t, "apply-unknown-interpolate")
  3355  	p := testProvider("aws")
  3356  	p.ApplyFn = testApplyFn
  3357  	p.DiffFn = testDiffFn
  3358  	ctx := testContext2(t, &ContextOpts{
  3359  		Module: m,
  3360  		Providers: map[string]ResourceProviderFactory{
  3361  			"aws": testProviderFuncFixed(p),
  3362  		},
  3363  	})
  3364  
  3365  	if _, err := ctx.Plan(); err == nil {
  3366  		t.Fatal("should error")
  3367  	}
  3368  }
  3369  
  3370  func TestContext2Apply_vars(t *testing.T) {
  3371  	m := testModule(t, "apply-vars")
  3372  	p := testProvider("aws")
  3373  	p.ApplyFn = testApplyFn
  3374  	p.DiffFn = testDiffFn
  3375  	ctx := testContext2(t, &ContextOpts{
  3376  		Module: m,
  3377  		Providers: map[string]ResourceProviderFactory{
  3378  			"aws": testProviderFuncFixed(p),
  3379  		},
  3380  		Variables: map[string]string{
  3381  			"foo":            "us-west-2",
  3382  			"amis.us-east-1": "override",
  3383  		},
  3384  	})
  3385  
  3386  	w, e := ctx.Validate()
  3387  	if len(w) > 0 {
  3388  		t.Fatalf("bad: %#v", w)
  3389  	}
  3390  	if len(e) > 0 {
  3391  		t.Fatalf("bad: %s", e)
  3392  	}
  3393  
  3394  	if _, err := ctx.Plan(); err != nil {
  3395  		t.Fatalf("err: %s", err)
  3396  	}
  3397  
  3398  	state, err := ctx.Apply()
  3399  	if err != nil {
  3400  		t.Fatalf("err: %s", err)
  3401  	}
  3402  
  3403  	actual := strings.TrimSpace(state.String())
  3404  	expected := strings.TrimSpace(testTerraformApplyVarsStr)
  3405  	if actual != expected {
  3406  		t.Fatalf("bad: \n%s", actual)
  3407  	}
  3408  }
  3409  
  3410  func TestContext2Apply_varsEnv(t *testing.T) {
  3411  	// Set the env var
  3412  	old := tempEnv(t, "TF_VAR_ami", "baz")
  3413  	defer os.Setenv("TF_VAR_ami", old)
  3414  
  3415  	m := testModule(t, "apply-vars-env")
  3416  	p := testProvider("aws")
  3417  	p.ApplyFn = testApplyFn
  3418  	p.DiffFn = testDiffFn
  3419  	ctx := testContext2(t, &ContextOpts{
  3420  		Module: m,
  3421  		Providers: map[string]ResourceProviderFactory{
  3422  			"aws": testProviderFuncFixed(p),
  3423  		},
  3424  	})
  3425  
  3426  	w, e := ctx.Validate()
  3427  	if len(w) > 0 {
  3428  		t.Fatalf("bad: %#v", w)
  3429  	}
  3430  	if len(e) > 0 {
  3431  		t.Fatalf("bad: %s", e)
  3432  	}
  3433  
  3434  	if _, err := ctx.Plan(); err != nil {
  3435  		t.Fatalf("err: %s", err)
  3436  	}
  3437  
  3438  	state, err := ctx.Apply()
  3439  	if err != nil {
  3440  		t.Fatalf("err: %s", err)
  3441  	}
  3442  
  3443  	actual := strings.TrimSpace(state.String())
  3444  	expected := strings.TrimSpace(testTerraformApplyVarsEnvStr)
  3445  	if actual != expected {
  3446  		t.Fatalf("bad: \n%s", actual)
  3447  	}
  3448  }
  3449  
  3450  func TestContext2Apply_createBefore_depends(t *testing.T) {
  3451  	m := testModule(t, "apply-depends-create-before")
  3452  	h := new(HookRecordApplyOrder)
  3453  	p := testProvider("aws")
  3454  	p.ApplyFn = testApplyFn
  3455  	p.DiffFn = testDiffFn
  3456  	state := &State{
  3457  		Modules: []*ModuleState{
  3458  			&ModuleState{
  3459  				Path: rootModulePath,
  3460  				Resources: map[string]*ResourceState{
  3461  					"aws_instance.web": &ResourceState{
  3462  						Type: "aws_instance",
  3463  						Primary: &InstanceState{
  3464  							ID: "bar",
  3465  							Attributes: map[string]string{
  3466  								"require_new": "ami-old",
  3467  							},
  3468  						},
  3469  					},
  3470  					"aws_instance.lb": &ResourceState{
  3471  						Type: "aws_instance",
  3472  						Primary: &InstanceState{
  3473  							ID: "baz",
  3474  							Attributes: map[string]string{
  3475  								"instance": "bar",
  3476  							},
  3477  						},
  3478  					},
  3479  				},
  3480  			},
  3481  		},
  3482  	}
  3483  	ctx := testContext2(t, &ContextOpts{
  3484  		Module: m,
  3485  		Hooks:  []Hook{h},
  3486  		Providers: map[string]ResourceProviderFactory{
  3487  			"aws": testProviderFuncFixed(p),
  3488  		},
  3489  		State: state,
  3490  	})
  3491  
  3492  	if _, err := ctx.Plan(); err != nil {
  3493  		t.Fatalf("err: %s", err)
  3494  	}
  3495  
  3496  	h.Active = true
  3497  	state, err := ctx.Apply()
  3498  	if err != nil {
  3499  		t.Fatalf("err: %s", err)
  3500  	}
  3501  
  3502  	mod := state.RootModule()
  3503  	if len(mod.Resources) < 2 {
  3504  		t.Fatalf("bad: %#v", mod.Resources)
  3505  	}
  3506  
  3507  	actual := strings.TrimSpace(state.String())
  3508  	expected := strings.TrimSpace(testTerraformApplyDependsCreateBeforeStr)
  3509  	if actual != expected {
  3510  		t.Fatalf("bad: \n%s\n%s", actual, expected)
  3511  	}
  3512  
  3513  	// Test that things were managed _in the right order_
  3514  	order := h.States
  3515  	diffs := h.Diffs
  3516  	if order[0].ID != "" || diffs[0].Destroy {
  3517  		t.Fatalf("should create new instance first: %#v", order)
  3518  	}
  3519  
  3520  	if order[1].ID != "baz" {
  3521  		t.Fatalf("update must happen after create: %#v", order)
  3522  	}
  3523  
  3524  	if order[2].ID != "bar" || !diffs[2].Destroy {
  3525  		t.Fatalf("destroy must happen after update: %#v", order)
  3526  	}
  3527  }
  3528  
  3529  func TestContext2Apply_singleDestroy(t *testing.T) {
  3530  	m := testModule(t, "apply-depends-create-before")
  3531  	h := new(HookRecordApplyOrder)
  3532  	p := testProvider("aws")
  3533  
  3534  	invokeCount := 0
  3535  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  3536  		invokeCount++
  3537  		switch invokeCount {
  3538  		case 1:
  3539  			if d.Destroy {
  3540  				t.Fatalf("should not destroy")
  3541  			}
  3542  			if s.ID != "" {
  3543  				t.Fatalf("should not have ID")
  3544  			}
  3545  		case 2:
  3546  			if d.Destroy {
  3547  				t.Fatalf("should not destroy")
  3548  			}
  3549  			if s.ID != "baz" {
  3550  				t.Fatalf("should have id")
  3551  			}
  3552  		case 3:
  3553  			if !d.Destroy {
  3554  				t.Fatalf("should destroy")
  3555  			}
  3556  			if s.ID == "" {
  3557  				t.Fatalf("should have ID")
  3558  			}
  3559  		default:
  3560  			t.Fatalf("bad invoke count %d", invokeCount)
  3561  		}
  3562  		return testApplyFn(info, s, d)
  3563  	}
  3564  	p.DiffFn = testDiffFn
  3565  	state := &State{
  3566  		Modules: []*ModuleState{
  3567  			&ModuleState{
  3568  				Path: rootModulePath,
  3569  				Resources: map[string]*ResourceState{
  3570  					"aws_instance.web": &ResourceState{
  3571  						Type: "aws_instance",
  3572  						Primary: &InstanceState{
  3573  							ID: "bar",
  3574  							Attributes: map[string]string{
  3575  								"require_new": "ami-old",
  3576  							},
  3577  						},
  3578  					},
  3579  					"aws_instance.lb": &ResourceState{
  3580  						Type: "aws_instance",
  3581  						Primary: &InstanceState{
  3582  							ID: "baz",
  3583  							Attributes: map[string]string{
  3584  								"instance": "bar",
  3585  							},
  3586  						},
  3587  					},
  3588  				},
  3589  			},
  3590  		},
  3591  	}
  3592  	ctx := testContext2(t, &ContextOpts{
  3593  		Module: m,
  3594  		Hooks:  []Hook{h},
  3595  		Providers: map[string]ResourceProviderFactory{
  3596  			"aws": testProviderFuncFixed(p),
  3597  		},
  3598  		State: state,
  3599  	})
  3600  
  3601  	if _, err := ctx.Plan(); err != nil {
  3602  		t.Fatalf("err: %s", err)
  3603  	}
  3604  
  3605  	h.Active = true
  3606  	state, err := ctx.Apply()
  3607  	if err != nil {
  3608  		t.Fatalf("err: %s", err)
  3609  	}
  3610  
  3611  	if invokeCount != 3 {
  3612  		t.Fatalf("bad: %d", invokeCount)
  3613  	}
  3614  }