github.com/ricardclau/terraform@v0.6.17-0.20160519222547-283e3ae6b5a9/terraform/context_apply_test.go (about)

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