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