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