github.com/renier/terraform@v0.7.8-0.20161024133817-eb8a9ef5471a/terraform/context_apply_test.go (about)

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