github.com/rebelkathi/terraform-@v0.11.12-beta1/terraform/context_apply_test.go (about)

     1  package terraform
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"fmt"
     7  	"reflect"
     8  	"runtime"
     9  	"sort"
    10  	"strings"
    11  	"sync"
    12  	"sync/atomic"
    13  	"testing"
    14  	"time"
    15  
    16  	"github.com/davecgh/go-spew/spew"
    17  	"github.com/hashicorp/terraform/config/module"
    18  )
    19  
    20  func TestContext2Apply_basic(t *testing.T) {
    21  	m := testModule(t, "apply-good")
    22  	p := testProvider("aws")
    23  	p.ApplyFn = testApplyFn
    24  	p.DiffFn = testDiffFn
    25  	ctx := testContext2(t, &ContextOpts{
    26  		Module: m,
    27  		ProviderResolver: ResourceProviderResolverFixed(
    28  			map[string]ResourceProviderFactory{
    29  				"aws": testProviderFuncFixed(p),
    30  			},
    31  		),
    32  	})
    33  
    34  	if _, err := ctx.Plan(); err != nil {
    35  		t.Fatalf("err: %s", err)
    36  	}
    37  
    38  	state, err := ctx.Apply()
    39  	if err != nil {
    40  		t.Fatalf("err: %s", err)
    41  	}
    42  
    43  	mod := state.RootModule()
    44  	if len(mod.Resources) < 2 {
    45  		t.Fatalf("bad: %#v", mod.Resources)
    46  	}
    47  
    48  	actual := strings.TrimSpace(state.String())
    49  	expected := strings.TrimSpace(testTerraformApplyStr)
    50  	if actual != expected {
    51  		t.Fatalf("bad: \n%s", actual)
    52  	}
    53  }
    54  
    55  func TestContext2Apply_unstable(t *testing.T) {
    56  	// This tests behavior when the configuration contains an unstable value,
    57  	// such as the result of uuid() or timestamp(), where each call produces
    58  	// a different result.
    59  	//
    60  	// This is an important case to test because we need to ensure that
    61  	// we don't re-call the function during the apply phase: the value should
    62  	// be fixed during plan
    63  
    64  	m := testModule(t, "apply-unstable")
    65  	p := testProvider("test")
    66  	p.ApplyFn = testApplyFn
    67  	p.DiffFn = testDiffFn
    68  	ctx := testContext2(t, &ContextOpts{
    69  		Module: m,
    70  		ProviderResolver: ResourceProviderResolverFixed(
    71  			map[string]ResourceProviderFactory{
    72  				"test": testProviderFuncFixed(p),
    73  			},
    74  		),
    75  	})
    76  
    77  	plan, err := ctx.Plan()
    78  	if err != nil {
    79  		t.Fatalf("unexpected error during Plan: %s", err)
    80  	}
    81  
    82  	md := plan.Diff.RootModule()
    83  	rd := md.Resources["test_resource.foo"]
    84  	randomVal := rd.Attributes["random"].New
    85  	t.Logf("plan-time value is %q", randomVal)
    86  
    87  	state, err := ctx.Apply()
    88  	if err != nil {
    89  		t.Fatalf("unexpected error during Apply: %s", err)
    90  	}
    91  
    92  	mod := state.RootModule()
    93  	if len(mod.Resources) != 1 {
    94  		t.Fatalf("wrong number of resources %d; want 1", len(mod.Resources))
    95  	}
    96  
    97  	rs := mod.Resources["test_resource.foo"].Primary
    98  	if got, want := rs.Attributes["random"], randomVal; got != want {
    99  		// FIXME: We actually currently have a bug where we re-interpolate
   100  		// the config during apply and end up with a random result, so this
   101  		// check fails. This check _should not_ fail, so we should fix this
   102  		// up in a later release.
   103  		//t.Errorf("wrong random value %q; want %q", got, want)
   104  	}
   105  }
   106  
   107  func TestContext2Apply_escape(t *testing.T) {
   108  	m := testModule(t, "apply-escape")
   109  	p := testProvider("aws")
   110  	p.ApplyFn = testApplyFn
   111  	p.DiffFn = testDiffFn
   112  	ctx := testContext2(t, &ContextOpts{
   113  		Module: m,
   114  		ProviderResolver: ResourceProviderResolverFixed(
   115  			map[string]ResourceProviderFactory{
   116  				"aws": testProviderFuncFixed(p),
   117  			},
   118  		),
   119  	})
   120  
   121  	if _, err := ctx.Plan(); err != nil {
   122  		t.Fatalf("err: %s", err)
   123  	}
   124  
   125  	state, err := ctx.Apply()
   126  	if err != nil {
   127  		t.Fatalf("err: %s", err)
   128  	}
   129  
   130  	checkStateString(t, state, `
   131  aws_instance.bar:
   132    ID = foo
   133    provider = provider.aws
   134    foo = "bar"
   135    type = aws_instance
   136  `)
   137  }
   138  
   139  func TestContext2Apply_resourceCountOneList(t *testing.T) {
   140  	m := testModule(t, "apply-resource-count-one-list")
   141  	p := testProvider("null")
   142  	p.ApplyFn = testApplyFn
   143  	p.DiffFn = testDiffFn
   144  	ctx := testContext2(t, &ContextOpts{
   145  		Module: m,
   146  		ProviderResolver: ResourceProviderResolverFixed(
   147  			map[string]ResourceProviderFactory{
   148  				"null": testProviderFuncFixed(p),
   149  			},
   150  		),
   151  	})
   152  
   153  	if _, err := ctx.Plan(); err != nil {
   154  		t.Fatalf("err: %s", err)
   155  	}
   156  
   157  	state, err := ctx.Apply()
   158  	if err != nil {
   159  		t.Fatalf("err: %s", err)
   160  	}
   161  
   162  	actual := strings.TrimSpace(state.String())
   163  	expected := strings.TrimSpace(`null_resource.foo:
   164    ID = foo
   165    provider = provider.null
   166  
   167  Outputs:
   168  
   169  test = [foo]`)
   170  	if actual != expected {
   171  		t.Fatalf("expected: \n%s\n\ngot: \n%s\n", expected, actual)
   172  	}
   173  }
   174  func TestContext2Apply_resourceCountZeroList(t *testing.T) {
   175  	m := testModule(t, "apply-resource-count-zero-list")
   176  	p := testProvider("null")
   177  	p.ApplyFn = testApplyFn
   178  	p.DiffFn = testDiffFn
   179  	ctx := testContext2(t, &ContextOpts{
   180  		Module: m,
   181  		ProviderResolver: ResourceProviderResolverFixed(
   182  			map[string]ResourceProviderFactory{
   183  				"null": testProviderFuncFixed(p),
   184  			},
   185  		),
   186  	})
   187  
   188  	if _, err := ctx.Plan(); err != nil {
   189  		t.Fatalf("err: %s", err)
   190  	}
   191  
   192  	state, err := ctx.Apply()
   193  	if err != nil {
   194  		t.Fatalf("err: %s", err)
   195  	}
   196  
   197  	actual := strings.TrimSpace(state.String())
   198  	expected := strings.TrimSpace(`<no state>
   199  Outputs:
   200  
   201  test = []`)
   202  	if actual != expected {
   203  		t.Fatalf("expected: \n%s\n\ngot: \n%s\n", expected, actual)
   204  	}
   205  }
   206  
   207  func TestContext2Apply_resourceDependsOnModule(t *testing.T) {
   208  	m := testModule(t, "apply-resource-depends-on-module")
   209  	p := testProvider("aws")
   210  	p.DiffFn = testDiffFn
   211  
   212  	{
   213  		// Wait for the dependency, sleep, and verify the graph never
   214  		// called a child.
   215  		var called int32
   216  		var checked bool
   217  		p.ApplyFn = func(
   218  			info *InstanceInfo,
   219  			is *InstanceState,
   220  			id *InstanceDiff) (*InstanceState, error) {
   221  			if info.HumanId() == "module.child.aws_instance.child" {
   222  				checked = true
   223  
   224  				// Sleep to allow parallel execution
   225  				time.Sleep(50 * time.Millisecond)
   226  
   227  				// Verify that called is 0 (dep not called)
   228  				if atomic.LoadInt32(&called) != 0 {
   229  					return nil, fmt.Errorf("aws_instance.a should not be called")
   230  				}
   231  			}
   232  
   233  			atomic.AddInt32(&called, 1)
   234  			return testApplyFn(info, is, id)
   235  		}
   236  
   237  		ctx := testContext2(t, &ContextOpts{
   238  			Module: m,
   239  			ProviderResolver: ResourceProviderResolverFixed(
   240  				map[string]ResourceProviderFactory{
   241  					"aws": testProviderFuncFixed(p),
   242  				},
   243  			),
   244  		})
   245  
   246  		if _, err := ctx.Plan(); err != nil {
   247  			t.Fatalf("err: %s", err)
   248  		}
   249  
   250  		state, err := ctx.Apply()
   251  		if err != nil {
   252  			t.Fatalf("err: %s", err)
   253  		}
   254  
   255  		if !checked {
   256  			t.Fatal("should check")
   257  		}
   258  
   259  		checkStateString(t, state, testTerraformApplyResourceDependsOnModuleStr)
   260  	}
   261  }
   262  
   263  // Test that without a config, the Dependencies in the state are enough
   264  // to maintain proper ordering.
   265  func TestContext2Apply_resourceDependsOnModuleStateOnly(t *testing.T) {
   266  	m := testModule(t, "apply-resource-depends-on-module-empty")
   267  	p := testProvider("aws")
   268  	p.DiffFn = testDiffFn
   269  
   270  	state := &State{
   271  		Modules: []*ModuleState{
   272  			&ModuleState{
   273  				Path: rootModulePath,
   274  				Resources: map[string]*ResourceState{
   275  					"aws_instance.a": &ResourceState{
   276  						Type: "aws_instance",
   277  						Primary: &InstanceState{
   278  							ID: "bar",
   279  						},
   280  						Dependencies: []string{"module.child"},
   281  					},
   282  				},
   283  			},
   284  			&ModuleState{
   285  				Path: []string{"root", "child"},
   286  				Resources: map[string]*ResourceState{
   287  					"aws_instance.child": &ResourceState{
   288  						Type: "aws_instance",
   289  						Primary: &InstanceState{
   290  							ID: "bar",
   291  						},
   292  					},
   293  				},
   294  			},
   295  		},
   296  	}
   297  
   298  	{
   299  		// Wait for the dependency, sleep, and verify the graph never
   300  		// called a child.
   301  		var called int32
   302  		var checked bool
   303  		p.ApplyFn = func(
   304  			info *InstanceInfo,
   305  			is *InstanceState,
   306  			id *InstanceDiff) (*InstanceState, error) {
   307  			if info.HumanId() == "aws_instance.a" {
   308  				checked = true
   309  
   310  				// Sleep to allow parallel execution
   311  				time.Sleep(50 * time.Millisecond)
   312  
   313  				// Verify that called is 0 (dep not called)
   314  				if atomic.LoadInt32(&called) != 0 {
   315  					return nil, fmt.Errorf("module child should not be called")
   316  				}
   317  			}
   318  
   319  			atomic.AddInt32(&called, 1)
   320  			return testApplyFn(info, is, id)
   321  		}
   322  
   323  		ctx := testContext2(t, &ContextOpts{
   324  			Module: m,
   325  			ProviderResolver: ResourceProviderResolverFixed(
   326  				map[string]ResourceProviderFactory{
   327  					"aws": testProviderFuncFixed(p),
   328  				},
   329  			),
   330  			State: state,
   331  		})
   332  
   333  		if _, err := ctx.Plan(); err != nil {
   334  			t.Fatalf("err: %s", err)
   335  		}
   336  
   337  		state, err := ctx.Apply()
   338  		if err != nil {
   339  			t.Fatalf("err: %s", err)
   340  		}
   341  
   342  		if !checked {
   343  			t.Fatal("should check")
   344  		}
   345  
   346  		checkStateString(t, state, "<no state>")
   347  	}
   348  }
   349  
   350  func TestContext2Apply_resourceDependsOnModuleDestroy(t *testing.T) {
   351  	m := testModule(t, "apply-resource-depends-on-module")
   352  	p := testProvider("aws")
   353  	p.DiffFn = testDiffFn
   354  
   355  	var globalState *State
   356  	{
   357  		p.ApplyFn = testApplyFn
   358  		ctx := testContext2(t, &ContextOpts{
   359  			Module: m,
   360  			ProviderResolver: ResourceProviderResolverFixed(
   361  				map[string]ResourceProviderFactory{
   362  					"aws": testProviderFuncFixed(p),
   363  				},
   364  			),
   365  		})
   366  
   367  		if _, err := ctx.Plan(); err != nil {
   368  			t.Fatalf("err: %s", err)
   369  		}
   370  
   371  		state, err := ctx.Apply()
   372  		if err != nil {
   373  			t.Fatalf("err: %s", err)
   374  		}
   375  
   376  		globalState = state
   377  	}
   378  
   379  	{
   380  		// Wait for the dependency, sleep, and verify the graph never
   381  		// called a child.
   382  		var called int32
   383  		var checked bool
   384  		p.ApplyFn = func(
   385  			info *InstanceInfo,
   386  			is *InstanceState,
   387  			id *InstanceDiff) (*InstanceState, error) {
   388  			if info.HumanId() == "aws_instance.a" {
   389  				checked = true
   390  
   391  				// Sleep to allow parallel execution
   392  				time.Sleep(50 * time.Millisecond)
   393  
   394  				// Verify that called is 0 (dep not called)
   395  				if atomic.LoadInt32(&called) != 0 {
   396  					return nil, fmt.Errorf("module child should not be called")
   397  				}
   398  			}
   399  
   400  			atomic.AddInt32(&called, 1)
   401  			return testApplyFn(info, is, id)
   402  		}
   403  
   404  		ctx := testContext2(t, &ContextOpts{
   405  			Module: m,
   406  			ProviderResolver: ResourceProviderResolverFixed(
   407  				map[string]ResourceProviderFactory{
   408  					"aws": testProviderFuncFixed(p),
   409  				},
   410  			),
   411  			State:   globalState,
   412  			Destroy: true,
   413  		})
   414  
   415  		if _, err := ctx.Plan(); err != nil {
   416  			t.Fatalf("err: %s", err)
   417  		}
   418  
   419  		state, err := ctx.Apply()
   420  		if err != nil {
   421  			t.Fatalf("err: %s", err)
   422  		}
   423  
   424  		if !checked {
   425  			t.Fatal("should check")
   426  		}
   427  
   428  		checkStateString(t, state, `
   429  <no state>
   430  module.child:
   431    <no state>
   432  		`)
   433  	}
   434  }
   435  
   436  func TestContext2Apply_resourceDependsOnModuleGrandchild(t *testing.T) {
   437  	m := testModule(t, "apply-resource-depends-on-module-deep")
   438  	p := testProvider("aws")
   439  	p.DiffFn = testDiffFn
   440  
   441  	{
   442  		// Wait for the dependency, sleep, and verify the graph never
   443  		// called a child.
   444  		var called int32
   445  		var checked bool
   446  		p.ApplyFn = func(
   447  			info *InstanceInfo,
   448  			is *InstanceState,
   449  			id *InstanceDiff) (*InstanceState, error) {
   450  			if info.HumanId() == "module.child.grandchild.aws_instance.c" {
   451  				checked = true
   452  
   453  				// Sleep to allow parallel execution
   454  				time.Sleep(50 * time.Millisecond)
   455  
   456  				// Verify that called is 0 (dep not called)
   457  				if atomic.LoadInt32(&called) != 0 {
   458  					return nil, fmt.Errorf("aws_instance.a should not be called")
   459  				}
   460  			}
   461  
   462  			atomic.AddInt32(&called, 1)
   463  			return testApplyFn(info, is, id)
   464  		}
   465  
   466  		ctx := testContext2(t, &ContextOpts{
   467  			Module: m,
   468  			ProviderResolver: ResourceProviderResolverFixed(
   469  				map[string]ResourceProviderFactory{
   470  					"aws": testProviderFuncFixed(p),
   471  				},
   472  			),
   473  		})
   474  
   475  		if _, err := ctx.Plan(); err != nil {
   476  			t.Fatalf("err: %s", err)
   477  		}
   478  
   479  		state, err := ctx.Apply()
   480  		if err != nil {
   481  			t.Fatalf("err: %s", err)
   482  		}
   483  
   484  		if !checked {
   485  			t.Fatal("should check")
   486  		}
   487  
   488  		checkStateString(t, state, testTerraformApplyResourceDependsOnModuleDeepStr)
   489  	}
   490  }
   491  
   492  func TestContext2Apply_resourceDependsOnModuleInModule(t *testing.T) {
   493  	m := testModule(t, "apply-resource-depends-on-module-in-module")
   494  	p := testProvider("aws")
   495  	p.DiffFn = testDiffFn
   496  
   497  	{
   498  		// Wait for the dependency, sleep, and verify the graph never
   499  		// called a child.
   500  		var called int32
   501  		var checked bool
   502  		p.ApplyFn = func(
   503  			info *InstanceInfo,
   504  			is *InstanceState,
   505  			id *InstanceDiff) (*InstanceState, error) {
   506  			if info.HumanId() == "module.child.grandchild.aws_instance.c" {
   507  				checked = true
   508  
   509  				// Sleep to allow parallel execution
   510  				time.Sleep(50 * time.Millisecond)
   511  
   512  				// Verify that called is 0 (dep not called)
   513  				if atomic.LoadInt32(&called) != 0 {
   514  					return nil, fmt.Errorf("nothing else should not be called")
   515  				}
   516  			}
   517  
   518  			atomic.AddInt32(&called, 1)
   519  			return testApplyFn(info, is, id)
   520  		}
   521  
   522  		ctx := testContext2(t, &ContextOpts{
   523  			Module: m,
   524  			ProviderResolver: ResourceProviderResolverFixed(
   525  				map[string]ResourceProviderFactory{
   526  					"aws": testProviderFuncFixed(p),
   527  				},
   528  			),
   529  		})
   530  
   531  		if _, err := ctx.Plan(); err != nil {
   532  			t.Fatalf("err: %s", err)
   533  		}
   534  
   535  		state, err := ctx.Apply()
   536  		if err != nil {
   537  			t.Fatalf("err: %s", err)
   538  		}
   539  
   540  		if !checked {
   541  			t.Fatal("should check")
   542  		}
   543  
   544  		checkStateString(t, state, testTerraformApplyResourceDependsOnModuleInModuleStr)
   545  	}
   546  }
   547  
   548  func TestContext2Apply_mapVarBetweenModules(t *testing.T) {
   549  	m := testModule(t, "apply-map-var-through-module")
   550  	p := testProvider("null")
   551  	p.ApplyFn = testApplyFn
   552  	p.DiffFn = testDiffFn
   553  	ctx := testContext2(t, &ContextOpts{
   554  		Module: m,
   555  		ProviderResolver: ResourceProviderResolverFixed(
   556  			map[string]ResourceProviderFactory{
   557  				"null": testProviderFuncFixed(p),
   558  			},
   559  		),
   560  	})
   561  
   562  	if _, err := ctx.Plan(); err != nil {
   563  		t.Fatalf("err: %s", err)
   564  	}
   565  
   566  	state, err := ctx.Apply()
   567  	if err != nil {
   568  		t.Fatalf("err: %s", err)
   569  	}
   570  
   571  	actual := strings.TrimSpace(state.String())
   572  	expected := strings.TrimSpace(`<no state>
   573  Outputs:
   574  
   575  amis_from_module = {eu-west-1:ami-789012 eu-west-2:ami-989484 us-west-1:ami-123456 us-west-2:ami-456789 }
   576  
   577  module.test:
   578    null_resource.noop:
   579      ID = foo
   580      provider = provider.null
   581  
   582    Outputs:
   583  
   584    amis_out = {eu-west-1:ami-789012 eu-west-2:ami-989484 us-west-1:ami-123456 us-west-2:ami-456789 }`)
   585  	if actual != expected {
   586  		t.Fatalf("expected: \n%s\n\ngot: \n%s\n", expected, actual)
   587  	}
   588  }
   589  
   590  func TestContext2Apply_refCount(t *testing.T) {
   591  	m := testModule(t, "apply-ref-count")
   592  	p := testProvider("aws")
   593  	p.ApplyFn = testApplyFn
   594  	p.DiffFn = testDiffFn
   595  	ctx := testContext2(t, &ContextOpts{
   596  		Module: m,
   597  		ProviderResolver: ResourceProviderResolverFixed(
   598  			map[string]ResourceProviderFactory{
   599  				"aws": testProviderFuncFixed(p),
   600  			},
   601  		),
   602  	})
   603  
   604  	if _, err := ctx.Plan(); err != nil {
   605  		t.Fatalf("err: %s", err)
   606  	}
   607  
   608  	state, err := ctx.Apply()
   609  	if err != nil {
   610  		t.Fatalf("err: %s", err)
   611  	}
   612  
   613  	mod := state.RootModule()
   614  	if len(mod.Resources) < 2 {
   615  		t.Fatalf("bad: %#v", mod.Resources)
   616  	}
   617  
   618  	actual := strings.TrimSpace(state.String())
   619  	expected := strings.TrimSpace(testTerraformApplyRefCountStr)
   620  	if actual != expected {
   621  		t.Fatalf("bad: \n%s", actual)
   622  	}
   623  }
   624  
   625  func TestContext2Apply_providerAlias(t *testing.T) {
   626  	m := testModule(t, "apply-provider-alias")
   627  	p := testProvider("aws")
   628  	p.ApplyFn = testApplyFn
   629  	p.DiffFn = testDiffFn
   630  	ctx := testContext2(t, &ContextOpts{
   631  		Module: m,
   632  		ProviderResolver: ResourceProviderResolverFixed(
   633  			map[string]ResourceProviderFactory{
   634  				"aws": testProviderFuncFixed(p),
   635  			},
   636  		),
   637  	})
   638  
   639  	if _, err := ctx.Plan(); err != nil {
   640  		t.Fatalf("err: %s", err)
   641  	}
   642  
   643  	state, err := ctx.Apply()
   644  	if err != nil {
   645  		t.Fatalf("err: %s", err)
   646  	}
   647  
   648  	mod := state.RootModule()
   649  	if len(mod.Resources) < 2 {
   650  		t.Fatalf("bad: %#v", mod.Resources)
   651  	}
   652  
   653  	actual := strings.TrimSpace(state.String())
   654  	expected := strings.TrimSpace(testTerraformApplyProviderAliasStr)
   655  	if actual != expected {
   656  		t.Fatalf("bad: \n%s", actual)
   657  	}
   658  }
   659  
   660  // Two providers that are configured should both be configured prior to apply
   661  func TestContext2Apply_providerAliasConfigure(t *testing.T) {
   662  	m := testModule(t, "apply-provider-alias-configure")
   663  
   664  	p2 := testProvider("another")
   665  	p2.ApplyFn = testApplyFn
   666  	p2.DiffFn = testDiffFn
   667  
   668  	ctx := testContext2(t, &ContextOpts{
   669  		Module: m,
   670  		ProviderResolver: ResourceProviderResolverFixed(
   671  			map[string]ResourceProviderFactory{
   672  				"another": testProviderFuncFixed(p2),
   673  			},
   674  		),
   675  	})
   676  
   677  	if p, err := ctx.Plan(); err != nil {
   678  		t.Fatalf("err: %s", err)
   679  	} else {
   680  		t.Logf(p.String())
   681  	}
   682  
   683  	// Configure to record calls AFTER Plan above
   684  	var configCount int32
   685  	p2.ConfigureFn = func(c *ResourceConfig) error {
   686  		atomic.AddInt32(&configCount, 1)
   687  
   688  		foo, ok := c.Get("foo")
   689  		if !ok {
   690  			return fmt.Errorf("foo is not found")
   691  		}
   692  
   693  		if foo != "bar" {
   694  			return fmt.Errorf("foo: %#v", foo)
   695  		}
   696  
   697  		return nil
   698  	}
   699  
   700  	state, err := ctx.Apply()
   701  	if err != nil {
   702  		t.Fatalf("err: %s", err)
   703  	}
   704  
   705  	if configCount != 2 {
   706  		t.Fatalf("provider config expected 2 calls, got: %d", configCount)
   707  	}
   708  
   709  	actual := strings.TrimSpace(state.String())
   710  	expected := strings.TrimSpace(testTerraformApplyProviderAliasConfigStr)
   711  	if actual != expected {
   712  		t.Fatalf("bad: \n%s", actual)
   713  	}
   714  }
   715  
   716  // GH-2870
   717  func TestContext2Apply_providerWarning(t *testing.T) {
   718  	m := testModule(t, "apply-provider-warning")
   719  	p := testProvider("aws")
   720  	p.ApplyFn = testApplyFn
   721  	p.DiffFn = testDiffFn
   722  	p.ValidateFn = func(c *ResourceConfig) (ws []string, es []error) {
   723  		ws = append(ws, "Just a warning")
   724  		return
   725  	}
   726  	ctx := testContext2(t, &ContextOpts{
   727  		Module: m,
   728  		ProviderResolver: ResourceProviderResolverFixed(
   729  			map[string]ResourceProviderFactory{
   730  				"aws": testProviderFuncFixed(p),
   731  			},
   732  		),
   733  	})
   734  
   735  	if _, err := ctx.Plan(); err != nil {
   736  		t.Fatalf("err: %s", err)
   737  	}
   738  
   739  	state, err := ctx.Apply()
   740  	if err != nil {
   741  		t.Fatalf("err: %s", err)
   742  	}
   743  
   744  	actual := strings.TrimSpace(state.String())
   745  	expected := strings.TrimSpace(`
   746  aws_instance.foo:
   747    ID = foo
   748    provider = provider.aws
   749  	`)
   750  	if actual != expected {
   751  		t.Fatalf("got: \n%s\n\nexpected:\n%s", actual, expected)
   752  	}
   753  
   754  	if !p.ConfigureCalled {
   755  		t.Fatalf("provider Configure() was never called!")
   756  	}
   757  }
   758  
   759  // Higher level test at TestResource_dataSourceListApplyPanic
   760  func TestContext2Apply_computedAttrRefTypeMismatch(t *testing.T) {
   761  	m := testModule(t, "apply-computed-attr-ref-type-mismatch")
   762  	p := testProvider("aws")
   763  	p.DiffFn = testDiffFn
   764  	p.ValidateResourceFn = func(t string, c *ResourceConfig) (ws []string, es []error) {
   765  		// Emulate the type checking behavior of helper/schema based validation
   766  		if t == "aws_instance" {
   767  			ami, _ := c.Get("ami")
   768  			switch a := ami.(type) {
   769  			case string:
   770  				// ok
   771  			default:
   772  				es = append(es, fmt.Errorf("Expected ami to be string, got %T", a))
   773  			}
   774  		}
   775  		return
   776  	}
   777  	p.DiffFn = func(
   778  		info *InstanceInfo,
   779  		state *InstanceState,
   780  		c *ResourceConfig) (*InstanceDiff, error) {
   781  		switch info.Type {
   782  		case "aws_ami_list":
   783  			// Emulate a diff that says "we'll create this list and ids will be populated"
   784  			return &InstanceDiff{
   785  				Attributes: map[string]*ResourceAttrDiff{
   786  					"ids.#": &ResourceAttrDiff{NewComputed: true},
   787  				},
   788  			}, nil
   789  		case "aws_instance":
   790  			// If we get to the diff for instance, we should be able to assume types
   791  			ami, _ := c.Get("ami")
   792  			_ = ami.(string)
   793  		}
   794  		return nil, nil
   795  	}
   796  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
   797  		if info.Type != "aws_ami_list" {
   798  			t.Fatalf("Reached apply for unexpected resource type! %s", info.Type)
   799  		}
   800  		// Pretend like we make a thing and the computed list "ids" is populated
   801  		return &InstanceState{
   802  			ID: "someid",
   803  			Attributes: map[string]string{
   804  				"ids.#": "2",
   805  				"ids.0": "ami-abc123",
   806  				"ids.1": "ami-bcd345",
   807  			},
   808  		}, nil
   809  	}
   810  	ctx := testContext2(t, &ContextOpts{
   811  		Module: m,
   812  		ProviderResolver: ResourceProviderResolverFixed(
   813  			map[string]ResourceProviderFactory{
   814  				"aws": testProviderFuncFixed(p),
   815  			},
   816  		),
   817  	})
   818  
   819  	if _, err := ctx.Plan(); err != nil {
   820  		t.Fatalf("err: %s", err)
   821  	}
   822  
   823  	_, err := ctx.Apply()
   824  	if err == nil {
   825  		t.Fatalf("Expected err, got none!")
   826  	}
   827  
   828  	expected := "Expected ami to be string"
   829  	if !strings.Contains(err.Error(), expected) {
   830  		t.Fatalf("expected:\n\n%s\n\nto contain:\n\n%s", err, expected)
   831  	}
   832  }
   833  
   834  func TestContext2Apply_emptyModule(t *testing.T) {
   835  	m := testModule(t, "apply-empty-module")
   836  	p := testProvider("aws")
   837  	p.ApplyFn = testApplyFn
   838  	p.DiffFn = testDiffFn
   839  	ctx := testContext2(t, &ContextOpts{
   840  		Module: m,
   841  		ProviderResolver: ResourceProviderResolverFixed(
   842  			map[string]ResourceProviderFactory{
   843  				"aws": testProviderFuncFixed(p),
   844  			},
   845  		),
   846  	})
   847  
   848  	if _, err := ctx.Plan(); err != nil {
   849  		t.Fatalf("err: %s", err)
   850  	}
   851  
   852  	state, err := ctx.Apply()
   853  	if err != nil {
   854  		t.Fatalf("err: %s", err)
   855  	}
   856  
   857  	actual := strings.TrimSpace(state.String())
   858  	actual = strings.Replace(actual, "  ", "", -1)
   859  	expected := strings.TrimSpace(testTerraformApplyEmptyModuleStr)
   860  	if actual != expected {
   861  		t.Fatalf("bad: \n%s\nexpect:\n%s", actual, expected)
   862  	}
   863  }
   864  
   865  func TestContext2Apply_createBeforeDestroy(t *testing.T) {
   866  	m := testModule(t, "apply-good-create-before")
   867  	p := testProvider("aws")
   868  	p.ApplyFn = testApplyFn
   869  	p.DiffFn = testDiffFn
   870  	state := &State{
   871  		Modules: []*ModuleState{
   872  			&ModuleState{
   873  				Path: rootModulePath,
   874  				Resources: map[string]*ResourceState{
   875  					"aws_instance.bar": &ResourceState{
   876  						Type: "aws_instance",
   877  						Primary: &InstanceState{
   878  							ID: "bar",
   879  							Attributes: map[string]string{
   880  								"require_new": "abc",
   881  							},
   882  						},
   883  					},
   884  				},
   885  			},
   886  		},
   887  	}
   888  	ctx := testContext2(t, &ContextOpts{
   889  		Module: m,
   890  		ProviderResolver: ResourceProviderResolverFixed(
   891  			map[string]ResourceProviderFactory{
   892  				"aws": testProviderFuncFixed(p),
   893  			},
   894  		),
   895  		State: state,
   896  	})
   897  
   898  	if p, err := ctx.Plan(); err != nil {
   899  		t.Fatalf("err: %s", err)
   900  	} else {
   901  		t.Logf(p.String())
   902  	}
   903  
   904  	state, err := ctx.Apply()
   905  	if err != nil {
   906  		t.Fatalf("err: %s", err)
   907  	}
   908  
   909  	mod := state.RootModule()
   910  	if len(mod.Resources) != 1 {
   911  		t.Fatalf("bad: %s", state)
   912  	}
   913  
   914  	actual := strings.TrimSpace(state.String())
   915  	expected := strings.TrimSpace(testTerraformApplyCreateBeforeStr)
   916  	if actual != expected {
   917  		t.Fatalf("expected:\n%s\ngot:\n%s", expected, actual)
   918  	}
   919  }
   920  
   921  func TestContext2Apply_createBeforeDestroyUpdate(t *testing.T) {
   922  	m := testModule(t, "apply-good-create-before-update")
   923  	p := testProvider("aws")
   924  	p.ApplyFn = testApplyFn
   925  	p.DiffFn = testDiffFn
   926  	state := &State{
   927  		Modules: []*ModuleState{
   928  			&ModuleState{
   929  				Path: rootModulePath,
   930  				Resources: map[string]*ResourceState{
   931  					"aws_instance.bar": &ResourceState{
   932  						Type: "aws_instance",
   933  						Primary: &InstanceState{
   934  							ID: "bar",
   935  							Attributes: map[string]string{
   936  								"foo": "bar",
   937  							},
   938  						},
   939  					},
   940  				},
   941  			},
   942  		},
   943  	}
   944  	ctx := testContext2(t, &ContextOpts{
   945  		Module: m,
   946  		ProviderResolver: ResourceProviderResolverFixed(
   947  			map[string]ResourceProviderFactory{
   948  				"aws": testProviderFuncFixed(p),
   949  			},
   950  		),
   951  		State: state,
   952  	})
   953  
   954  	if p, err := ctx.Plan(); err != nil {
   955  		t.Fatalf("err: %s", err)
   956  	} else {
   957  		t.Logf(p.String())
   958  	}
   959  
   960  	state, err := ctx.Apply()
   961  	if err != nil {
   962  		t.Fatalf("err: %s", err)
   963  	}
   964  
   965  	mod := state.RootModule()
   966  	if len(mod.Resources) != 1 {
   967  		t.Fatalf("bad: %s", state)
   968  	}
   969  
   970  	actual := strings.TrimSpace(state.String())
   971  	expected := strings.TrimSpace(testTerraformApplyCreateBeforeUpdateStr)
   972  	if actual != expected {
   973  		t.Fatalf("bad: \n%s", actual)
   974  	}
   975  }
   976  
   977  // This tests that when a CBD resource depends on a non-CBD resource,
   978  // we can still properly apply changes that require new for both.
   979  func TestContext2Apply_createBeforeDestroy_dependsNonCBD(t *testing.T) {
   980  	m := testModule(t, "apply-cbd-depends-non-cbd")
   981  	p := testProvider("aws")
   982  	p.ApplyFn = testApplyFn
   983  	p.DiffFn = testDiffFn
   984  	state := &State{
   985  		Modules: []*ModuleState{
   986  			&ModuleState{
   987  				Path: rootModulePath,
   988  				Resources: map[string]*ResourceState{
   989  					"aws_instance.bar": &ResourceState{
   990  						Type: "aws_instance",
   991  						Primary: &InstanceState{
   992  							ID: "bar",
   993  							Attributes: map[string]string{
   994  								"require_new": "abc",
   995  							},
   996  						},
   997  					},
   998  
   999  					"aws_instance.foo": &ResourceState{
  1000  						Type: "aws_instance",
  1001  						Primary: &InstanceState{
  1002  							ID: "foo",
  1003  							Attributes: map[string]string{
  1004  								"require_new": "abc",
  1005  							},
  1006  						},
  1007  					},
  1008  				},
  1009  			},
  1010  		},
  1011  	}
  1012  	ctx := testContext2(t, &ContextOpts{
  1013  		Module: m,
  1014  		ProviderResolver: ResourceProviderResolverFixed(
  1015  			map[string]ResourceProviderFactory{
  1016  				"aws": testProviderFuncFixed(p),
  1017  			},
  1018  		),
  1019  		State: state,
  1020  	})
  1021  
  1022  	if p, err := ctx.Plan(); err != nil {
  1023  		t.Fatalf("err: %s", err)
  1024  	} else {
  1025  		t.Logf(p.String())
  1026  	}
  1027  
  1028  	state, err := ctx.Apply()
  1029  	if err != nil {
  1030  		t.Fatalf("err: %s", err)
  1031  	}
  1032  
  1033  	checkStateString(t, state, `
  1034  aws_instance.bar:
  1035    ID = foo
  1036    provider = provider.aws
  1037    require_new = yes
  1038    type = aws_instance
  1039    value = foo
  1040  aws_instance.foo:
  1041    ID = foo
  1042    provider = provider.aws
  1043    require_new = yes
  1044    type = aws_instance
  1045  	`)
  1046  }
  1047  
  1048  func TestContext2Apply_createBeforeDestroy_hook(t *testing.T) {
  1049  	h := new(MockHook)
  1050  	m := testModule(t, "apply-good-create-before")
  1051  	p := testProvider("aws")
  1052  	p.ApplyFn = testApplyFn
  1053  	p.DiffFn = testDiffFn
  1054  	state := &State{
  1055  		Modules: []*ModuleState{
  1056  			&ModuleState{
  1057  				Path: rootModulePath,
  1058  				Resources: map[string]*ResourceState{
  1059  					"aws_instance.bar": &ResourceState{
  1060  						Type: "aws_instance",
  1061  						Primary: &InstanceState{
  1062  							ID: "bar",
  1063  							Attributes: map[string]string{
  1064  								"require_new": "abc",
  1065  							},
  1066  						},
  1067  					},
  1068  				},
  1069  			},
  1070  		},
  1071  	}
  1072  
  1073  	var actual []string
  1074  	var actualLock sync.Mutex
  1075  	h.PostApplyFn = func(n *InstanceInfo, s *InstanceState, e error) (HookAction, error) {
  1076  		actualLock.Lock()
  1077  		defer actualLock.Unlock()
  1078  		actual = append(actual, n.Id)
  1079  		return HookActionContinue, nil
  1080  	}
  1081  
  1082  	ctx := testContext2(t, &ContextOpts{
  1083  		Module: m,
  1084  		Hooks:  []Hook{h},
  1085  		ProviderResolver: ResourceProviderResolverFixed(
  1086  			map[string]ResourceProviderFactory{
  1087  				"aws": testProviderFuncFixed(p),
  1088  			},
  1089  		),
  1090  		State: state,
  1091  	})
  1092  
  1093  	if p, err := ctx.Plan(); err != nil {
  1094  		t.Fatalf("err: %s", err)
  1095  	} else {
  1096  		t.Logf(p.String())
  1097  	}
  1098  
  1099  	if _, err := ctx.Apply(); err != nil {
  1100  		t.Fatalf("err: %s", err)
  1101  	}
  1102  
  1103  	expected := []string{"aws_instance.bar", "aws_instance.bar (deposed #0)"}
  1104  	if !reflect.DeepEqual(actual, expected) {
  1105  		t.Fatalf("bad: %#v", actual)
  1106  	}
  1107  }
  1108  
  1109  // Test that we can perform an apply with CBD in a count with deposed instances.
  1110  func TestContext2Apply_createBeforeDestroy_deposedCount(t *testing.T) {
  1111  	m := testModule(t, "apply-cbd-count")
  1112  	p := testProvider("aws")
  1113  	p.ApplyFn = testApplyFn
  1114  	p.DiffFn = testDiffFn
  1115  
  1116  	state := &State{
  1117  		Modules: []*ModuleState{
  1118  			&ModuleState{
  1119  				Path: rootModulePath,
  1120  				Resources: map[string]*ResourceState{
  1121  					"aws_instance.bar.0": &ResourceState{
  1122  						Type: "aws_instance",
  1123  						Primary: &InstanceState{
  1124  							ID:      "bar",
  1125  							Tainted: true,
  1126  						},
  1127  
  1128  						Deposed: []*InstanceState{
  1129  							&InstanceState{
  1130  								ID: "foo",
  1131  							},
  1132  						},
  1133  					},
  1134  					"aws_instance.bar.1": &ResourceState{
  1135  						Type: "aws_instance",
  1136  						Primary: &InstanceState{
  1137  							ID:      "bar",
  1138  							Tainted: true,
  1139  						},
  1140  
  1141  						Deposed: []*InstanceState{
  1142  							&InstanceState{
  1143  								ID: "bar",
  1144  							},
  1145  						},
  1146  					},
  1147  				},
  1148  			},
  1149  		},
  1150  	}
  1151  
  1152  	ctx := testContext2(t, &ContextOpts{
  1153  		Module: m,
  1154  		ProviderResolver: ResourceProviderResolverFixed(
  1155  			map[string]ResourceProviderFactory{
  1156  				"aws": testProviderFuncFixed(p),
  1157  			},
  1158  		),
  1159  		State: state,
  1160  	})
  1161  
  1162  	if p, err := ctx.Plan(); err != nil {
  1163  		t.Fatalf("err: %s", err)
  1164  	} else {
  1165  		t.Logf(p.String())
  1166  	}
  1167  
  1168  	state, err := ctx.Apply()
  1169  	if err != nil {
  1170  		t.Fatalf("err: %s", err)
  1171  	}
  1172  
  1173  	checkStateString(t, state, `
  1174  aws_instance.bar.0:
  1175    ID = foo
  1176    provider = provider.aws
  1177    foo = bar
  1178    type = aws_instance
  1179  aws_instance.bar.1:
  1180    ID = foo
  1181    provider = provider.aws
  1182    foo = bar
  1183    type = aws_instance
  1184  	`)
  1185  }
  1186  
  1187  // Test that when we have a deposed instance but a good primary, we still
  1188  // destroy the deposed instance.
  1189  func TestContext2Apply_createBeforeDestroy_deposedOnly(t *testing.T) {
  1190  	m := testModule(t, "apply-cbd-deposed-only")
  1191  	p := testProvider("aws")
  1192  	p.ApplyFn = testApplyFn
  1193  	p.DiffFn = testDiffFn
  1194  
  1195  	state := &State{
  1196  		Modules: []*ModuleState{
  1197  			&ModuleState{
  1198  				Path: rootModulePath,
  1199  				Resources: map[string]*ResourceState{
  1200  					"aws_instance.bar": &ResourceState{
  1201  						Type: "aws_instance",
  1202  						Primary: &InstanceState{
  1203  							ID: "bar",
  1204  						},
  1205  
  1206  						Deposed: []*InstanceState{
  1207  							&InstanceState{
  1208  								ID: "foo",
  1209  							},
  1210  						},
  1211  					},
  1212  				},
  1213  			},
  1214  		},
  1215  	}
  1216  
  1217  	ctx := testContext2(t, &ContextOpts{
  1218  		Module: m,
  1219  		ProviderResolver: ResourceProviderResolverFixed(
  1220  			map[string]ResourceProviderFactory{
  1221  				"aws": testProviderFuncFixed(p),
  1222  			},
  1223  		),
  1224  		State: state,
  1225  	})
  1226  
  1227  	if p, err := ctx.Plan(); err != nil {
  1228  		t.Fatalf("err: %s", err)
  1229  	} else {
  1230  		t.Logf(p.String())
  1231  	}
  1232  
  1233  	state, err := ctx.Apply()
  1234  	if err != nil {
  1235  		t.Fatalf("err: %s", err)
  1236  	}
  1237  
  1238  	checkStateString(t, state, `
  1239  aws_instance.bar:
  1240    ID = bar
  1241    provider = provider.aws
  1242  	`)
  1243  }
  1244  
  1245  func TestContext2Apply_destroyComputed(t *testing.T) {
  1246  	m := testModule(t, "apply-destroy-computed")
  1247  	p := testProvider("aws")
  1248  	p.ApplyFn = testApplyFn
  1249  	p.DiffFn = testDiffFn
  1250  	state := &State{
  1251  		Modules: []*ModuleState{
  1252  			&ModuleState{
  1253  				Path: rootModulePath,
  1254  				Resources: map[string]*ResourceState{
  1255  					"aws_instance.foo": &ResourceState{
  1256  						Type: "aws_instance",
  1257  						Primary: &InstanceState{
  1258  							ID: "foo",
  1259  							Attributes: map[string]string{
  1260  								"output": "value",
  1261  							},
  1262  						},
  1263  					},
  1264  				},
  1265  			},
  1266  		},
  1267  	}
  1268  	ctx := testContext2(t, &ContextOpts{
  1269  		Module: m,
  1270  		ProviderResolver: ResourceProviderResolverFixed(
  1271  			map[string]ResourceProviderFactory{
  1272  				"aws": testProviderFuncFixed(p),
  1273  			},
  1274  		),
  1275  		State:   state,
  1276  		Destroy: true,
  1277  	})
  1278  
  1279  	if p, err := ctx.Plan(); err != nil {
  1280  		t.Fatalf("err: %s", err)
  1281  	} else {
  1282  		t.Logf(p.String())
  1283  	}
  1284  
  1285  	if _, err := ctx.Apply(); err != nil {
  1286  		t.Fatalf("err: %s", err)
  1287  	}
  1288  }
  1289  
  1290  // Test that the destroy operation uses depends_on as a source of ordering.
  1291  func TestContext2Apply_destroyDependsOn(t *testing.T) {
  1292  	// It is possible for this to be racy, so we loop a number of times
  1293  	// just to check.
  1294  	for i := 0; i < 10; i++ {
  1295  		testContext2Apply_destroyDependsOn(t)
  1296  	}
  1297  }
  1298  
  1299  func testContext2Apply_destroyDependsOn(t *testing.T) {
  1300  	m := testModule(t, "apply-destroy-depends-on")
  1301  	p := testProvider("aws")
  1302  	p.ApplyFn = testApplyFn
  1303  	p.DiffFn = testDiffFn
  1304  	state := &State{
  1305  		Modules: []*ModuleState{
  1306  			&ModuleState{
  1307  				Path: rootModulePath,
  1308  				Resources: map[string]*ResourceState{
  1309  					"aws_instance.foo": &ResourceState{
  1310  						Type: "aws_instance",
  1311  						Primary: &InstanceState{
  1312  							ID:         "foo",
  1313  							Attributes: map[string]string{},
  1314  						},
  1315  					},
  1316  
  1317  					"aws_instance.bar": &ResourceState{
  1318  						Type: "aws_instance",
  1319  						Primary: &InstanceState{
  1320  							ID:         "bar",
  1321  							Attributes: map[string]string{},
  1322  						},
  1323  					},
  1324  				},
  1325  			},
  1326  		},
  1327  	}
  1328  
  1329  	// Record the order we see Apply
  1330  	var actual []string
  1331  	var actualLock sync.Mutex
  1332  	p.ApplyFn = func(
  1333  		info *InstanceInfo, _ *InstanceState, _ *InstanceDiff) (*InstanceState, error) {
  1334  		actualLock.Lock()
  1335  		defer actualLock.Unlock()
  1336  		actual = append(actual, info.Id)
  1337  		return nil, nil
  1338  	}
  1339  
  1340  	ctx := testContext2(t, &ContextOpts{
  1341  		Module: m,
  1342  		ProviderResolver: ResourceProviderResolverFixed(
  1343  			map[string]ResourceProviderFactory{
  1344  				"aws": testProviderFuncFixed(p),
  1345  			},
  1346  		),
  1347  		State:       state,
  1348  		Destroy:     true,
  1349  		Parallelism: 1, // To check ordering
  1350  	})
  1351  
  1352  	if _, err := ctx.Plan(); err != nil {
  1353  		t.Fatalf("err: %s", err)
  1354  	}
  1355  
  1356  	if _, err := ctx.Apply(); err != nil {
  1357  		t.Fatalf("err: %s", err)
  1358  	}
  1359  
  1360  	expected := []string{"aws_instance.foo", "aws_instance.bar"}
  1361  	if !reflect.DeepEqual(actual, expected) {
  1362  		t.Fatalf("bad: %#v", actual)
  1363  	}
  1364  }
  1365  
  1366  // Test that destroy ordering is correct with dependencies only
  1367  // in the state.
  1368  func TestContext2Apply_destroyDependsOnStateOnly(t *testing.T) {
  1369  	// It is possible for this to be racy, so we loop a number of times
  1370  	// just to check.
  1371  	for i := 0; i < 10; i++ {
  1372  		testContext2Apply_destroyDependsOnStateOnly(t)
  1373  	}
  1374  }
  1375  
  1376  func testContext2Apply_destroyDependsOnStateOnly(t *testing.T) {
  1377  	m := testModule(t, "empty")
  1378  	p := testProvider("aws")
  1379  	p.ApplyFn = testApplyFn
  1380  	p.DiffFn = testDiffFn
  1381  	state := &State{
  1382  		Modules: []*ModuleState{
  1383  			&ModuleState{
  1384  				Path: rootModulePath,
  1385  				Resources: map[string]*ResourceState{
  1386  					"aws_instance.foo": &ResourceState{
  1387  						Type: "aws_instance",
  1388  						Primary: &InstanceState{
  1389  							ID:         "foo",
  1390  							Attributes: map[string]string{},
  1391  						},
  1392  					},
  1393  
  1394  					"aws_instance.bar": &ResourceState{
  1395  						Type: "aws_instance",
  1396  						Primary: &InstanceState{
  1397  							ID:         "bar",
  1398  							Attributes: map[string]string{},
  1399  						},
  1400  						Dependencies: []string{"aws_instance.foo"},
  1401  					},
  1402  				},
  1403  			},
  1404  		},
  1405  	}
  1406  
  1407  	// Record the order we see Apply
  1408  	var actual []string
  1409  	var actualLock sync.Mutex
  1410  	p.ApplyFn = func(
  1411  		info *InstanceInfo, _ *InstanceState, _ *InstanceDiff) (*InstanceState, error) {
  1412  		actualLock.Lock()
  1413  		defer actualLock.Unlock()
  1414  		actual = append(actual, info.Id)
  1415  		return nil, nil
  1416  	}
  1417  
  1418  	ctx := testContext2(t, &ContextOpts{
  1419  		Module: m,
  1420  		ProviderResolver: ResourceProviderResolverFixed(
  1421  			map[string]ResourceProviderFactory{
  1422  				"aws": testProviderFuncFixed(p),
  1423  			},
  1424  		),
  1425  		State:       state,
  1426  		Destroy:     true,
  1427  		Parallelism: 1, // To check ordering
  1428  	})
  1429  
  1430  	if _, err := ctx.Plan(); err != nil {
  1431  		t.Fatalf("err: %s", err)
  1432  	}
  1433  
  1434  	if _, err := ctx.Apply(); err != nil {
  1435  		t.Fatalf("err: %s", err)
  1436  	}
  1437  
  1438  	expected := []string{"aws_instance.bar", "aws_instance.foo"}
  1439  	if !reflect.DeepEqual(actual, expected) {
  1440  		t.Fatalf("bad: %#v", actual)
  1441  	}
  1442  }
  1443  
  1444  // Test that destroy ordering is correct with dependencies only
  1445  // in the state within a module (GH-11749)
  1446  func TestContext2Apply_destroyDependsOnStateOnlyModule(t *testing.T) {
  1447  	// It is possible for this to be racy, so we loop a number of times
  1448  	// just to check.
  1449  	for i := 0; i < 10; i++ {
  1450  		testContext2Apply_destroyDependsOnStateOnlyModule(t)
  1451  	}
  1452  }
  1453  
  1454  func testContext2Apply_destroyDependsOnStateOnlyModule(t *testing.T) {
  1455  	m := testModule(t, "empty")
  1456  	p := testProvider("aws")
  1457  	p.ApplyFn = testApplyFn
  1458  	p.DiffFn = testDiffFn
  1459  	state := &State{
  1460  		Modules: []*ModuleState{
  1461  			&ModuleState{
  1462  				Path: []string{"root", "child"},
  1463  				Resources: map[string]*ResourceState{
  1464  					"aws_instance.foo": &ResourceState{
  1465  						Type: "aws_instance",
  1466  						Primary: &InstanceState{
  1467  							ID:         "foo",
  1468  							Attributes: map[string]string{},
  1469  						},
  1470  					},
  1471  
  1472  					"aws_instance.bar": &ResourceState{
  1473  						Type: "aws_instance",
  1474  						Primary: &InstanceState{
  1475  							ID:         "bar",
  1476  							Attributes: map[string]string{},
  1477  						},
  1478  						Dependencies: []string{"aws_instance.foo"},
  1479  					},
  1480  				},
  1481  			},
  1482  		},
  1483  	}
  1484  
  1485  	// Record the order we see Apply
  1486  	var actual []string
  1487  	var actualLock sync.Mutex
  1488  	p.ApplyFn = func(
  1489  		info *InstanceInfo, _ *InstanceState, _ *InstanceDiff) (*InstanceState, error) {
  1490  		actualLock.Lock()
  1491  		defer actualLock.Unlock()
  1492  		actual = append(actual, info.Id)
  1493  		return nil, nil
  1494  	}
  1495  
  1496  	ctx := testContext2(t, &ContextOpts{
  1497  		Module: m,
  1498  		ProviderResolver: ResourceProviderResolverFixed(
  1499  			map[string]ResourceProviderFactory{
  1500  				"aws": testProviderFuncFixed(p),
  1501  			},
  1502  		),
  1503  		State:       state,
  1504  		Destroy:     true,
  1505  		Parallelism: 1, // To check ordering
  1506  	})
  1507  
  1508  	if _, err := ctx.Plan(); err != nil {
  1509  		t.Fatalf("err: %s", err)
  1510  	}
  1511  
  1512  	if _, err := ctx.Apply(); err != nil {
  1513  		t.Fatalf("err: %s", err)
  1514  	}
  1515  
  1516  	expected := []string{"aws_instance.bar", "aws_instance.foo"}
  1517  	if !reflect.DeepEqual(actual, expected) {
  1518  		t.Fatalf("bad: %#v", actual)
  1519  	}
  1520  }
  1521  
  1522  func TestContext2Apply_dataBasic(t *testing.T) {
  1523  	m := testModule(t, "apply-data-basic")
  1524  	p := testProvider("null")
  1525  	p.ApplyFn = testApplyFn
  1526  	p.DiffFn = testDiffFn
  1527  	p.ReadDataApplyReturn = &InstanceState{ID: "yo"}
  1528  
  1529  	ctx := testContext2(t, &ContextOpts{
  1530  		Module: m,
  1531  		ProviderResolver: ResourceProviderResolverFixed(
  1532  			map[string]ResourceProviderFactory{
  1533  				"null": testProviderFuncFixed(p),
  1534  			},
  1535  		),
  1536  	})
  1537  
  1538  	if p, err := ctx.Plan(); err != nil {
  1539  		t.Fatalf("err: %s", err)
  1540  	} else {
  1541  		t.Logf(p.String())
  1542  	}
  1543  
  1544  	state, err := ctx.Apply()
  1545  	if err != nil {
  1546  		t.Fatalf("err: %s", err)
  1547  	}
  1548  
  1549  	actual := strings.TrimSpace(state.String())
  1550  	expected := strings.TrimSpace(testTerraformApplyDataBasicStr)
  1551  	if actual != expected {
  1552  		t.Fatalf("bad: \n%s", actual)
  1553  	}
  1554  }
  1555  
  1556  func TestContext2Apply_destroyData(t *testing.T) {
  1557  	m := testModule(t, "apply-destroy-data-resource")
  1558  	p := testProvider("null")
  1559  	p.ApplyFn = testApplyFn
  1560  	p.DiffFn = testDiffFn
  1561  	state := &State{
  1562  		Modules: []*ModuleState{
  1563  			&ModuleState{
  1564  				Path: rootModulePath,
  1565  				Resources: map[string]*ResourceState{
  1566  					"data.null_data_source.testing": &ResourceState{
  1567  						Type: "null_data_source",
  1568  						Primary: &InstanceState{
  1569  							ID: "-",
  1570  							Attributes: map[string]string{
  1571  								"inputs.#":    "1",
  1572  								"inputs.test": "yes",
  1573  							},
  1574  						},
  1575  					},
  1576  				},
  1577  			},
  1578  		},
  1579  	}
  1580  	hook := &testHook{}
  1581  	ctx := testContext2(t, &ContextOpts{
  1582  		Module: m,
  1583  		ProviderResolver: ResourceProviderResolverFixed(
  1584  			map[string]ResourceProviderFactory{
  1585  				"null": testProviderFuncFixed(p),
  1586  			},
  1587  		),
  1588  		State:   state,
  1589  		Destroy: true,
  1590  		Hooks:   []Hook{hook},
  1591  	})
  1592  
  1593  	if p, err := ctx.Plan(); err != nil {
  1594  		t.Fatalf("err: %s", err)
  1595  	} else {
  1596  		t.Logf(p.String())
  1597  	}
  1598  
  1599  	newState, err := ctx.Apply()
  1600  	if err != nil {
  1601  		t.Fatalf("err: %s", err)
  1602  	}
  1603  
  1604  	if got := len(newState.Modules); got != 1 {
  1605  		t.Fatalf("state has %d modules after destroy; want 1", got)
  1606  	}
  1607  
  1608  	if got := len(newState.Modules[0].Resources); got != 0 {
  1609  		t.Fatalf("state has %d resources after destroy; want 0", got)
  1610  	}
  1611  
  1612  	wantHookCalls := []*testHookCall{
  1613  		{"PreDiff", "data.null_data_source.testing"},
  1614  		{"PostDiff", "data.null_data_source.testing"},
  1615  		{"PostStateUpdate", ""},
  1616  	}
  1617  	if !reflect.DeepEqual(hook.Calls, wantHookCalls) {
  1618  		t.Errorf("wrong hook calls\ngot: %swant: %s", spew.Sdump(hook.Calls), spew.Sdump(wantHookCalls))
  1619  	}
  1620  }
  1621  
  1622  // https://github.com/hashicorp/terraform/pull/5096
  1623  func TestContext2Apply_destroySkipsCBD(t *testing.T) {
  1624  	// Config contains CBD resource depending on non-CBD resource, which triggers
  1625  	// a cycle if they are both replaced, but should _not_ trigger a cycle when
  1626  	// just doing a `terraform destroy`.
  1627  	m := testModule(t, "apply-destroy-cbd")
  1628  	p := testProvider("aws")
  1629  	p.ApplyFn = testApplyFn
  1630  	p.DiffFn = testDiffFn
  1631  	state := &State{
  1632  		Modules: []*ModuleState{
  1633  			&ModuleState{
  1634  				Path: rootModulePath,
  1635  				Resources: map[string]*ResourceState{
  1636  					"aws_instance.foo": &ResourceState{
  1637  						Type: "aws_instance",
  1638  						Primary: &InstanceState{
  1639  							ID: "foo",
  1640  						},
  1641  					},
  1642  					"aws_instance.bar": &ResourceState{
  1643  						Type: "aws_instance",
  1644  						Primary: &InstanceState{
  1645  							ID: "foo",
  1646  						},
  1647  					},
  1648  				},
  1649  			},
  1650  		},
  1651  	}
  1652  	ctx := testContext2(t, &ContextOpts{
  1653  		Module: m,
  1654  		ProviderResolver: ResourceProviderResolverFixed(
  1655  			map[string]ResourceProviderFactory{
  1656  				"aws": testProviderFuncFixed(p),
  1657  			},
  1658  		),
  1659  		State:   state,
  1660  		Destroy: true,
  1661  	})
  1662  
  1663  	if p, err := ctx.Plan(); err != nil {
  1664  		t.Fatalf("err: %s", err)
  1665  	} else {
  1666  		t.Logf(p.String())
  1667  	}
  1668  
  1669  	if _, err := ctx.Apply(); err != nil {
  1670  		t.Fatalf("err: %s", err)
  1671  	}
  1672  }
  1673  
  1674  func TestContext2Apply_destroyModuleVarProviderConfig(t *testing.T) {
  1675  	m := testModule(t, "apply-destroy-mod-var-provider-config")
  1676  	p := testProvider("aws")
  1677  	p.ApplyFn = testApplyFn
  1678  	p.DiffFn = testDiffFn
  1679  	state := &State{
  1680  		Modules: []*ModuleState{
  1681  			&ModuleState{
  1682  				Path: []string{"root", "child"},
  1683  				Resources: map[string]*ResourceState{
  1684  					"aws_instance.foo": &ResourceState{
  1685  						Type: "aws_instance",
  1686  						Primary: &InstanceState{
  1687  							ID: "foo",
  1688  						},
  1689  					},
  1690  				},
  1691  			},
  1692  		},
  1693  	}
  1694  	ctx := testContext2(t, &ContextOpts{
  1695  		Module: m,
  1696  		ProviderResolver: ResourceProviderResolverFixed(
  1697  			map[string]ResourceProviderFactory{
  1698  				"aws": testProviderFuncFixed(p),
  1699  			},
  1700  		),
  1701  		State:   state,
  1702  		Destroy: true,
  1703  	})
  1704  
  1705  	if _, err := ctx.Plan(); err != nil {
  1706  		t.Fatalf("err: %s", err)
  1707  	}
  1708  
  1709  	_, err := ctx.Apply()
  1710  	if err != nil {
  1711  		t.Fatalf("err: %s", err)
  1712  	}
  1713  }
  1714  
  1715  // https://github.com/hashicorp/terraform/issues/2892
  1716  func TestContext2Apply_destroyCrossProviders(t *testing.T) {
  1717  	m := testModule(t, "apply-destroy-cross-providers")
  1718  
  1719  	p_aws := testProvider("aws")
  1720  	p_aws.ApplyFn = testApplyFn
  1721  	p_aws.DiffFn = testDiffFn
  1722  
  1723  	p_tf := testProvider("terraform")
  1724  	p_tf.ApplyFn = testApplyFn
  1725  	p_tf.DiffFn = testDiffFn
  1726  
  1727  	providers := map[string]ResourceProviderFactory{
  1728  		"aws":       testProviderFuncFixed(p_aws),
  1729  		"terraform": testProviderFuncFixed(p_tf),
  1730  	}
  1731  
  1732  	// Bug only appears from time to time,
  1733  	// so we run this test multiple times
  1734  	// to check for the race-condition
  1735  	for i := 0; i <= 10; i++ {
  1736  		ctx := getContextForApply_destroyCrossProviders(
  1737  			t, m, providers)
  1738  
  1739  		if p, err := ctx.Plan(); err != nil {
  1740  			t.Fatalf("err: %s", err)
  1741  		} else {
  1742  			t.Logf(p.String())
  1743  		}
  1744  
  1745  		if _, err := ctx.Apply(); err != nil {
  1746  			t.Fatalf("err: %s", err)
  1747  		}
  1748  	}
  1749  }
  1750  
  1751  func getContextForApply_destroyCrossProviders(
  1752  	t *testing.T,
  1753  	m *module.Tree,
  1754  	providers map[string]ResourceProviderFactory) *Context {
  1755  	state := &State{
  1756  		Modules: []*ModuleState{
  1757  			&ModuleState{
  1758  				Path: rootModulePath,
  1759  				Resources: map[string]*ResourceState{
  1760  					"terraform_remote_state.shared": &ResourceState{
  1761  						Type: "terraform_remote_state",
  1762  						Primary: &InstanceState{
  1763  							ID: "remote-2652591293",
  1764  							Attributes: map[string]string{
  1765  								"output.env_name": "test",
  1766  							},
  1767  						},
  1768  					},
  1769  				},
  1770  			},
  1771  			&ModuleState{
  1772  				Path: []string{"root", "child"},
  1773  				Resources: map[string]*ResourceState{
  1774  					"aws_vpc.bar": &ResourceState{
  1775  						Type: "aws_vpc",
  1776  						Primary: &InstanceState{
  1777  							ID: "vpc-aaabbb12",
  1778  							Attributes: map[string]string{
  1779  								"value": "test",
  1780  							},
  1781  						},
  1782  					},
  1783  				},
  1784  			},
  1785  		},
  1786  	}
  1787  	ctx := testContext2(t, &ContextOpts{
  1788  		Module:           m,
  1789  		ProviderResolver: ResourceProviderResolverFixed(providers),
  1790  		State:            state,
  1791  		Destroy:          true,
  1792  	})
  1793  
  1794  	return ctx
  1795  }
  1796  
  1797  func TestContext2Apply_minimal(t *testing.T) {
  1798  	m := testModule(t, "apply-minimal")
  1799  	p := testProvider("aws")
  1800  	p.ApplyFn = testApplyFn
  1801  	p.DiffFn = testDiffFn
  1802  	ctx := testContext2(t, &ContextOpts{
  1803  		Module: m,
  1804  		ProviderResolver: ResourceProviderResolverFixed(
  1805  			map[string]ResourceProviderFactory{
  1806  				"aws": testProviderFuncFixed(p),
  1807  			},
  1808  		),
  1809  	})
  1810  
  1811  	if _, err := ctx.Plan(); err != nil {
  1812  		t.Fatalf("err: %s", err)
  1813  	}
  1814  
  1815  	state, err := ctx.Apply()
  1816  	if err != nil {
  1817  		t.Fatalf("err: %s", err)
  1818  	}
  1819  
  1820  	actual := strings.TrimSpace(state.String())
  1821  	expected := strings.TrimSpace(testTerraformApplyMinimalStr)
  1822  	if actual != expected {
  1823  		t.Fatalf("bad: \n%s", actual)
  1824  	}
  1825  }
  1826  
  1827  func TestContext2Apply_badDiff(t *testing.T) {
  1828  	m := testModule(t, "apply-good")
  1829  	p := testProvider("aws")
  1830  	p.ApplyFn = testApplyFn
  1831  	p.DiffFn = testDiffFn
  1832  	ctx := testContext2(t, &ContextOpts{
  1833  		Module: m,
  1834  		ProviderResolver: ResourceProviderResolverFixed(
  1835  			map[string]ResourceProviderFactory{
  1836  				"aws": testProviderFuncFixed(p),
  1837  			},
  1838  		),
  1839  	})
  1840  
  1841  	if _, err := ctx.Plan(); err != nil {
  1842  		t.Fatalf("err: %s", err)
  1843  	}
  1844  
  1845  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  1846  		return &InstanceDiff{
  1847  			Attributes: map[string]*ResourceAttrDiff{
  1848  				"newp": nil,
  1849  			},
  1850  		}, nil
  1851  	}
  1852  
  1853  	if _, err := ctx.Apply(); err == nil {
  1854  		t.Fatal("should error")
  1855  	}
  1856  }
  1857  
  1858  func TestContext2Apply_cancel(t *testing.T) {
  1859  	stopped := false
  1860  
  1861  	m := testModule(t, "apply-cancel")
  1862  	p := testProvider("aws")
  1863  	ctx := testContext2(t, &ContextOpts{
  1864  		Module: m,
  1865  		ProviderResolver: ResourceProviderResolverFixed(
  1866  			map[string]ResourceProviderFactory{
  1867  				"aws": testProviderFuncFixed(p),
  1868  			},
  1869  		),
  1870  	})
  1871  
  1872  	p.ApplyFn = func(*InstanceInfo, *InstanceState, *InstanceDiff) (*InstanceState, error) {
  1873  		if !stopped {
  1874  			stopped = true
  1875  			go ctx.Stop()
  1876  
  1877  			for {
  1878  				if ctx.sh.Stopped() {
  1879  					break
  1880  				}
  1881  				time.Sleep(10 * time.Millisecond)
  1882  			}
  1883  		}
  1884  
  1885  		return &InstanceState{
  1886  			ID: "foo",
  1887  			Attributes: map[string]string{
  1888  				"num": "2",
  1889  			},
  1890  		}, nil
  1891  	}
  1892  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  1893  		return &InstanceDiff{
  1894  			Attributes: map[string]*ResourceAttrDiff{
  1895  				"num": &ResourceAttrDiff{
  1896  					New: "bar",
  1897  				},
  1898  			},
  1899  		}, nil
  1900  	}
  1901  
  1902  	if _, err := ctx.Plan(); err != nil {
  1903  		t.Fatalf("err: %s", err)
  1904  	}
  1905  
  1906  	// Start the Apply in a goroutine
  1907  	var applyErr error
  1908  	stateCh := make(chan *State)
  1909  	go func() {
  1910  		state, err := ctx.Apply()
  1911  		if err != nil {
  1912  			applyErr = err
  1913  		}
  1914  
  1915  		stateCh <- state
  1916  	}()
  1917  
  1918  	state := <-stateCh
  1919  	if applyErr != nil {
  1920  		t.Fatalf("err: %s", applyErr)
  1921  	}
  1922  
  1923  	mod := state.RootModule()
  1924  	if len(mod.Resources) != 1 {
  1925  		t.Fatalf("bad: %s", state.String())
  1926  	}
  1927  
  1928  	actual := strings.TrimSpace(state.String())
  1929  	expected := strings.TrimSpace(testTerraformApplyCancelStr)
  1930  	if actual != expected {
  1931  		t.Fatalf("bad: \n%s", actual)
  1932  	}
  1933  
  1934  	if !p.StopCalled {
  1935  		t.Fatal("stop should be called")
  1936  	}
  1937  }
  1938  
  1939  func TestContext2Apply_cancelBlock(t *testing.T) {
  1940  	m := testModule(t, "apply-cancel-block")
  1941  	p := testProvider("aws")
  1942  	ctx := testContext2(t, &ContextOpts{
  1943  		Module: m,
  1944  		ProviderResolver: ResourceProviderResolverFixed(
  1945  			map[string]ResourceProviderFactory{
  1946  				"aws": testProviderFuncFixed(p),
  1947  			},
  1948  		),
  1949  	})
  1950  
  1951  	applyCh := make(chan struct{})
  1952  	p.DiffFn = testDiffFn
  1953  	p.ApplyFn = func(*InstanceInfo, *InstanceState, *InstanceDiff) (*InstanceState, error) {
  1954  		close(applyCh)
  1955  
  1956  		for !ctx.sh.Stopped() {
  1957  			// Wait for stop to be called. We call Gosched here so that
  1958  			// the other goroutines can always be scheduled to set Stopped.
  1959  			runtime.Gosched()
  1960  		}
  1961  
  1962  		// Sleep
  1963  		time.Sleep(100 * time.Millisecond)
  1964  
  1965  		return &InstanceState{
  1966  			ID: "foo",
  1967  		}, nil
  1968  	}
  1969  
  1970  	if _, err := ctx.Plan(); err != nil {
  1971  		t.Fatalf("err: %s", err)
  1972  	}
  1973  
  1974  	// Start the Apply in a goroutine
  1975  	var applyErr error
  1976  	stateCh := make(chan *State)
  1977  	go func() {
  1978  		state, err := ctx.Apply()
  1979  		if err != nil {
  1980  			applyErr = err
  1981  		}
  1982  
  1983  		stateCh <- state
  1984  	}()
  1985  
  1986  	stopDone := make(chan struct{})
  1987  	go func() {
  1988  		defer close(stopDone)
  1989  		<-applyCh
  1990  		ctx.Stop()
  1991  	}()
  1992  
  1993  	// Make sure that stop blocks
  1994  	select {
  1995  	case <-stopDone:
  1996  		t.Fatal("stop should block")
  1997  	case <-time.After(10 * time.Millisecond):
  1998  	}
  1999  
  2000  	// Wait for stop
  2001  	select {
  2002  	case <-stopDone:
  2003  	case <-time.After(500 * time.Millisecond):
  2004  		t.Fatal("stop should be done")
  2005  	}
  2006  
  2007  	// Wait for apply to complete
  2008  	state := <-stateCh
  2009  	if applyErr != nil {
  2010  		t.Fatalf("err: %s", applyErr)
  2011  	}
  2012  
  2013  	checkStateString(t, state, `
  2014  aws_instance.foo:
  2015    ID = foo
  2016    provider = provider.aws
  2017  	`)
  2018  }
  2019  
  2020  func TestContext2Apply_cancelProvisioner(t *testing.T) {
  2021  	m := testModule(t, "apply-cancel-provisioner")
  2022  	p := testProvider("aws")
  2023  	p.ApplyFn = testApplyFn
  2024  	p.DiffFn = testDiffFn
  2025  	pr := testProvisioner()
  2026  	ctx := testContext2(t, &ContextOpts{
  2027  		Module: m,
  2028  		ProviderResolver: ResourceProviderResolverFixed(
  2029  			map[string]ResourceProviderFactory{
  2030  				"aws": testProviderFuncFixed(p),
  2031  			},
  2032  		),
  2033  		Provisioners: map[string]ResourceProvisionerFactory{
  2034  			"shell": testProvisionerFuncFixed(pr),
  2035  		},
  2036  	})
  2037  
  2038  	prStopped := make(chan struct{})
  2039  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  2040  		// Start the stop process
  2041  		go ctx.Stop()
  2042  
  2043  		<-prStopped
  2044  		return nil
  2045  	}
  2046  	pr.StopFn = func() error {
  2047  		close(prStopped)
  2048  		return nil
  2049  	}
  2050  
  2051  	if _, err := ctx.Plan(); err != nil {
  2052  		t.Fatalf("err: %s", err)
  2053  	}
  2054  
  2055  	// Start the Apply in a goroutine
  2056  	var applyErr error
  2057  	stateCh := make(chan *State)
  2058  	go func() {
  2059  		state, err := ctx.Apply()
  2060  		if err != nil {
  2061  			applyErr = err
  2062  		}
  2063  
  2064  		stateCh <- state
  2065  	}()
  2066  
  2067  	// Wait for completion
  2068  	state := <-stateCh
  2069  	if applyErr != nil {
  2070  		t.Fatalf("err: %s", applyErr)
  2071  	}
  2072  
  2073  	checkStateString(t, state, `
  2074  aws_instance.foo: (tainted)
  2075    ID = foo
  2076    provider = provider.aws
  2077    num = 2
  2078    type = aws_instance
  2079  	`)
  2080  
  2081  	if !pr.StopCalled {
  2082  		t.Fatal("stop should be called")
  2083  	}
  2084  }
  2085  
  2086  func TestContext2Apply_compute(t *testing.T) {
  2087  	m := testModule(t, "apply-compute")
  2088  	p := testProvider("aws")
  2089  	p.ApplyFn = testApplyFn
  2090  	p.DiffFn = testDiffFn
  2091  	ctx := testContext2(t, &ContextOpts{
  2092  		Module: m,
  2093  		ProviderResolver: ResourceProviderResolverFixed(
  2094  			map[string]ResourceProviderFactory{
  2095  				"aws": testProviderFuncFixed(p),
  2096  			},
  2097  		),
  2098  	})
  2099  
  2100  	if _, err := ctx.Plan(); err != nil {
  2101  		t.Fatalf("err: %s", err)
  2102  	}
  2103  
  2104  	ctx.variables = map[string]interface{}{"value": "1"}
  2105  
  2106  	state, err := ctx.Apply()
  2107  	if err != nil {
  2108  		t.Fatalf("err: %s", err)
  2109  	}
  2110  
  2111  	actual := strings.TrimSpace(state.String())
  2112  	expected := strings.TrimSpace(testTerraformApplyComputeStr)
  2113  	if actual != expected {
  2114  		t.Fatalf("bad: \n%s", actual)
  2115  	}
  2116  }
  2117  
  2118  func TestContext2Apply_countDecrease(t *testing.T) {
  2119  	m := testModule(t, "apply-count-dec")
  2120  	p := testProvider("aws")
  2121  	p.DiffFn = testDiffFn
  2122  	s := &State{
  2123  		Modules: []*ModuleState{
  2124  			&ModuleState{
  2125  				Path: rootModulePath,
  2126  				Resources: map[string]*ResourceState{
  2127  					"aws_instance.foo.0": &ResourceState{
  2128  						Type: "aws_instance",
  2129  						Primary: &InstanceState{
  2130  							ID: "bar",
  2131  							Attributes: map[string]string{
  2132  								"foo":  "foo",
  2133  								"type": "aws_instance",
  2134  							},
  2135  						},
  2136  					},
  2137  					"aws_instance.foo.1": &ResourceState{
  2138  						Type: "aws_instance",
  2139  						Primary: &InstanceState{
  2140  							ID: "bar",
  2141  							Attributes: map[string]string{
  2142  								"foo":  "foo",
  2143  								"type": "aws_instance",
  2144  							},
  2145  						},
  2146  					},
  2147  					"aws_instance.foo.2": &ResourceState{
  2148  						Type: "aws_instance",
  2149  						Primary: &InstanceState{
  2150  							ID: "bar",
  2151  							Attributes: map[string]string{
  2152  								"foo":  "foo",
  2153  								"type": "aws_instance",
  2154  							},
  2155  						},
  2156  					},
  2157  				},
  2158  			},
  2159  		},
  2160  	}
  2161  	ctx := testContext2(t, &ContextOpts{
  2162  		Module: m,
  2163  		ProviderResolver: ResourceProviderResolverFixed(
  2164  			map[string]ResourceProviderFactory{
  2165  				"aws": testProviderFuncFixed(p),
  2166  			},
  2167  		),
  2168  		State: s,
  2169  	})
  2170  
  2171  	if _, err := ctx.Plan(); err != nil {
  2172  		t.Fatalf("err: %s", err)
  2173  	}
  2174  
  2175  	state, err := ctx.Apply()
  2176  	if err != nil {
  2177  		t.Fatalf("err: %s", err)
  2178  	}
  2179  
  2180  	actual := strings.TrimSpace(state.String())
  2181  	expected := strings.TrimSpace(testTerraformApplyCountDecStr)
  2182  	if actual != expected {
  2183  		t.Fatalf("bad: \n%s", actual)
  2184  	}
  2185  }
  2186  
  2187  func TestContext2Apply_countDecreaseToOneX(t *testing.T) {
  2188  	m := testModule(t, "apply-count-dec-one")
  2189  	p := testProvider("aws")
  2190  	p.ApplyFn = testApplyFn
  2191  	p.DiffFn = testDiffFn
  2192  	s := &State{
  2193  		Modules: []*ModuleState{
  2194  			&ModuleState{
  2195  				Path: rootModulePath,
  2196  				Resources: map[string]*ResourceState{
  2197  					"aws_instance.foo.0": &ResourceState{
  2198  						Type: "aws_instance",
  2199  						Primary: &InstanceState{
  2200  							ID: "bar",
  2201  							Attributes: map[string]string{
  2202  								"foo":  "foo",
  2203  								"type": "aws_instance",
  2204  							},
  2205  						},
  2206  					},
  2207  					"aws_instance.foo.1": &ResourceState{
  2208  						Type: "aws_instance",
  2209  						Primary: &InstanceState{
  2210  							ID: "bar",
  2211  						},
  2212  					},
  2213  					"aws_instance.foo.2": &ResourceState{
  2214  						Type: "aws_instance",
  2215  						Primary: &InstanceState{
  2216  							ID: "bar",
  2217  						},
  2218  					},
  2219  				},
  2220  			},
  2221  		},
  2222  	}
  2223  	ctx := testContext2(t, &ContextOpts{
  2224  		Module: m,
  2225  		ProviderResolver: ResourceProviderResolverFixed(
  2226  			map[string]ResourceProviderFactory{
  2227  				"aws": testProviderFuncFixed(p),
  2228  			},
  2229  		),
  2230  		State: s,
  2231  	})
  2232  
  2233  	if _, err := ctx.Plan(); err != nil {
  2234  		t.Fatalf("err: %s", err)
  2235  	}
  2236  
  2237  	state, err := ctx.Apply()
  2238  	if err != nil {
  2239  		t.Fatalf("err: %s", err)
  2240  	}
  2241  
  2242  	actual := strings.TrimSpace(state.String())
  2243  	expected := strings.TrimSpace(testTerraformApplyCountDecToOneStr)
  2244  	if actual != expected {
  2245  		t.Fatalf("bad: \n%s", actual)
  2246  	}
  2247  }
  2248  
  2249  // https://github.com/PeoplePerHour/terraform/pull/11
  2250  //
  2251  // This tests a case where both a "resource" and "resource.0" are in
  2252  // the state file, which apparently is a reasonable backwards compatibility
  2253  // concern found in the above 3rd party repo.
  2254  func TestContext2Apply_countDecreaseToOneCorrupted(t *testing.T) {
  2255  	m := testModule(t, "apply-count-dec-one")
  2256  	p := testProvider("aws")
  2257  	p.ApplyFn = testApplyFn
  2258  	p.DiffFn = testDiffFn
  2259  	s := &State{
  2260  		Modules: []*ModuleState{
  2261  			&ModuleState{
  2262  				Path: rootModulePath,
  2263  				Resources: map[string]*ResourceState{
  2264  					"aws_instance.foo": &ResourceState{
  2265  						Type: "aws_instance",
  2266  						Primary: &InstanceState{
  2267  							ID: "bar",
  2268  							Attributes: map[string]string{
  2269  								"foo":  "foo",
  2270  								"type": "aws_instance",
  2271  							},
  2272  						},
  2273  					},
  2274  					"aws_instance.foo.0": &ResourceState{
  2275  						Type: "aws_instance",
  2276  						Primary: &InstanceState{
  2277  							ID: "baz",
  2278  							Attributes: map[string]string{
  2279  								"type": "aws_instance",
  2280  							},
  2281  						},
  2282  					},
  2283  				},
  2284  			},
  2285  		},
  2286  	}
  2287  	ctx := testContext2(t, &ContextOpts{
  2288  		Module: m,
  2289  		ProviderResolver: ResourceProviderResolverFixed(
  2290  			map[string]ResourceProviderFactory{
  2291  				"aws": testProviderFuncFixed(p),
  2292  			},
  2293  		),
  2294  		State: s,
  2295  	})
  2296  
  2297  	if p, err := ctx.Plan(); err != nil {
  2298  		t.Fatalf("err: %s", err)
  2299  	} else {
  2300  		testStringMatch(t, p, testTerraformApplyCountDecToOneCorruptedPlanStr)
  2301  	}
  2302  
  2303  	state, err := ctx.Apply()
  2304  	if err != nil {
  2305  		t.Fatalf("err: %s", err)
  2306  	}
  2307  
  2308  	actual := strings.TrimSpace(state.String())
  2309  	expected := strings.TrimSpace(testTerraformApplyCountDecToOneCorruptedStr)
  2310  	if actual != expected {
  2311  		t.Fatalf("bad: \n%s", actual)
  2312  	}
  2313  }
  2314  
  2315  func TestContext2Apply_countTainted(t *testing.T) {
  2316  	m := testModule(t, "apply-count-tainted")
  2317  	p := testProvider("aws")
  2318  	p.DiffFn = testDiffFn
  2319  	s := &State{
  2320  		Modules: []*ModuleState{
  2321  			&ModuleState{
  2322  				Path: rootModulePath,
  2323  				Resources: map[string]*ResourceState{
  2324  					"aws_instance.foo.0": &ResourceState{
  2325  						Type: "aws_instance",
  2326  						Primary: &InstanceState{
  2327  							ID: "bar",
  2328  							Attributes: map[string]string{
  2329  								"foo":  "foo",
  2330  								"type": "aws_instance",
  2331  							},
  2332  							Tainted: true,
  2333  						},
  2334  					},
  2335  				},
  2336  			},
  2337  		},
  2338  	}
  2339  	ctx := testContext2(t, &ContextOpts{
  2340  		Module: m,
  2341  		ProviderResolver: ResourceProviderResolverFixed(
  2342  			map[string]ResourceProviderFactory{
  2343  				"aws": testProviderFuncFixed(p),
  2344  			},
  2345  		),
  2346  		State: s,
  2347  	})
  2348  
  2349  	if _, err := ctx.Plan(); err != nil {
  2350  		t.Fatalf("err: %s", err)
  2351  	}
  2352  
  2353  	state, err := ctx.Apply()
  2354  	if err != nil {
  2355  		t.Fatalf("err: %s", err)
  2356  	}
  2357  
  2358  	actual := strings.TrimSpace(state.String())
  2359  	expected := strings.TrimSpace(testTerraformApplyCountTaintedStr)
  2360  	if actual != expected {
  2361  		t.Fatalf("bad: \n%s", actual)
  2362  	}
  2363  }
  2364  
  2365  func TestContext2Apply_countVariable(t *testing.T) {
  2366  	m := testModule(t, "apply-count-variable")
  2367  	p := testProvider("aws")
  2368  	p.ApplyFn = testApplyFn
  2369  	p.DiffFn = testDiffFn
  2370  	ctx := testContext2(t, &ContextOpts{
  2371  		Module: m,
  2372  		ProviderResolver: ResourceProviderResolverFixed(
  2373  			map[string]ResourceProviderFactory{
  2374  				"aws": testProviderFuncFixed(p),
  2375  			},
  2376  		),
  2377  	})
  2378  
  2379  	if _, err := ctx.Plan(); err != nil {
  2380  		t.Fatalf("err: %s", err)
  2381  	}
  2382  
  2383  	state, err := ctx.Apply()
  2384  	if err != nil {
  2385  		t.Fatalf("err: %s", err)
  2386  	}
  2387  
  2388  	actual := strings.TrimSpace(state.String())
  2389  	expected := strings.TrimSpace(testTerraformApplyCountVariableStr)
  2390  	if actual != expected {
  2391  		t.Fatalf("bad: \n%s", actual)
  2392  	}
  2393  }
  2394  
  2395  func TestContext2Apply_countVariableRef(t *testing.T) {
  2396  	m := testModule(t, "apply-count-variable-ref")
  2397  	p := testProvider("aws")
  2398  	p.ApplyFn = testApplyFn
  2399  	p.DiffFn = testDiffFn
  2400  	ctx := testContext2(t, &ContextOpts{
  2401  		Module: m,
  2402  		ProviderResolver: ResourceProviderResolverFixed(
  2403  			map[string]ResourceProviderFactory{
  2404  				"aws": testProviderFuncFixed(p),
  2405  			},
  2406  		),
  2407  	})
  2408  
  2409  	if _, err := ctx.Plan(); err != nil {
  2410  		t.Fatalf("err: %s", err)
  2411  	}
  2412  
  2413  	state, err := ctx.Apply()
  2414  	if err != nil {
  2415  		t.Fatalf("err: %s", err)
  2416  	}
  2417  
  2418  	actual := strings.TrimSpace(state.String())
  2419  	expected := strings.TrimSpace(testTerraformApplyCountVariableRefStr)
  2420  	if actual != expected {
  2421  		t.Fatalf("bad: \n%s", actual)
  2422  	}
  2423  }
  2424  
  2425  func TestContext2Apply_provisionerInterpCount(t *testing.T) {
  2426  	// This test ensures that a provisioner can interpolate a resource count
  2427  	// even though the provisioner expression is evaluated during the plan
  2428  	// walk. https://github.com/hashicorp/terraform/issues/16840
  2429  
  2430  	m := testModule(t, "apply-provisioner-interp-count")
  2431  
  2432  	p := testProvider("aws")
  2433  	p.ApplyFn = testApplyFn
  2434  	p.DiffFn = testDiffFn
  2435  
  2436  	pr := testProvisioner()
  2437  
  2438  	providerResolver := ResourceProviderResolverFixed(
  2439  		map[string]ResourceProviderFactory{
  2440  			"aws": testProviderFuncFixed(p),
  2441  		},
  2442  	)
  2443  	provisioners := map[string]ResourceProvisionerFactory{
  2444  		"local-exec": testProvisionerFuncFixed(pr),
  2445  	}
  2446  	ctx := testContext2(t, &ContextOpts{
  2447  		Module:           m,
  2448  		ProviderResolver: providerResolver,
  2449  		Provisioners:     provisioners,
  2450  	})
  2451  
  2452  	plan, err := ctx.Plan()
  2453  	if err != nil {
  2454  		t.Fatalf("plan failed: %s", err)
  2455  	}
  2456  
  2457  	// We'll marshal and unmarshal the plan here, to ensure that we have
  2458  	// a clean new context as would be created if we separately ran
  2459  	// terraform plan -out=tfplan && terraform apply tfplan
  2460  	var planBuf bytes.Buffer
  2461  	err = WritePlan(plan, &planBuf)
  2462  	if err != nil {
  2463  		t.Fatalf("failed to write plan: %s", err)
  2464  	}
  2465  	plan, err = ReadPlan(&planBuf)
  2466  	if err != nil {
  2467  		t.Fatalf("failed to read plan: %s", err)
  2468  	}
  2469  
  2470  	ctx, err = plan.Context(&ContextOpts{
  2471  		// Most options are taken from the plan in this case, but we still
  2472  		// need to provide the plugins.
  2473  		ProviderResolver: providerResolver,
  2474  		Provisioners:     provisioners,
  2475  	})
  2476  	if err != nil {
  2477  		t.Fatalf("failed to create context for plan: %s", err)
  2478  	}
  2479  
  2480  	// Applying the plan should now succeed
  2481  	_, err = ctx.Apply()
  2482  	if err != nil {
  2483  		t.Fatalf("apply failed: %s", err)
  2484  	}
  2485  
  2486  	// Verify apply was invoked
  2487  	if !pr.ApplyCalled {
  2488  		t.Fatalf("provisioner was not applied")
  2489  	}
  2490  }
  2491  
  2492  func TestContext2Apply_mapVariableOverride(t *testing.T) {
  2493  	m := testModule(t, "apply-map-var-override")
  2494  	p := testProvider("aws")
  2495  	p.ApplyFn = testApplyFn
  2496  	p.DiffFn = testDiffFn
  2497  	ctx := testContext2(t, &ContextOpts{
  2498  		Module: m,
  2499  		ProviderResolver: ResourceProviderResolverFixed(
  2500  			map[string]ResourceProviderFactory{
  2501  				"aws": testProviderFuncFixed(p),
  2502  			},
  2503  		),
  2504  		Variables: map[string]interface{}{
  2505  			"images": []map[string]interface{}{
  2506  				map[string]interface{}{
  2507  					"us-west-2": "overridden",
  2508  				},
  2509  			},
  2510  		},
  2511  	})
  2512  
  2513  	if _, err := ctx.Plan(); err != nil {
  2514  		t.Fatalf("err: %s", err)
  2515  	}
  2516  
  2517  	state, err := ctx.Apply()
  2518  	if err != nil {
  2519  		t.Fatalf("err: %s", err)
  2520  	}
  2521  
  2522  	actual := strings.TrimSpace(state.String())
  2523  	expected := strings.TrimSpace(`
  2524  aws_instance.bar:
  2525    ID = foo
  2526    provider = provider.aws
  2527    ami = overridden
  2528    type = aws_instance
  2529  aws_instance.foo:
  2530    ID = foo
  2531    provider = provider.aws
  2532    ami = image-1234
  2533    type = aws_instance
  2534  	`)
  2535  	if actual != expected {
  2536  		t.Fatalf("got: \n%s\nexpected: \n%s", actual, expected)
  2537  	}
  2538  }
  2539  
  2540  func TestContext2Apply_moduleBasic(t *testing.T) {
  2541  	m := testModule(t, "apply-module")
  2542  	p := testProvider("aws")
  2543  	p.ApplyFn = testApplyFn
  2544  	p.DiffFn = testDiffFn
  2545  	ctx := testContext2(t, &ContextOpts{
  2546  		Module: m,
  2547  		ProviderResolver: ResourceProviderResolverFixed(
  2548  			map[string]ResourceProviderFactory{
  2549  				"aws": testProviderFuncFixed(p),
  2550  			},
  2551  		),
  2552  	})
  2553  
  2554  	if _, err := ctx.Plan(); err != nil {
  2555  		t.Fatalf("err: %s", err)
  2556  	}
  2557  
  2558  	state, err := ctx.Apply()
  2559  	if err != nil {
  2560  		t.Fatalf("err: %s", err)
  2561  	}
  2562  
  2563  	actual := strings.TrimSpace(state.String())
  2564  	expected := strings.TrimSpace(testTerraformApplyModuleStr)
  2565  	if actual != expected {
  2566  		t.Fatalf("bad, expected:\n%s\n\nactual:\n%s", expected, actual)
  2567  	}
  2568  }
  2569  
  2570  func TestContext2Apply_moduleDestroyOrder(t *testing.T) {
  2571  	m := testModule(t, "apply-module-destroy-order")
  2572  	p := testProvider("aws")
  2573  	p.DiffFn = testDiffFn
  2574  
  2575  	// Create a custom apply function to track the order they were destroyed
  2576  	var order []string
  2577  	var orderLock sync.Mutex
  2578  	p.ApplyFn = func(
  2579  		info *InstanceInfo,
  2580  		is *InstanceState,
  2581  		id *InstanceDiff) (*InstanceState, error) {
  2582  		orderLock.Lock()
  2583  		defer orderLock.Unlock()
  2584  
  2585  		order = append(order, is.ID)
  2586  		return nil, nil
  2587  	}
  2588  
  2589  	state := &State{
  2590  		Modules: []*ModuleState{
  2591  			&ModuleState{
  2592  				Path: rootModulePath,
  2593  				Resources: map[string]*ResourceState{
  2594  					"aws_instance.b": resourceState("aws_instance", "b"),
  2595  				},
  2596  			},
  2597  
  2598  			&ModuleState{
  2599  				Path: []string{"root", "child"},
  2600  				Resources: map[string]*ResourceState{
  2601  					"aws_instance.a": resourceState("aws_instance", "a"),
  2602  				},
  2603  				Outputs: map[string]*OutputState{
  2604  					"a_output": &OutputState{
  2605  						Type:      "string",
  2606  						Sensitive: false,
  2607  						Value:     "a",
  2608  					},
  2609  				},
  2610  			},
  2611  		},
  2612  	}
  2613  
  2614  	ctx := testContext2(t, &ContextOpts{
  2615  		Module: m,
  2616  		ProviderResolver: ResourceProviderResolverFixed(
  2617  			map[string]ResourceProviderFactory{
  2618  				"aws": testProviderFuncFixed(p),
  2619  			},
  2620  		),
  2621  		State:   state,
  2622  		Destroy: true,
  2623  	})
  2624  
  2625  	if _, err := ctx.Plan(); err != nil {
  2626  		t.Fatalf("err: %s", err)
  2627  	}
  2628  
  2629  	state, err := ctx.Apply()
  2630  	if err != nil {
  2631  		t.Fatalf("err: %s", err)
  2632  	}
  2633  
  2634  	expected := []string{"b", "a"}
  2635  	if !reflect.DeepEqual(order, expected) {
  2636  		t.Fatalf("bad: %#v", order)
  2637  	}
  2638  
  2639  	{
  2640  		actual := strings.TrimSpace(state.String())
  2641  		expected := strings.TrimSpace(testTerraformApplyModuleDestroyOrderStr)
  2642  		if actual != expected {
  2643  			t.Fatalf("bad: \n%s", actual)
  2644  		}
  2645  	}
  2646  }
  2647  
  2648  func TestContext2Apply_moduleInheritAlias(t *testing.T) {
  2649  	m := testModule(t, "apply-module-provider-inherit-alias")
  2650  	p := testProvider("aws")
  2651  	p.ApplyFn = testApplyFn
  2652  	p.DiffFn = testDiffFn
  2653  
  2654  	p.ConfigureFn = func(c *ResourceConfig) error {
  2655  		if _, ok := c.Get("child"); !ok {
  2656  			return nil
  2657  		}
  2658  
  2659  		if _, ok := c.Get("root"); ok {
  2660  			return fmt.Errorf("child should not get root")
  2661  		}
  2662  
  2663  		return nil
  2664  	}
  2665  
  2666  	ctx := testContext2(t, &ContextOpts{
  2667  		Module: m,
  2668  		ProviderResolver: ResourceProviderResolverFixed(
  2669  			map[string]ResourceProviderFactory{
  2670  				"aws": testProviderFuncFixed(p),
  2671  			},
  2672  		),
  2673  	})
  2674  
  2675  	if _, err := ctx.Plan(); err != nil {
  2676  		t.Fatalf("err: %s", err)
  2677  	}
  2678  
  2679  	state, err := ctx.Apply()
  2680  	if err != nil {
  2681  		t.Fatalf("err: %s", err)
  2682  	}
  2683  
  2684  	checkStateString(t, state, `
  2685  <no state>
  2686  module.child:
  2687    aws_instance.foo:
  2688      ID = foo
  2689      provider = provider.aws.eu
  2690  	`)
  2691  }
  2692  
  2693  func TestContext2Apply_moduleOrphanInheritAlias(t *testing.T) {
  2694  	m := testModule(t, "apply-module-provider-inherit-alias-orphan")
  2695  	p := testProvider("aws")
  2696  	p.ApplyFn = testApplyFn
  2697  	p.DiffFn = testDiffFn
  2698  
  2699  	called := false
  2700  	p.ConfigureFn = func(c *ResourceConfig) error {
  2701  		called = true
  2702  
  2703  		if _, ok := c.Get("child"); !ok {
  2704  			return nil
  2705  		}
  2706  
  2707  		if _, ok := c.Get("root"); ok {
  2708  			return fmt.Errorf("child should not get root")
  2709  		}
  2710  
  2711  		return nil
  2712  	}
  2713  
  2714  	// Create a state with an orphan module
  2715  	state := &State{
  2716  		Modules: []*ModuleState{
  2717  			&ModuleState{
  2718  				Path: []string{"root", "child"},
  2719  				Resources: map[string]*ResourceState{
  2720  					"aws_instance.bar": &ResourceState{
  2721  						Type: "aws_instance",
  2722  						Primary: &InstanceState{
  2723  							ID: "bar",
  2724  						},
  2725  						Provider: "aws.eu",
  2726  					},
  2727  				},
  2728  			},
  2729  		},
  2730  	}
  2731  
  2732  	ctx := testContext2(t, &ContextOpts{
  2733  		Module: m,
  2734  		State:  state,
  2735  		ProviderResolver: ResourceProviderResolverFixed(
  2736  			map[string]ResourceProviderFactory{
  2737  				"aws": testProviderFuncFixed(p),
  2738  			},
  2739  		),
  2740  	})
  2741  
  2742  	if _, err := ctx.Plan(); err != nil {
  2743  		t.Fatalf("err: %s", err)
  2744  	}
  2745  
  2746  	state, err := ctx.Apply()
  2747  	if err != nil {
  2748  		t.Fatalf("err: %s", err)
  2749  	}
  2750  
  2751  	if !called {
  2752  		t.Fatal("must call configure")
  2753  	}
  2754  
  2755  	checkStateString(t, state, "")
  2756  }
  2757  
  2758  func TestContext2Apply_moduleOrphanProvider(t *testing.T) {
  2759  	m := testModule(t, "apply-module-orphan-provider-inherit")
  2760  	p := testProvider("aws")
  2761  	p.ApplyFn = testApplyFn
  2762  	p.DiffFn = testDiffFn
  2763  
  2764  	p.ConfigureFn = func(c *ResourceConfig) error {
  2765  		if _, ok := c.Get("value"); !ok {
  2766  			return fmt.Errorf("value is not found")
  2767  		}
  2768  
  2769  		return nil
  2770  	}
  2771  
  2772  	// Create a state with an orphan module
  2773  	state := &State{
  2774  		Modules: []*ModuleState{
  2775  			&ModuleState{
  2776  				Path: []string{"root", "child"},
  2777  				Resources: map[string]*ResourceState{
  2778  					"aws_instance.bar": &ResourceState{
  2779  						Type: "aws_instance",
  2780  						Primary: &InstanceState{
  2781  							ID: "bar",
  2782  						},
  2783  					},
  2784  				},
  2785  			},
  2786  		},
  2787  	}
  2788  
  2789  	ctx := testContext2(t, &ContextOpts{
  2790  		Module: m,
  2791  		State:  state,
  2792  		ProviderResolver: ResourceProviderResolverFixed(
  2793  			map[string]ResourceProviderFactory{
  2794  				"aws": testProviderFuncFixed(p),
  2795  			},
  2796  		),
  2797  	})
  2798  
  2799  	if _, err := ctx.Plan(); err != nil {
  2800  		t.Fatalf("err: %s", err)
  2801  	}
  2802  
  2803  	if _, err := ctx.Apply(); err != nil {
  2804  		t.Fatalf("err: %s", err)
  2805  	}
  2806  }
  2807  
  2808  func TestContext2Apply_moduleOrphanGrandchildProvider(t *testing.T) {
  2809  	m := testModule(t, "apply-module-orphan-provider-inherit")
  2810  	p := testProvider("aws")
  2811  	p.ApplyFn = testApplyFn
  2812  	p.DiffFn = testDiffFn
  2813  
  2814  	p.ConfigureFn = func(c *ResourceConfig) error {
  2815  		if _, ok := c.Get("value"); !ok {
  2816  			return fmt.Errorf("value is not found")
  2817  		}
  2818  
  2819  		return nil
  2820  	}
  2821  
  2822  	// Create a state with an orphan module that is nested (grandchild)
  2823  	state := &State{
  2824  		Modules: []*ModuleState{
  2825  			&ModuleState{
  2826  				Path: []string{"root", "parent", "child"},
  2827  				Resources: map[string]*ResourceState{
  2828  					"aws_instance.bar": &ResourceState{
  2829  						Type: "aws_instance",
  2830  						Primary: &InstanceState{
  2831  							ID: "bar",
  2832  						},
  2833  					},
  2834  				},
  2835  			},
  2836  		},
  2837  	}
  2838  
  2839  	ctx := testContext2(t, &ContextOpts{
  2840  		Module: m,
  2841  		State:  state,
  2842  		ProviderResolver: ResourceProviderResolverFixed(
  2843  			map[string]ResourceProviderFactory{
  2844  				"aws": testProviderFuncFixed(p),
  2845  			},
  2846  		),
  2847  	})
  2848  
  2849  	if _, err := ctx.Plan(); err != nil {
  2850  		t.Fatalf("err: %s", err)
  2851  	}
  2852  
  2853  	if _, err := ctx.Apply(); err != nil {
  2854  		t.Fatalf("err: %s", err)
  2855  	}
  2856  }
  2857  
  2858  func TestContext2Apply_moduleGrandchildProvider(t *testing.T) {
  2859  	m := testModule(t, "apply-module-grandchild-provider-inherit")
  2860  	p := testProvider("aws")
  2861  	p.ApplyFn = testApplyFn
  2862  	p.DiffFn = testDiffFn
  2863  
  2864  	var callLock sync.Mutex
  2865  	called := false
  2866  	p.ConfigureFn = func(c *ResourceConfig) error {
  2867  		if _, ok := c.Get("value"); !ok {
  2868  			return fmt.Errorf("value is not found")
  2869  		}
  2870  		callLock.Lock()
  2871  		called = true
  2872  		callLock.Unlock()
  2873  
  2874  		return nil
  2875  	}
  2876  
  2877  	ctx := testContext2(t, &ContextOpts{
  2878  		Module: m,
  2879  		ProviderResolver: ResourceProviderResolverFixed(
  2880  			map[string]ResourceProviderFactory{
  2881  				"aws": testProviderFuncFixed(p),
  2882  			},
  2883  		),
  2884  	})
  2885  
  2886  	if _, err := ctx.Plan(); err != nil {
  2887  		t.Fatalf("err: %s", err)
  2888  	}
  2889  
  2890  	if _, err := ctx.Apply(); err != nil {
  2891  		t.Fatalf("err: %s", err)
  2892  	}
  2893  
  2894  	callLock.Lock()
  2895  	defer callLock.Unlock()
  2896  	if called != true {
  2897  		t.Fatalf("err: configure never called")
  2898  	}
  2899  }
  2900  
  2901  // This tests an issue where all the providers in a module but not
  2902  // in the root weren't being added to the root properly. In this test
  2903  // case: aws is explicitly added to root, but "test" should be added to.
  2904  // With the bug, it wasn't.
  2905  func TestContext2Apply_moduleOnlyProvider(t *testing.T) {
  2906  	m := testModule(t, "apply-module-only-provider")
  2907  	p := testProvider("aws")
  2908  	p.ApplyFn = testApplyFn
  2909  	p.DiffFn = testDiffFn
  2910  	pTest := testProvider("test")
  2911  	pTest.ApplyFn = testApplyFn
  2912  	pTest.DiffFn = testDiffFn
  2913  
  2914  	ctx := testContext2(t, &ContextOpts{
  2915  		Module: m,
  2916  		ProviderResolver: ResourceProviderResolverFixed(
  2917  			map[string]ResourceProviderFactory{
  2918  				"aws":  testProviderFuncFixed(p),
  2919  				"test": testProviderFuncFixed(pTest),
  2920  			},
  2921  		),
  2922  	})
  2923  
  2924  	if _, err := ctx.Plan(); err != nil {
  2925  		t.Fatalf("err: %s", err)
  2926  	}
  2927  
  2928  	state, err := ctx.Apply()
  2929  	if err != nil {
  2930  		t.Fatalf("err: %s", err)
  2931  	}
  2932  
  2933  	actual := strings.TrimSpace(state.String())
  2934  	expected := strings.TrimSpace(testTerraformApplyModuleOnlyProviderStr)
  2935  	if actual != expected {
  2936  		t.Fatalf("bad: \n%s", actual)
  2937  	}
  2938  }
  2939  
  2940  func TestContext2Apply_moduleProviderAlias(t *testing.T) {
  2941  	m := testModule(t, "apply-module-provider-alias")
  2942  	p := testProvider("aws")
  2943  	p.ApplyFn = testApplyFn
  2944  	p.DiffFn = testDiffFn
  2945  	ctx := testContext2(t, &ContextOpts{
  2946  		Module: m,
  2947  		ProviderResolver: ResourceProviderResolverFixed(
  2948  			map[string]ResourceProviderFactory{
  2949  				"aws": testProviderFuncFixed(p),
  2950  			},
  2951  		),
  2952  	})
  2953  
  2954  	if _, err := ctx.Plan(); err != nil {
  2955  		t.Fatalf("err: %s", err)
  2956  	}
  2957  
  2958  	state, err := ctx.Apply()
  2959  	if err != nil {
  2960  		t.Fatalf("err: %s", err)
  2961  	}
  2962  
  2963  	actual := strings.TrimSpace(state.String())
  2964  	expected := strings.TrimSpace(testTerraformApplyModuleProviderAliasStr)
  2965  	if actual != expected {
  2966  		t.Fatalf("bad: \n%s", actual)
  2967  	}
  2968  }
  2969  
  2970  func TestContext2Apply_moduleProviderAliasTargets(t *testing.T) {
  2971  	m := testModule(t, "apply-module-provider-alias")
  2972  	p := testProvider("aws")
  2973  	p.ApplyFn = testApplyFn
  2974  	p.DiffFn = testDiffFn
  2975  	ctx := testContext2(t, &ContextOpts{
  2976  		Module: m,
  2977  		ProviderResolver: ResourceProviderResolverFixed(
  2978  			map[string]ResourceProviderFactory{
  2979  				"aws": testProviderFuncFixed(p),
  2980  			},
  2981  		),
  2982  		Targets: []string{"no.thing"},
  2983  	})
  2984  
  2985  	if _, err := ctx.Plan(); err != nil {
  2986  		t.Fatalf("err: %s", err)
  2987  	}
  2988  
  2989  	state, err := ctx.Apply()
  2990  	if err != nil {
  2991  		t.Fatalf("err: %s", err)
  2992  	}
  2993  
  2994  	actual := strings.TrimSpace(state.String())
  2995  	expected := strings.TrimSpace(`
  2996  <no state>
  2997  	`)
  2998  	if actual != expected {
  2999  		t.Fatalf("bad: \n%s", actual)
  3000  	}
  3001  }
  3002  
  3003  func TestContext2Apply_moduleProviderCloseNested(t *testing.T) {
  3004  	m := testModule(t, "apply-module-provider-close-nested")
  3005  	p := testProvider("aws")
  3006  	p.ApplyFn = testApplyFn
  3007  	p.DiffFn = testDiffFn
  3008  	ctx := testContext2(t, &ContextOpts{
  3009  		Module: m,
  3010  		ProviderResolver: ResourceProviderResolverFixed(
  3011  			map[string]ResourceProviderFactory{
  3012  				"aws": testProviderFuncFixed(p),
  3013  			},
  3014  		),
  3015  		State: &State{
  3016  			Modules: []*ModuleState{
  3017  				&ModuleState{
  3018  					Path: []string{"root", "child", "subchild"},
  3019  					Resources: map[string]*ResourceState{
  3020  						"aws_instance.foo": &ResourceState{
  3021  							Type: "aws_instance",
  3022  							Primary: &InstanceState{
  3023  								ID: "bar",
  3024  							},
  3025  						},
  3026  					},
  3027  				},
  3028  			},
  3029  		},
  3030  		Destroy: true,
  3031  	})
  3032  
  3033  	if _, err := ctx.Plan(); err != nil {
  3034  		t.Fatalf("err: %s", err)
  3035  	}
  3036  
  3037  	if _, err := ctx.Apply(); err != nil {
  3038  		t.Fatalf("err: %s", err)
  3039  	}
  3040  }
  3041  
  3042  // Tests that variables used as module vars that reference data that
  3043  // already exists in the state and requires no diff works properly. This
  3044  // fixes an issue faced where module variables were pruned because they were
  3045  // accessing "non-existent" resources (they existed, just not in the graph
  3046  // cause they weren't in the diff).
  3047  func TestContext2Apply_moduleVarRefExisting(t *testing.T) {
  3048  	m := testModule(t, "apply-ref-existing")
  3049  	p := testProvider("aws")
  3050  	p.ApplyFn = testApplyFn
  3051  	p.DiffFn = testDiffFn
  3052  
  3053  	state := &State{
  3054  		Modules: []*ModuleState{
  3055  			&ModuleState{
  3056  				Path: rootModulePath,
  3057  				Resources: map[string]*ResourceState{
  3058  					"aws_instance.foo": &ResourceState{
  3059  						Type: "aws_instance",
  3060  						Primary: &InstanceState{
  3061  							ID: "foo",
  3062  							Attributes: map[string]string{
  3063  								"foo": "bar",
  3064  							},
  3065  						},
  3066  					},
  3067  				},
  3068  			},
  3069  		},
  3070  	}
  3071  
  3072  	ctx := testContext2(t, &ContextOpts{
  3073  		Module: m,
  3074  		ProviderResolver: ResourceProviderResolverFixed(
  3075  			map[string]ResourceProviderFactory{
  3076  				"aws": testProviderFuncFixed(p),
  3077  			},
  3078  		),
  3079  		State: state,
  3080  	})
  3081  
  3082  	if _, err := ctx.Plan(); err != nil {
  3083  		t.Fatalf("err: %s", err)
  3084  	}
  3085  
  3086  	state, err := ctx.Apply()
  3087  	if err != nil {
  3088  		t.Fatalf("err: %s", err)
  3089  	}
  3090  
  3091  	actual := strings.TrimSpace(state.String())
  3092  	expected := strings.TrimSpace(testTerraformApplyModuleVarRefExistingStr)
  3093  	if actual != expected {
  3094  		t.Fatalf("bad: \n%s", actual)
  3095  	}
  3096  }
  3097  
  3098  func TestContext2Apply_moduleVarResourceCount(t *testing.T) {
  3099  	m := testModule(t, "apply-module-var-resource-count")
  3100  	p := testProvider("aws")
  3101  	p.ApplyFn = testApplyFn
  3102  	p.DiffFn = testDiffFn
  3103  	ctx := testContext2(t, &ContextOpts{
  3104  		Module: m,
  3105  		ProviderResolver: ResourceProviderResolverFixed(
  3106  			map[string]ResourceProviderFactory{
  3107  				"aws": testProviderFuncFixed(p),
  3108  			},
  3109  		),
  3110  		Variables: map[string]interface{}{
  3111  			"count": "2",
  3112  		},
  3113  		Destroy: true,
  3114  	})
  3115  
  3116  	if _, err := ctx.Plan(); err != nil {
  3117  		t.Fatalf("err: %s", err)
  3118  	}
  3119  
  3120  	if _, err := ctx.Apply(); err != nil {
  3121  		t.Fatalf("err: %s", err)
  3122  	}
  3123  
  3124  	ctx = testContext2(t, &ContextOpts{
  3125  		Module: m,
  3126  		ProviderResolver: ResourceProviderResolverFixed(
  3127  			map[string]ResourceProviderFactory{
  3128  				"aws": testProviderFuncFixed(p),
  3129  			},
  3130  		),
  3131  		Variables: map[string]interface{}{
  3132  			"count": "5",
  3133  		},
  3134  	})
  3135  
  3136  	if _, err := ctx.Plan(); err != nil {
  3137  		t.Fatalf("err: %s", err)
  3138  	}
  3139  
  3140  	if _, err := ctx.Apply(); err != nil {
  3141  		t.Fatalf("err: %s", err)
  3142  	}
  3143  }
  3144  
  3145  // GH-819
  3146  func TestContext2Apply_moduleBool(t *testing.T) {
  3147  	m := testModule(t, "apply-module-bool")
  3148  	p := testProvider("aws")
  3149  	p.ApplyFn = testApplyFn
  3150  	p.DiffFn = testDiffFn
  3151  	ctx := testContext2(t, &ContextOpts{
  3152  		Module: m,
  3153  		ProviderResolver: ResourceProviderResolverFixed(
  3154  			map[string]ResourceProviderFactory{
  3155  				"aws": testProviderFuncFixed(p),
  3156  			},
  3157  		),
  3158  	})
  3159  
  3160  	if _, err := ctx.Plan(); err != nil {
  3161  		t.Fatalf("err: %s", err)
  3162  	}
  3163  
  3164  	state, err := ctx.Apply()
  3165  	if err != nil {
  3166  		t.Fatalf("err: %s", err)
  3167  	}
  3168  
  3169  	actual := strings.TrimSpace(state.String())
  3170  	expected := strings.TrimSpace(testTerraformApplyModuleBoolStr)
  3171  	if actual != expected {
  3172  		t.Fatalf("bad: \n%s", actual)
  3173  	}
  3174  }
  3175  
  3176  // Tests that a module can be targeted and everything is properly created.
  3177  // This adds to the plan test to also just verify that apply works.
  3178  func TestContext2Apply_moduleTarget(t *testing.T) {
  3179  	m := testModule(t, "plan-targeted-cross-module")
  3180  	p := testProvider("aws")
  3181  	p.ApplyFn = testApplyFn
  3182  	p.DiffFn = testDiffFn
  3183  	ctx := testContext2(t, &ContextOpts{
  3184  		Module: m,
  3185  		ProviderResolver: ResourceProviderResolverFixed(
  3186  			map[string]ResourceProviderFactory{
  3187  				"aws": testProviderFuncFixed(p),
  3188  			},
  3189  		),
  3190  		Targets: []string{"module.B"},
  3191  	})
  3192  
  3193  	if _, err := ctx.Plan(); err != nil {
  3194  		t.Fatalf("err: %s", err)
  3195  	}
  3196  
  3197  	state, err := ctx.Apply()
  3198  	if err != nil {
  3199  		t.Fatalf("err: %s", err)
  3200  	}
  3201  
  3202  	checkStateString(t, state, `
  3203  <no state>
  3204  module.A:
  3205    aws_instance.foo:
  3206      ID = foo
  3207      provider = provider.aws
  3208      foo = bar
  3209      type = aws_instance
  3210  
  3211    Outputs:
  3212  
  3213    value = foo
  3214  module.B:
  3215    aws_instance.bar:
  3216      ID = foo
  3217      provider = provider.aws
  3218      foo = foo
  3219      type = aws_instance
  3220  	`)
  3221  }
  3222  
  3223  func TestContext2Apply_multiProvider(t *testing.T) {
  3224  	m := testModule(t, "apply-multi-provider")
  3225  	p := testProvider("aws")
  3226  	p.ApplyFn = testApplyFn
  3227  	p.DiffFn = testDiffFn
  3228  
  3229  	pDO := testProvider("do")
  3230  	pDO.ApplyFn = testApplyFn
  3231  	pDO.DiffFn = testDiffFn
  3232  
  3233  	ctx := testContext2(t, &ContextOpts{
  3234  		Module: m,
  3235  		ProviderResolver: ResourceProviderResolverFixed(
  3236  			map[string]ResourceProviderFactory{
  3237  				"aws": testProviderFuncFixed(p),
  3238  				"do":  testProviderFuncFixed(pDO),
  3239  			},
  3240  		),
  3241  	})
  3242  
  3243  	if _, err := ctx.Plan(); err != nil {
  3244  		t.Fatalf("err: %s", err)
  3245  	}
  3246  
  3247  	state, err := ctx.Apply()
  3248  	if err != nil {
  3249  		t.Fatalf("err: %s", err)
  3250  	}
  3251  
  3252  	mod := state.RootModule()
  3253  	if len(mod.Resources) < 2 {
  3254  		t.Fatalf("bad: %#v", mod.Resources)
  3255  	}
  3256  
  3257  	actual := strings.TrimSpace(state.String())
  3258  	expected := strings.TrimSpace(testTerraformApplyMultiProviderStr)
  3259  	if actual != expected {
  3260  		t.Fatalf("bad: \n%s", actual)
  3261  	}
  3262  }
  3263  
  3264  func TestContext2Apply_multiProviderDestroy(t *testing.T) {
  3265  	m := testModule(t, "apply-multi-provider-destroy")
  3266  	p := testProvider("aws")
  3267  	p.ApplyFn = testApplyFn
  3268  	p.DiffFn = testDiffFn
  3269  
  3270  	p2 := testProvider("do")
  3271  	p2.ApplyFn = testApplyFn
  3272  	p2.DiffFn = testDiffFn
  3273  
  3274  	var state *State
  3275  
  3276  	// First, create the instances
  3277  	{
  3278  		ctx := testContext2(t, &ContextOpts{
  3279  			Module: m,
  3280  			ProviderResolver: ResourceProviderResolverFixed(
  3281  				map[string]ResourceProviderFactory{
  3282  					"aws":   testProviderFuncFixed(p),
  3283  					"vault": testProviderFuncFixed(p2),
  3284  				},
  3285  			),
  3286  		})
  3287  
  3288  		if _, err := ctx.Plan(); err != nil {
  3289  			t.Fatalf("err: %s", err)
  3290  		}
  3291  
  3292  		s, err := ctx.Apply()
  3293  		if err != nil {
  3294  			t.Fatalf("err: %s", err)
  3295  		}
  3296  
  3297  		state = s
  3298  	}
  3299  
  3300  	// Destroy them
  3301  	{
  3302  		// Verify that aws_instance.bar is destroyed first
  3303  		var checked bool
  3304  		var called int32
  3305  		var lock sync.Mutex
  3306  		applyFn := func(
  3307  			info *InstanceInfo,
  3308  			is *InstanceState,
  3309  			id *InstanceDiff) (*InstanceState, error) {
  3310  			lock.Lock()
  3311  			defer lock.Unlock()
  3312  
  3313  			if info.HumanId() == "aws_instance.bar" {
  3314  				checked = true
  3315  
  3316  				// Sleep to allow parallel execution
  3317  				time.Sleep(50 * time.Millisecond)
  3318  
  3319  				// Verify that called is 0 (dep not called)
  3320  				if atomic.LoadInt32(&called) != 0 {
  3321  					return nil, fmt.Errorf("nothing else should be called")
  3322  				}
  3323  			}
  3324  
  3325  			atomic.AddInt32(&called, 1)
  3326  			return testApplyFn(info, is, id)
  3327  		}
  3328  
  3329  		// Set the apply functions
  3330  		p.ApplyFn = applyFn
  3331  		p2.ApplyFn = applyFn
  3332  
  3333  		ctx := testContext2(t, &ContextOpts{
  3334  			Destroy: true,
  3335  			State:   state,
  3336  			Module:  m,
  3337  			ProviderResolver: ResourceProviderResolverFixed(
  3338  				map[string]ResourceProviderFactory{
  3339  					"aws":   testProviderFuncFixed(p),
  3340  					"vault": testProviderFuncFixed(p2),
  3341  				},
  3342  			),
  3343  		})
  3344  
  3345  		if _, err := ctx.Plan(); err != nil {
  3346  			t.Fatalf("err: %s", err)
  3347  		}
  3348  
  3349  		s, err := ctx.Apply()
  3350  		if err != nil {
  3351  			t.Fatalf("err: %s", err)
  3352  		}
  3353  
  3354  		if !checked {
  3355  			t.Fatal("should be checked")
  3356  		}
  3357  
  3358  		state = s
  3359  	}
  3360  
  3361  	checkStateString(t, state, `<no state>`)
  3362  }
  3363  
  3364  // This is like the multiProviderDestroy test except it tests that
  3365  // dependent resources within a child module that inherit provider
  3366  // configuration are still destroyed first.
  3367  func TestContext2Apply_multiProviderDestroyChild(t *testing.T) {
  3368  	m := testModule(t, "apply-multi-provider-destroy-child")
  3369  	p := testProvider("aws")
  3370  	p.ApplyFn = testApplyFn
  3371  	p.DiffFn = testDiffFn
  3372  
  3373  	p2 := testProvider("do")
  3374  	p2.ApplyFn = testApplyFn
  3375  	p2.DiffFn = testDiffFn
  3376  
  3377  	var state *State
  3378  
  3379  	// First, create the instances
  3380  	{
  3381  		ctx := testContext2(t, &ContextOpts{
  3382  			Module: m,
  3383  			ProviderResolver: ResourceProviderResolverFixed(
  3384  				map[string]ResourceProviderFactory{
  3385  					"aws":   testProviderFuncFixed(p),
  3386  					"vault": testProviderFuncFixed(p2),
  3387  				},
  3388  			),
  3389  		})
  3390  
  3391  		if _, err := ctx.Plan(); err != nil {
  3392  			t.Fatalf("err: %s", err)
  3393  		}
  3394  
  3395  		s, err := ctx.Apply()
  3396  		if err != nil {
  3397  			t.Fatalf("err: %s", err)
  3398  		}
  3399  
  3400  		state = s
  3401  	}
  3402  
  3403  	// Destroy them
  3404  	{
  3405  		// Verify that aws_instance.bar is destroyed first
  3406  		var checked bool
  3407  		var called int32
  3408  		var lock sync.Mutex
  3409  		applyFn := func(
  3410  			info *InstanceInfo,
  3411  			is *InstanceState,
  3412  			id *InstanceDiff) (*InstanceState, error) {
  3413  			lock.Lock()
  3414  			defer lock.Unlock()
  3415  
  3416  			if info.HumanId() == "module.child.aws_instance.bar" {
  3417  				checked = true
  3418  
  3419  				// Sleep to allow parallel execution
  3420  				time.Sleep(50 * time.Millisecond)
  3421  
  3422  				// Verify that called is 0 (dep not called)
  3423  				if atomic.LoadInt32(&called) != 0 {
  3424  					return nil, fmt.Errorf("nothing else should be called")
  3425  				}
  3426  			}
  3427  
  3428  			atomic.AddInt32(&called, 1)
  3429  			return testApplyFn(info, is, id)
  3430  		}
  3431  
  3432  		// Set the apply functions
  3433  		p.ApplyFn = applyFn
  3434  		p2.ApplyFn = applyFn
  3435  
  3436  		ctx := testContext2(t, &ContextOpts{
  3437  			Destroy: true,
  3438  			State:   state,
  3439  			Module:  m,
  3440  			ProviderResolver: ResourceProviderResolverFixed(
  3441  				map[string]ResourceProviderFactory{
  3442  					"aws":   testProviderFuncFixed(p),
  3443  					"vault": testProviderFuncFixed(p2),
  3444  				},
  3445  			),
  3446  		})
  3447  
  3448  		if _, err := ctx.Plan(); err != nil {
  3449  			t.Fatalf("err: %s", err)
  3450  		}
  3451  
  3452  		s, err := ctx.Apply()
  3453  		if err != nil {
  3454  			t.Fatalf("err: %s", err)
  3455  		}
  3456  
  3457  		if !checked {
  3458  			t.Fatal("should be checked")
  3459  		}
  3460  
  3461  		state = s
  3462  	}
  3463  
  3464  	checkStateString(t, state, `
  3465  <no state>
  3466  module.child:
  3467    <no state>
  3468  `)
  3469  }
  3470  
  3471  func TestContext2Apply_multiVar(t *testing.T) {
  3472  	m := testModule(t, "apply-multi-var")
  3473  	p := testProvider("aws")
  3474  	p.ApplyFn = testApplyFn
  3475  	p.DiffFn = testDiffFn
  3476  
  3477  	// First, apply with a count of 3
  3478  	ctx := testContext2(t, &ContextOpts{
  3479  		Module: m,
  3480  		ProviderResolver: ResourceProviderResolverFixed(
  3481  			map[string]ResourceProviderFactory{
  3482  				"aws": testProviderFuncFixed(p),
  3483  			},
  3484  		),
  3485  		Variables: map[string]interface{}{
  3486  			"count": "3",
  3487  		},
  3488  	})
  3489  
  3490  	if _, err := ctx.Plan(); err != nil {
  3491  		t.Fatalf("err: %s", err)
  3492  	}
  3493  
  3494  	state, err := ctx.Apply()
  3495  	if err != nil {
  3496  		t.Fatalf("err: %s", err)
  3497  	}
  3498  
  3499  	actual := state.RootModule().Outputs["output"]
  3500  	expected := "bar0,bar1,bar2"
  3501  	if actual == nil || actual.Value != expected {
  3502  		t.Fatalf("bad: \n%s", actual)
  3503  	}
  3504  
  3505  	t.Logf("Initial state: %s", state.String())
  3506  
  3507  	// Apply again, reduce the count to 1
  3508  	{
  3509  		ctx := testContext2(t, &ContextOpts{
  3510  			Module: m,
  3511  			State:  state,
  3512  			ProviderResolver: ResourceProviderResolverFixed(
  3513  				map[string]ResourceProviderFactory{
  3514  					"aws": testProviderFuncFixed(p),
  3515  				},
  3516  			),
  3517  			Variables: map[string]interface{}{
  3518  				"count": "1",
  3519  			},
  3520  		})
  3521  
  3522  		if _, err := ctx.Plan(); err != nil {
  3523  			t.Fatalf("err: %s", err)
  3524  		}
  3525  
  3526  		state, err := ctx.Apply()
  3527  		if err != nil {
  3528  			t.Fatalf("err: %s", err)
  3529  		}
  3530  
  3531  		t.Logf("End state: %s", state.String())
  3532  
  3533  		actual := state.RootModule().Outputs["output"]
  3534  		if actual == nil {
  3535  			t.Fatal("missing output")
  3536  		}
  3537  
  3538  		expected := "bar0"
  3539  		if actual.Value != expected {
  3540  			t.Fatalf("bad: \n%s", actual)
  3541  		}
  3542  	}
  3543  }
  3544  
  3545  // This is a holistic test of multi-var (aka "splat variable") handling
  3546  // across several different Terraform subsystems. This is here because
  3547  // historically there were quirky differences in handling across different
  3548  // parts of Terraform and so here we want to assert the expected behavior and
  3549  // ensure that it remains consistent in future.
  3550  func TestContext2Apply_multiVarComprehensive(t *testing.T) {
  3551  	m := testModule(t, "apply-multi-var-comprehensive")
  3552  	p := testProvider("test")
  3553  
  3554  	configs := map[string]*ResourceConfig{}
  3555  
  3556  	p.ApplyFn = testApplyFn
  3557  
  3558  	p.DiffFn = func(info *InstanceInfo, s *InstanceState, c *ResourceConfig) (*InstanceDiff, error) {
  3559  		configs[info.HumanId()] = c
  3560  
  3561  		// Return a minimal diff to make sure this resource gets included in
  3562  		// the apply graph and thus the final state, but otherwise we're just
  3563  		// gathering data for assertions.
  3564  		return &InstanceDiff{
  3565  			Attributes: map[string]*ResourceAttrDiff{
  3566  				"id": &ResourceAttrDiff{
  3567  					NewComputed: true,
  3568  				},
  3569  				"name": &ResourceAttrDiff{
  3570  					New: info.HumanId(),
  3571  				},
  3572  			},
  3573  		}, nil
  3574  	}
  3575  
  3576  	// First, apply with a count of 3
  3577  	ctx := testContext2(t, &ContextOpts{
  3578  		Module: m,
  3579  		ProviderResolver: ResourceProviderResolverFixed(
  3580  			map[string]ResourceProviderFactory{
  3581  				"test": testProviderFuncFixed(p),
  3582  			},
  3583  		),
  3584  		Variables: map[string]interface{}{
  3585  			"count": "3",
  3586  		},
  3587  	})
  3588  
  3589  	if _, err := ctx.Plan(); err != nil {
  3590  		t.Fatalf("error during plan: %s", err)
  3591  	}
  3592  
  3593  	checkConfig := func(name string, want map[string]interface{}) {
  3594  		got := configs[name].Config
  3595  		if !reflect.DeepEqual(got, want) {
  3596  			t.Errorf(
  3597  				"wrong config for %s\ngot:  %s\nwant: %s",
  3598  				name, spew.Sdump(got), spew.Sdump(want),
  3599  			)
  3600  		}
  3601  	}
  3602  
  3603  	checkConfig("test_thing.multi_count_var.0", map[string]interface{}{
  3604  		"source_id":   unknownValue(),
  3605  		"source_name": "test_thing.source.0",
  3606  	})
  3607  	checkConfig("test_thing.multi_count_var.2", map[string]interface{}{
  3608  		"source_id":   unknownValue(),
  3609  		"source_name": "test_thing.source.2",
  3610  	})
  3611  	checkConfig("test_thing.multi_count_derived.0", map[string]interface{}{
  3612  		"source_id":   unknownValue(),
  3613  		"source_name": "test_thing.source.0",
  3614  	})
  3615  	checkConfig("test_thing.multi_count_derived.2", map[string]interface{}{
  3616  		"source_id":   unknownValue(),
  3617  		"source_name": "test_thing.source.2",
  3618  	})
  3619  	checkConfig("test_thing.whole_splat", map[string]interface{}{
  3620  		"source_ids": unknownValue(),
  3621  		"source_names": []interface{}{
  3622  			"test_thing.source.0",
  3623  			"test_thing.source.1",
  3624  			"test_thing.source.2",
  3625  		},
  3626  		"source_ids_from_func": unknownValue(),
  3627  		"source_names_from_func": []interface{}{
  3628  			"test_thing.source.0",
  3629  			"test_thing.source.1",
  3630  			"test_thing.source.2",
  3631  		},
  3632  
  3633  		// This one ends up being a list with a single unknown value at this
  3634  		// layer, but is fixed up inside helper/schema. There is a test for
  3635  		// this inside the "test" provider, since core tests can't exercise
  3636  		// helper/schema functionality.
  3637  		"source_ids_wrapped": []interface{}{unknownValue()},
  3638  
  3639  		"source_names_wrapped": []interface{}{
  3640  			"test_thing.source.0",
  3641  			"test_thing.source.1",
  3642  			"test_thing.source.2",
  3643  		},
  3644  		"first_source_id":   unknownValue(),
  3645  		"first_source_name": "test_thing.source.0",
  3646  	})
  3647  	checkConfig("module.child.test_thing.whole_splat", map[string]interface{}{
  3648  		"source_ids": unknownValue(),
  3649  		"source_names": []interface{}{
  3650  			"test_thing.source.0",
  3651  			"test_thing.source.1",
  3652  			"test_thing.source.2",
  3653  		},
  3654  
  3655  		// This one ends up being a list with a single unknown value at this
  3656  		// layer, but is fixed up inside helper/schema. There is a test for
  3657  		// this inside the "test" provider, since core tests can't exercise
  3658  		// helper/schema functionality.
  3659  		"source_ids_wrapped": []interface{}{unknownValue()},
  3660  
  3661  		"source_names_wrapped": []interface{}{
  3662  			"test_thing.source.0",
  3663  			"test_thing.source.1",
  3664  			"test_thing.source.2",
  3665  		},
  3666  	})
  3667  
  3668  	state, err := ctx.Apply()
  3669  	if err != nil {
  3670  		t.Fatalf("error during apply: %s", err)
  3671  	}
  3672  
  3673  	{
  3674  		want := map[string]interface{}{
  3675  			"source_ids": []interface{}{"foo", "foo", "foo"},
  3676  			"source_names": []interface{}{
  3677  				"test_thing.source.0",
  3678  				"test_thing.source.1",
  3679  				"test_thing.source.2",
  3680  			},
  3681  		}
  3682  		got := map[string]interface{}{}
  3683  		for k, s := range state.RootModule().Outputs {
  3684  			got[k] = s.Value
  3685  		}
  3686  		if !reflect.DeepEqual(got, want) {
  3687  			t.Errorf(
  3688  				"wrong outputs\ngot:  %s\nwant: %s",
  3689  				spew.Sdump(got), spew.Sdump(want),
  3690  			)
  3691  		}
  3692  	}
  3693  }
  3694  
  3695  // Test that multi-var (splat) access is ordered by count, not by
  3696  // value.
  3697  func TestContext2Apply_multiVarOrder(t *testing.T) {
  3698  	m := testModule(t, "apply-multi-var-order")
  3699  	p := testProvider("aws")
  3700  	p.ApplyFn = testApplyFn
  3701  	p.DiffFn = testDiffFn
  3702  
  3703  	// First, apply with a count of 3
  3704  	ctx := testContext2(t, &ContextOpts{
  3705  		Module: m,
  3706  		ProviderResolver: ResourceProviderResolverFixed(
  3707  			map[string]ResourceProviderFactory{
  3708  				"aws": testProviderFuncFixed(p),
  3709  			},
  3710  		),
  3711  	})
  3712  
  3713  	if _, err := ctx.Plan(); err != nil {
  3714  		t.Fatalf("err: %s", err)
  3715  	}
  3716  
  3717  	state, err := ctx.Apply()
  3718  	if err != nil {
  3719  		t.Fatalf("err: %s", err)
  3720  	}
  3721  
  3722  	t.Logf("State: %s", state.String())
  3723  
  3724  	actual := state.RootModule().Outputs["should-be-11"]
  3725  	expected := "index-11"
  3726  	if actual == nil || actual.Value != expected {
  3727  		t.Fatalf("bad: \n%s", actual)
  3728  	}
  3729  }
  3730  
  3731  // Test that multi-var (splat) access is ordered by count, not by
  3732  // value, through interpolations.
  3733  func TestContext2Apply_multiVarOrderInterp(t *testing.T) {
  3734  	m := testModule(t, "apply-multi-var-order-interp")
  3735  	p := testProvider("aws")
  3736  	p.ApplyFn = testApplyFn
  3737  	p.DiffFn = testDiffFn
  3738  
  3739  	// First, apply with a count of 3
  3740  	ctx := testContext2(t, &ContextOpts{
  3741  		Module: m,
  3742  		ProviderResolver: ResourceProviderResolverFixed(
  3743  			map[string]ResourceProviderFactory{
  3744  				"aws": testProviderFuncFixed(p),
  3745  			},
  3746  		),
  3747  	})
  3748  
  3749  	if _, err := ctx.Plan(); err != nil {
  3750  		t.Fatalf("err: %s", err)
  3751  	}
  3752  
  3753  	state, err := ctx.Apply()
  3754  	if err != nil {
  3755  		t.Fatalf("err: %s", err)
  3756  	}
  3757  
  3758  	t.Logf("State: %s", state.String())
  3759  
  3760  	actual := state.RootModule().Outputs["should-be-11"]
  3761  	expected := "baz-index-11"
  3762  	if actual == nil || actual.Value != expected {
  3763  		t.Fatalf("bad: \n%s", actual)
  3764  	}
  3765  }
  3766  
  3767  // Based on GH-10440 where a graph edge wasn't properly being created
  3768  // between a modified resource and a count instance being destroyed.
  3769  func TestContext2Apply_multiVarCountDec(t *testing.T) {
  3770  	var s *State
  3771  
  3772  	// First create resources. Nothing sneaky here.
  3773  	{
  3774  		m := testModule(t, "apply-multi-var-count-dec")
  3775  		p := testProvider("aws")
  3776  		p.ApplyFn = testApplyFn
  3777  		p.DiffFn = testDiffFn
  3778  		ctx := testContext2(t, &ContextOpts{
  3779  			Module: m,
  3780  			ProviderResolver: ResourceProviderResolverFixed(
  3781  				map[string]ResourceProviderFactory{
  3782  					"aws": testProviderFuncFixed(p),
  3783  				},
  3784  			),
  3785  			Variables: map[string]interface{}{
  3786  				"count": "2",
  3787  			},
  3788  		})
  3789  
  3790  		if _, err := ctx.Plan(); err != nil {
  3791  			t.Fatalf("err: %s", err)
  3792  		}
  3793  
  3794  		state, err := ctx.Apply()
  3795  		if err != nil {
  3796  			t.Fatalf("err: %s", err)
  3797  		}
  3798  
  3799  		t.Logf("Step 1 state: %s", state)
  3800  
  3801  		s = state
  3802  	}
  3803  
  3804  	// Decrease the count by 1 and verify that everything happens in the
  3805  	// right order.
  3806  	{
  3807  		m := testModule(t, "apply-multi-var-count-dec")
  3808  		p := testProvider("aws")
  3809  		p.ApplyFn = testApplyFn
  3810  		p.DiffFn = testDiffFn
  3811  
  3812  		// Verify that aws_instance.bar is modified first and nothing
  3813  		// else happens at the same time.
  3814  		var checked bool
  3815  		var called int32
  3816  		var lock sync.Mutex
  3817  		p.ApplyFn = func(
  3818  			info *InstanceInfo,
  3819  			is *InstanceState,
  3820  			id *InstanceDiff) (*InstanceState, error) {
  3821  			lock.Lock()
  3822  			defer lock.Unlock()
  3823  
  3824  			if info.HumanId() == "aws_instance.bar" {
  3825  				checked = true
  3826  
  3827  				// Sleep to allow parallel execution
  3828  				time.Sleep(50 * time.Millisecond)
  3829  
  3830  				// Verify that called is 0 (dep not called)
  3831  				if atomic.LoadInt32(&called) != 1 {
  3832  					return nil, fmt.Errorf("nothing else should be called")
  3833  				}
  3834  			}
  3835  
  3836  			atomic.AddInt32(&called, 1)
  3837  			return testApplyFn(info, is, id)
  3838  		}
  3839  
  3840  		ctx := testContext2(t, &ContextOpts{
  3841  			State:  s,
  3842  			Module: m,
  3843  			ProviderResolver: ResourceProviderResolverFixed(
  3844  				map[string]ResourceProviderFactory{
  3845  					"aws": testProviderFuncFixed(p),
  3846  				},
  3847  			),
  3848  			Variables: map[string]interface{}{
  3849  				"count": "1",
  3850  			},
  3851  		})
  3852  
  3853  		if _, err := ctx.Plan(); err != nil {
  3854  			t.Fatalf("err: %s", err)
  3855  		}
  3856  
  3857  		state, err := ctx.Apply()
  3858  		if err != nil {
  3859  			t.Fatalf("err: %s", err)
  3860  		}
  3861  
  3862  		if !checked {
  3863  			t.Fatal("apply never called")
  3864  		}
  3865  
  3866  		t.Logf("Step 2 state: %s", state)
  3867  
  3868  		s = state
  3869  	}
  3870  }
  3871  
  3872  // Test that we can resolve a multi-var (splat) for the first resource
  3873  // created in a non-root module, which happens when the module state doesn't
  3874  // exist yet.
  3875  // https://github.com/hashicorp/terraform/issues/14438
  3876  func TestContext2Apply_multiVarMissingState(t *testing.T) {
  3877  	m := testModule(t, "apply-multi-var-missing-state")
  3878  	p := testProvider("test")
  3879  	p.ApplyFn = testApplyFn
  3880  	p.DiffFn = testDiffFn
  3881  
  3882  	// First, apply with a count of 3
  3883  	ctx := testContext2(t, &ContextOpts{
  3884  		Module: m,
  3885  		ProviderResolver: ResourceProviderResolverFixed(
  3886  			map[string]ResourceProviderFactory{
  3887  				"test": testProviderFuncFixed(p),
  3888  			},
  3889  		),
  3890  	})
  3891  
  3892  	if _, err := ctx.Plan(); err != nil {
  3893  		t.Fatalf("plan failed: %s", err)
  3894  	}
  3895  
  3896  	// Before the relevant bug was fixed, Terraform would panic during apply.
  3897  	if _, err := ctx.Apply(); err != nil {
  3898  		t.Fatalf("apply failed: %s", err)
  3899  	}
  3900  
  3901  	// If we get here with no errors or panics then our test was successful.
  3902  }
  3903  
  3904  func TestContext2Apply_nilDiff(t *testing.T) {
  3905  	m := testModule(t, "apply-good")
  3906  	p := testProvider("aws")
  3907  	p.ApplyFn = testApplyFn
  3908  	p.DiffFn = testDiffFn
  3909  	ctx := testContext2(t, &ContextOpts{
  3910  		Module: m,
  3911  		ProviderResolver: ResourceProviderResolverFixed(
  3912  			map[string]ResourceProviderFactory{
  3913  				"aws": testProviderFuncFixed(p),
  3914  			},
  3915  		),
  3916  	})
  3917  
  3918  	if _, err := ctx.Plan(); err != nil {
  3919  		t.Fatalf("err: %s", err)
  3920  	}
  3921  
  3922  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  3923  		return nil, nil
  3924  	}
  3925  
  3926  	if _, err := ctx.Apply(); err == nil {
  3927  		t.Fatal("should error")
  3928  	}
  3929  }
  3930  
  3931  func TestContext2Apply_outputDependsOn(t *testing.T) {
  3932  	m := testModule(t, "apply-output-depends-on")
  3933  	p := testProvider("aws")
  3934  	p.DiffFn = testDiffFn
  3935  
  3936  	{
  3937  		// Create a custom apply function that sleeps a bit (to allow parallel
  3938  		// graph execution) and then returns an error to force a partial state
  3939  		// return. We then verify the output is NOT there.
  3940  		p.ApplyFn = func(
  3941  			info *InstanceInfo,
  3942  			is *InstanceState,
  3943  			id *InstanceDiff) (*InstanceState, error) {
  3944  			// Sleep to allow parallel execution
  3945  			time.Sleep(50 * time.Millisecond)
  3946  
  3947  			// Return error to force partial state
  3948  			return nil, fmt.Errorf("abcd")
  3949  		}
  3950  
  3951  		ctx := testContext2(t, &ContextOpts{
  3952  			Module: m,
  3953  			ProviderResolver: ResourceProviderResolverFixed(
  3954  				map[string]ResourceProviderFactory{
  3955  					"aws": testProviderFuncFixed(p),
  3956  				},
  3957  			),
  3958  		})
  3959  
  3960  		if _, err := ctx.Plan(); err != nil {
  3961  			t.Fatalf("err: %s", err)
  3962  		}
  3963  
  3964  		state, err := ctx.Apply()
  3965  		if err == nil || !strings.Contains(err.Error(), "abcd") {
  3966  			t.Fatalf("err: %s", err)
  3967  		}
  3968  
  3969  		checkStateString(t, state, `<no state>`)
  3970  	}
  3971  
  3972  	{
  3973  		// Create the standard apply function and verify we get the output
  3974  		p.ApplyFn = testApplyFn
  3975  
  3976  		ctx := testContext2(t, &ContextOpts{
  3977  			Module: m,
  3978  			ProviderResolver: ResourceProviderResolverFixed(
  3979  				map[string]ResourceProviderFactory{
  3980  					"aws": testProviderFuncFixed(p),
  3981  				},
  3982  			),
  3983  		})
  3984  
  3985  		if _, err := ctx.Plan(); err != nil {
  3986  			t.Fatalf("err: %s", err)
  3987  		}
  3988  
  3989  		state, err := ctx.Apply()
  3990  		if err != nil {
  3991  			t.Fatalf("err: %s", err)
  3992  		}
  3993  
  3994  		checkStateString(t, state, `
  3995  aws_instance.foo:
  3996    ID = foo
  3997    provider = provider.aws
  3998  
  3999  Outputs:
  4000  
  4001  value = result
  4002  		`)
  4003  	}
  4004  }
  4005  
  4006  func TestContext2Apply_outputOrphan(t *testing.T) {
  4007  	m := testModule(t, "apply-output-orphan")
  4008  	p := testProvider("aws")
  4009  	p.ApplyFn = testApplyFn
  4010  	p.DiffFn = testDiffFn
  4011  
  4012  	state := &State{
  4013  		Modules: []*ModuleState{
  4014  			&ModuleState{
  4015  				Path: rootModulePath,
  4016  				Outputs: map[string]*OutputState{
  4017  					"foo": &OutputState{
  4018  						Type:      "string",
  4019  						Sensitive: false,
  4020  						Value:     "bar",
  4021  					},
  4022  					"bar": &OutputState{
  4023  						Type:      "string",
  4024  						Sensitive: false,
  4025  						Value:     "baz",
  4026  					},
  4027  				},
  4028  			},
  4029  		},
  4030  	}
  4031  
  4032  	ctx := testContext2(t, &ContextOpts{
  4033  		Module: m,
  4034  		ProviderResolver: ResourceProviderResolverFixed(
  4035  			map[string]ResourceProviderFactory{
  4036  				"aws": testProviderFuncFixed(p),
  4037  			},
  4038  		),
  4039  		State: state,
  4040  	})
  4041  
  4042  	if _, err := ctx.Plan(); err != nil {
  4043  		t.Fatalf("err: %s", err)
  4044  	}
  4045  
  4046  	state, err := ctx.Apply()
  4047  	if err != nil {
  4048  		t.Fatalf("err: %s", err)
  4049  	}
  4050  
  4051  	actual := strings.TrimSpace(state.String())
  4052  	expected := strings.TrimSpace(testTerraformApplyOutputOrphanStr)
  4053  	if actual != expected {
  4054  		t.Fatalf("bad: \n%s", actual)
  4055  	}
  4056  }
  4057  
  4058  func TestContext2Apply_outputOrphanModule(t *testing.T) {
  4059  	m := testModule(t, "apply-output-orphan-module")
  4060  	p := testProvider("aws")
  4061  	p.ApplyFn = testApplyFn
  4062  	p.DiffFn = testDiffFn
  4063  
  4064  	state := &State{
  4065  		Modules: []*ModuleState{
  4066  			&ModuleState{
  4067  				Path: []string{"root", "child"},
  4068  				Outputs: map[string]*OutputState{
  4069  					"foo": &OutputState{
  4070  						Type:  "string",
  4071  						Value: "bar",
  4072  					},
  4073  					"bar": &OutputState{
  4074  						Type:  "string",
  4075  						Value: "baz",
  4076  					},
  4077  				},
  4078  			},
  4079  		},
  4080  	}
  4081  
  4082  	ctx := testContext2(t, &ContextOpts{
  4083  		Module: m,
  4084  		ProviderResolver: ResourceProviderResolverFixed(
  4085  			map[string]ResourceProviderFactory{
  4086  				"aws": testProviderFuncFixed(p),
  4087  			},
  4088  		),
  4089  		State: state.DeepCopy(),
  4090  	})
  4091  
  4092  	if _, err := ctx.Plan(); err != nil {
  4093  		t.Fatalf("err: %s", err)
  4094  	}
  4095  
  4096  	state, err := ctx.Apply()
  4097  	if err != nil {
  4098  		t.Fatalf("err: %s", err)
  4099  	}
  4100  
  4101  	actual := strings.TrimSpace(state.String())
  4102  	expected := strings.TrimSpace(testTerraformApplyOutputOrphanModuleStr)
  4103  	if actual != expected {
  4104  		t.Fatalf("expected:\n%s\n\ngot:\n%s", expected, actual)
  4105  	}
  4106  
  4107  	// now apply with no module in the config, which should remove the
  4108  	// remaining output
  4109  	ctx = testContext2(t, &ContextOpts{
  4110  		Module: module.NewEmptyTree(),
  4111  		ProviderResolver: ResourceProviderResolverFixed(
  4112  			map[string]ResourceProviderFactory{
  4113  				"aws": testProviderFuncFixed(p),
  4114  			},
  4115  		),
  4116  		State: state.DeepCopy(),
  4117  	})
  4118  
  4119  	if _, err := ctx.Plan(); err != nil {
  4120  		t.Fatalf("err: %s", err)
  4121  	}
  4122  
  4123  	state, err = ctx.Apply()
  4124  	if err != nil {
  4125  		t.Fatalf("err: %s", err)
  4126  	}
  4127  
  4128  	actual = strings.TrimSpace(state.String())
  4129  	if actual != "" {
  4130  		t.Fatalf("expected no state, got:\n%s", actual)
  4131  	}
  4132  }
  4133  
  4134  func TestContext2Apply_providerComputedVar(t *testing.T) {
  4135  	m := testModule(t, "apply-provider-computed")
  4136  	p := testProvider("aws")
  4137  	p.ApplyFn = testApplyFn
  4138  	p.DiffFn = testDiffFn
  4139  
  4140  	pTest := testProvider("test")
  4141  	pTest.ApplyFn = testApplyFn
  4142  	pTest.DiffFn = testDiffFn
  4143  
  4144  	ctx := testContext2(t, &ContextOpts{
  4145  		Module: m,
  4146  		ProviderResolver: ResourceProviderResolverFixed(
  4147  			map[string]ResourceProviderFactory{
  4148  				"aws":  testProviderFuncFixed(p),
  4149  				"test": testProviderFuncFixed(pTest),
  4150  			},
  4151  		),
  4152  	})
  4153  
  4154  	p.ConfigureFn = func(c *ResourceConfig) error {
  4155  		if c.IsComputed("value") {
  4156  			return fmt.Errorf("value is computed")
  4157  		}
  4158  
  4159  		v, ok := c.Get("value")
  4160  		if !ok {
  4161  			return fmt.Errorf("value is not found")
  4162  		}
  4163  		if v != "yes" {
  4164  			return fmt.Errorf("value is not 'yes': %v", v)
  4165  		}
  4166  
  4167  		return nil
  4168  	}
  4169  
  4170  	if _, err := ctx.Plan(); err != nil {
  4171  		t.Fatalf("err: %s", err)
  4172  	}
  4173  
  4174  	if _, err := ctx.Apply(); err != nil {
  4175  		t.Fatalf("err: %s", err)
  4176  	}
  4177  }
  4178  
  4179  func TestContext2Apply_providerConfigureDisabled(t *testing.T) {
  4180  	m := testModule(t, "apply-provider-configure-disabled")
  4181  	p := testProvider("aws")
  4182  	p.ApplyFn = testApplyFn
  4183  	p.DiffFn = testDiffFn
  4184  
  4185  	called := false
  4186  	p.ConfigureFn = func(c *ResourceConfig) error {
  4187  		called = true
  4188  
  4189  		if _, ok := c.Get("value"); !ok {
  4190  			return fmt.Errorf("value is not found")
  4191  		}
  4192  
  4193  		return nil
  4194  	}
  4195  
  4196  	ctx := testContext2(t, &ContextOpts{
  4197  		Module: m,
  4198  		ProviderResolver: ResourceProviderResolverFixed(
  4199  			map[string]ResourceProviderFactory{
  4200  				"aws": testProviderFuncFixed(p),
  4201  			},
  4202  		),
  4203  	})
  4204  
  4205  	if _, err := ctx.Plan(); err != nil {
  4206  		t.Fatalf("err: %s", err)
  4207  	}
  4208  
  4209  	if _, err := ctx.Apply(); err != nil {
  4210  		t.Fatalf("err: %s", err)
  4211  	}
  4212  
  4213  	if !called {
  4214  		t.Fatal("configure never called")
  4215  	}
  4216  }
  4217  
  4218  func TestContext2Apply_provisionerModule(t *testing.T) {
  4219  	m := testModule(t, "apply-provisioner-module")
  4220  	p := testProvider("aws")
  4221  	pr := testProvisioner()
  4222  	p.ApplyFn = testApplyFn
  4223  	p.DiffFn = testDiffFn
  4224  	ctx := testContext2(t, &ContextOpts{
  4225  		Module: m,
  4226  		ProviderResolver: ResourceProviderResolverFixed(
  4227  			map[string]ResourceProviderFactory{
  4228  				"aws": testProviderFuncFixed(p),
  4229  			},
  4230  		),
  4231  		Provisioners: map[string]ResourceProvisionerFactory{
  4232  			"shell": testProvisionerFuncFixed(pr),
  4233  		},
  4234  	})
  4235  
  4236  	if _, err := ctx.Plan(); err != nil {
  4237  		t.Fatalf("err: %s", err)
  4238  	}
  4239  
  4240  	state, err := ctx.Apply()
  4241  	if err != nil {
  4242  		t.Fatalf("err: %s", err)
  4243  	}
  4244  
  4245  	actual := strings.TrimSpace(state.String())
  4246  	expected := strings.TrimSpace(testTerraformApplyProvisionerModuleStr)
  4247  	if actual != expected {
  4248  		t.Fatalf("bad: \n%s", actual)
  4249  	}
  4250  
  4251  	// Verify apply was invoked
  4252  	if !pr.ApplyCalled {
  4253  		t.Fatalf("provisioner not invoked")
  4254  	}
  4255  }
  4256  
  4257  func TestContext2Apply_Provisioner_compute(t *testing.T) {
  4258  	m := testModule(t, "apply-provisioner-compute")
  4259  	p := testProvider("aws")
  4260  	pr := testProvisioner()
  4261  	p.ApplyFn = testApplyFn
  4262  	p.DiffFn = testDiffFn
  4263  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  4264  		val, ok := c.Config["foo"]
  4265  		if !ok || val != "computed_dynamical" {
  4266  			t.Fatalf("bad value for foo: %v %#v", val, c)
  4267  		}
  4268  
  4269  		return nil
  4270  	}
  4271  	ctx := testContext2(t, &ContextOpts{
  4272  		Module: m,
  4273  		ProviderResolver: ResourceProviderResolverFixed(
  4274  			map[string]ResourceProviderFactory{
  4275  				"aws": testProviderFuncFixed(p),
  4276  			},
  4277  		),
  4278  		Provisioners: map[string]ResourceProvisionerFactory{
  4279  			"shell": testProvisionerFuncFixed(pr),
  4280  		},
  4281  		Variables: map[string]interface{}{
  4282  			"value": "1",
  4283  		},
  4284  	})
  4285  
  4286  	if _, err := ctx.Plan(); err != nil {
  4287  		t.Fatalf("err: %s", err)
  4288  	}
  4289  
  4290  	state, err := ctx.Apply()
  4291  	if err != nil {
  4292  		t.Fatalf("err: %s", err)
  4293  	}
  4294  
  4295  	actual := strings.TrimSpace(state.String())
  4296  	expected := strings.TrimSpace(testTerraformApplyProvisionerStr)
  4297  	if actual != expected {
  4298  		t.Fatalf("bad: \n%s", actual)
  4299  	}
  4300  
  4301  	// Verify apply was invoked
  4302  	if !pr.ApplyCalled {
  4303  		t.Fatalf("provisioner not invoked")
  4304  	}
  4305  }
  4306  
  4307  func TestContext2Apply_provisionerCreateFail(t *testing.T) {
  4308  	m := testModule(t, "apply-provisioner-fail-create")
  4309  	p := testProvider("aws")
  4310  	pr := testProvisioner()
  4311  	p.DiffFn = testDiffFn
  4312  
  4313  	p.ApplyFn = func(
  4314  		info *InstanceInfo,
  4315  		is *InstanceState,
  4316  		id *InstanceDiff) (*InstanceState, error) {
  4317  		is.ID = "foo"
  4318  		return is, fmt.Errorf("error")
  4319  	}
  4320  
  4321  	ctx := testContext2(t, &ContextOpts{
  4322  		Module: m,
  4323  		ProviderResolver: ResourceProviderResolverFixed(
  4324  			map[string]ResourceProviderFactory{
  4325  				"aws": testProviderFuncFixed(p),
  4326  			},
  4327  		),
  4328  		Provisioners: map[string]ResourceProvisionerFactory{
  4329  			"shell": testProvisionerFuncFixed(pr),
  4330  		},
  4331  	})
  4332  
  4333  	if _, err := ctx.Plan(); err != nil {
  4334  		t.Fatalf("err: %s", err)
  4335  	}
  4336  
  4337  	state, err := ctx.Apply()
  4338  	if err == nil {
  4339  		t.Fatal("should error")
  4340  	}
  4341  
  4342  	actual := strings.TrimSpace(state.String())
  4343  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailCreateStr)
  4344  	if actual != expected {
  4345  		t.Fatalf("bad: \n%s", actual)
  4346  	}
  4347  }
  4348  
  4349  func TestContext2Apply_provisionerCreateFailNoId(t *testing.T) {
  4350  	m := testModule(t, "apply-provisioner-fail-create")
  4351  	p := testProvider("aws")
  4352  	pr := testProvisioner()
  4353  	p.DiffFn = testDiffFn
  4354  
  4355  	p.ApplyFn = func(
  4356  		info *InstanceInfo,
  4357  		is *InstanceState,
  4358  		id *InstanceDiff) (*InstanceState, error) {
  4359  		return nil, fmt.Errorf("error")
  4360  	}
  4361  
  4362  	ctx := testContext2(t, &ContextOpts{
  4363  		Module: m,
  4364  		ProviderResolver: ResourceProviderResolverFixed(
  4365  			map[string]ResourceProviderFactory{
  4366  				"aws": testProviderFuncFixed(p),
  4367  			},
  4368  		),
  4369  		Provisioners: map[string]ResourceProvisionerFactory{
  4370  			"shell": testProvisionerFuncFixed(pr),
  4371  		},
  4372  	})
  4373  
  4374  	if _, err := ctx.Plan(); err != nil {
  4375  		t.Fatalf("err: %s", err)
  4376  	}
  4377  
  4378  	state, err := ctx.Apply()
  4379  	if err == nil {
  4380  		t.Fatal("should error")
  4381  	}
  4382  
  4383  	actual := strings.TrimSpace(state.String())
  4384  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailCreateNoIdStr)
  4385  	if actual != expected {
  4386  		t.Fatalf("bad: \n%s", actual)
  4387  	}
  4388  }
  4389  
  4390  func TestContext2Apply_provisionerFail(t *testing.T) {
  4391  	m := testModule(t, "apply-provisioner-fail")
  4392  	p := testProvider("aws")
  4393  	pr := testProvisioner()
  4394  	p.ApplyFn = testApplyFn
  4395  	p.DiffFn = testDiffFn
  4396  
  4397  	pr.ApplyFn = func(*InstanceState, *ResourceConfig) error {
  4398  		return fmt.Errorf("EXPLOSION")
  4399  	}
  4400  
  4401  	ctx := testContext2(t, &ContextOpts{
  4402  		Module: m,
  4403  		ProviderResolver: ResourceProviderResolverFixed(
  4404  			map[string]ResourceProviderFactory{
  4405  				"aws": testProviderFuncFixed(p),
  4406  			},
  4407  		),
  4408  		Provisioners: map[string]ResourceProvisionerFactory{
  4409  			"shell": testProvisionerFuncFixed(pr),
  4410  		},
  4411  		Variables: map[string]interface{}{
  4412  			"value": "1",
  4413  		},
  4414  	})
  4415  
  4416  	if _, err := ctx.Plan(); err != nil {
  4417  		t.Fatalf("err: %s", err)
  4418  	}
  4419  
  4420  	state, err := ctx.Apply()
  4421  	if err == nil {
  4422  		t.Fatal("should error")
  4423  	}
  4424  
  4425  	actual := strings.TrimSpace(state.String())
  4426  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailStr)
  4427  	if actual != expected {
  4428  		t.Fatalf("bad: \n%s", actual)
  4429  	}
  4430  }
  4431  
  4432  func TestContext2Apply_provisionerFail_createBeforeDestroy(t *testing.T) {
  4433  	m := testModule(t, "apply-provisioner-fail-create-before")
  4434  	p := testProvider("aws")
  4435  	pr := testProvisioner()
  4436  	p.ApplyFn = testApplyFn
  4437  	p.DiffFn = testDiffFn
  4438  	pr.ApplyFn = func(*InstanceState, *ResourceConfig) error {
  4439  		return fmt.Errorf("EXPLOSION")
  4440  	}
  4441  
  4442  	state := &State{
  4443  		Modules: []*ModuleState{
  4444  			&ModuleState{
  4445  				Path: rootModulePath,
  4446  				Resources: map[string]*ResourceState{
  4447  					"aws_instance.bar": &ResourceState{
  4448  						Type: "aws_instance",
  4449  						Primary: &InstanceState{
  4450  							ID: "bar",
  4451  							Attributes: map[string]string{
  4452  								"require_new": "abc",
  4453  							},
  4454  						},
  4455  					},
  4456  				},
  4457  			},
  4458  		},
  4459  	}
  4460  	ctx := testContext2(t, &ContextOpts{
  4461  		Module: m,
  4462  		ProviderResolver: ResourceProviderResolverFixed(
  4463  			map[string]ResourceProviderFactory{
  4464  				"aws": testProviderFuncFixed(p),
  4465  			},
  4466  		),
  4467  		Provisioners: map[string]ResourceProvisionerFactory{
  4468  			"shell": testProvisionerFuncFixed(pr),
  4469  		},
  4470  		State: state,
  4471  	})
  4472  
  4473  	if _, err := ctx.Plan(); err != nil {
  4474  		t.Fatalf("err: %s", err)
  4475  	}
  4476  
  4477  	state, err := ctx.Apply()
  4478  	if err == nil {
  4479  		t.Fatal("should error")
  4480  	}
  4481  
  4482  	actual := strings.TrimSpace(state.String())
  4483  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailCreateBeforeDestroyStr)
  4484  	if actual != expected {
  4485  		t.Fatalf("expected:\n%s\n:got\n%s", expected, actual)
  4486  	}
  4487  }
  4488  
  4489  func TestContext2Apply_error_createBeforeDestroy(t *testing.T) {
  4490  	m := testModule(t, "apply-error-create-before")
  4491  	p := testProvider("aws")
  4492  	state := &State{
  4493  		Modules: []*ModuleState{
  4494  			&ModuleState{
  4495  				Path: rootModulePath,
  4496  				Resources: map[string]*ResourceState{
  4497  					"aws_instance.bar": &ResourceState{
  4498  						Type: "aws_instance",
  4499  						Primary: &InstanceState{
  4500  							ID: "bar",
  4501  							Attributes: map[string]string{
  4502  								"require_new": "abc",
  4503  							},
  4504  						},
  4505  					},
  4506  				},
  4507  			},
  4508  		},
  4509  	}
  4510  	ctx := testContext2(t, &ContextOpts{
  4511  		Module: m,
  4512  		ProviderResolver: ResourceProviderResolverFixed(
  4513  			map[string]ResourceProviderFactory{
  4514  				"aws": testProviderFuncFixed(p),
  4515  			},
  4516  		),
  4517  		State: state,
  4518  	})
  4519  	p.ApplyFn = func(info *InstanceInfo, is *InstanceState, id *InstanceDiff) (*InstanceState, error) {
  4520  		return nil, fmt.Errorf("error")
  4521  	}
  4522  	p.DiffFn = testDiffFn
  4523  
  4524  	if _, err := ctx.Plan(); err != nil {
  4525  		t.Fatalf("err: %s", err)
  4526  	}
  4527  
  4528  	state, err := ctx.Apply()
  4529  	if err == nil {
  4530  		t.Fatal("should have error")
  4531  	}
  4532  
  4533  	actual := strings.TrimSpace(state.String())
  4534  	expected := strings.TrimSpace(testTerraformApplyErrorCreateBeforeDestroyStr)
  4535  	if actual != expected {
  4536  		t.Fatalf("bad: \n%s\n\nExpected:\n\n%s", actual, expected)
  4537  	}
  4538  }
  4539  
  4540  func TestContext2Apply_errorDestroy_createBeforeDestroy(t *testing.T) {
  4541  	m := testModule(t, "apply-error-create-before")
  4542  	p := testProvider("aws")
  4543  	state := &State{
  4544  		Modules: []*ModuleState{
  4545  			&ModuleState{
  4546  				Path: rootModulePath,
  4547  				Resources: map[string]*ResourceState{
  4548  					"aws_instance.bar": &ResourceState{
  4549  						Type: "aws_instance",
  4550  						Primary: &InstanceState{
  4551  							ID: "bar",
  4552  							Attributes: map[string]string{
  4553  								"require_new": "abc",
  4554  							},
  4555  						},
  4556  					},
  4557  				},
  4558  			},
  4559  		},
  4560  	}
  4561  	ctx := testContext2(t, &ContextOpts{
  4562  		Module: m,
  4563  		ProviderResolver: ResourceProviderResolverFixed(
  4564  			map[string]ResourceProviderFactory{
  4565  				"aws": testProviderFuncFixed(p),
  4566  			},
  4567  		),
  4568  		State: state,
  4569  	})
  4570  	p.ApplyFn = func(info *InstanceInfo, is *InstanceState, id *InstanceDiff) (*InstanceState, error) {
  4571  		// Fail the destroy!
  4572  		if id.Destroy {
  4573  			return is, fmt.Errorf("error")
  4574  		}
  4575  
  4576  		// Create should work
  4577  		is = &InstanceState{
  4578  			ID: "foo",
  4579  		}
  4580  		return is, nil
  4581  	}
  4582  	p.DiffFn = testDiffFn
  4583  
  4584  	if _, err := ctx.Plan(); err != nil {
  4585  		t.Fatalf("err: %s", err)
  4586  	}
  4587  
  4588  	state, err := ctx.Apply()
  4589  	if err == nil {
  4590  		t.Fatal("should have error")
  4591  	}
  4592  
  4593  	actual := strings.TrimSpace(state.String())
  4594  	expected := strings.TrimSpace(testTerraformApplyErrorDestroyCreateBeforeDestroyStr)
  4595  	if actual != expected {
  4596  		t.Fatalf("bad: actual:\n%s\n\nexpected:\n%s", actual, expected)
  4597  	}
  4598  }
  4599  
  4600  func TestContext2Apply_multiDepose_createBeforeDestroy(t *testing.T) {
  4601  	m := testModule(t, "apply-multi-depose-create-before-destroy")
  4602  	p := testProvider("aws")
  4603  	p.DiffFn = testDiffFn
  4604  	ps := map[string]ResourceProviderFactory{"aws": testProviderFuncFixed(p)}
  4605  	state := &State{
  4606  		Modules: []*ModuleState{
  4607  			&ModuleState{
  4608  				Path: rootModulePath,
  4609  				Resources: map[string]*ResourceState{
  4610  					"aws_instance.web": &ResourceState{
  4611  						Type:    "aws_instance",
  4612  						Primary: &InstanceState{ID: "foo"},
  4613  					},
  4614  				},
  4615  			},
  4616  		},
  4617  	}
  4618  
  4619  	ctx := testContext2(t, &ContextOpts{
  4620  		Module:           m,
  4621  		ProviderResolver: ResourceProviderResolverFixed(ps),
  4622  		State:            state,
  4623  	})
  4624  	createdInstanceId := "bar"
  4625  	// Create works
  4626  	createFunc := func(is *InstanceState) (*InstanceState, error) {
  4627  		return &InstanceState{ID: createdInstanceId}, nil
  4628  	}
  4629  	// Destroy starts broken
  4630  	destroyFunc := func(is *InstanceState) (*InstanceState, error) {
  4631  		return is, fmt.Errorf("destroy failed")
  4632  	}
  4633  	p.ApplyFn = func(info *InstanceInfo, is *InstanceState, id *InstanceDiff) (*InstanceState, error) {
  4634  		if id.Destroy {
  4635  			return destroyFunc(is)
  4636  		} else {
  4637  			return createFunc(is)
  4638  		}
  4639  	}
  4640  
  4641  	if _, err := ctx.Plan(); err != nil {
  4642  		t.Fatalf("err: %s", err)
  4643  	}
  4644  
  4645  	// Destroy is broken, so even though CBD successfully replaces the instance,
  4646  	// we'll have to save the Deposed instance to destroy later
  4647  	state, err := ctx.Apply()
  4648  	if err == nil {
  4649  		t.Fatal("should have error")
  4650  	}
  4651  
  4652  	checkStateString(t, state, `
  4653  aws_instance.web: (1 deposed)
  4654    ID = bar
  4655    provider = provider.aws
  4656    Deposed ID 1 = foo
  4657  	`)
  4658  
  4659  	createdInstanceId = "baz"
  4660  	ctx = testContext2(t, &ContextOpts{
  4661  		Module:           m,
  4662  		ProviderResolver: ResourceProviderResolverFixed(ps),
  4663  		State:            state,
  4664  	})
  4665  
  4666  	if _, err := ctx.Plan(); err != nil {
  4667  		t.Fatalf("err: %s", err)
  4668  	}
  4669  
  4670  	// We're replacing the primary instance once again. Destroy is _still_
  4671  	// broken, so the Deposed list gets longer
  4672  	state, err = ctx.Apply()
  4673  	if err == nil {
  4674  		t.Fatal("should have error")
  4675  	}
  4676  
  4677  	checkStateString(t, state, `
  4678  aws_instance.web: (2 deposed)
  4679    ID = baz
  4680    provider = provider.aws
  4681    Deposed ID 1 = foo
  4682    Deposed ID 2 = bar
  4683  	`)
  4684  
  4685  	// Destroy partially fixed!
  4686  	destroyFunc = func(is *InstanceState) (*InstanceState, error) {
  4687  		if is.ID == "foo" || is.ID == "baz" {
  4688  			return nil, nil
  4689  		} else {
  4690  			return is, fmt.Errorf("destroy partially failed")
  4691  		}
  4692  	}
  4693  
  4694  	createdInstanceId = "qux"
  4695  	if _, err := ctx.Plan(); err != nil {
  4696  		t.Fatalf("err: %s", err)
  4697  	}
  4698  	state, err = ctx.Apply()
  4699  	// Expect error because 1/2 of Deposed destroys failed
  4700  	if err == nil {
  4701  		t.Fatal("should have error")
  4702  	}
  4703  
  4704  	// foo and baz are now gone, bar sticks around
  4705  	checkStateString(t, state, `
  4706  aws_instance.web: (1 deposed)
  4707    ID = qux
  4708    provider = provider.aws
  4709    Deposed ID 1 = bar
  4710  	`)
  4711  
  4712  	// Destroy working fully!
  4713  	destroyFunc = func(is *InstanceState) (*InstanceState, error) {
  4714  		return nil, nil
  4715  	}
  4716  
  4717  	createdInstanceId = "quux"
  4718  	if _, err := ctx.Plan(); err != nil {
  4719  		t.Fatalf("err: %s", err)
  4720  	}
  4721  	state, err = ctx.Apply()
  4722  	if err != nil {
  4723  		t.Fatal("should not have error:", err)
  4724  	}
  4725  
  4726  	// And finally the state is clean
  4727  	checkStateString(t, state, `
  4728  aws_instance.web:
  4729    ID = quux
  4730    provider = provider.aws
  4731  	`)
  4732  }
  4733  
  4734  // Verify that a normal provisioner with on_failure "continue" set won't
  4735  // taint the resource and continues executing.
  4736  func TestContext2Apply_provisionerFailContinue(t *testing.T) {
  4737  	m := testModule(t, "apply-provisioner-fail-continue")
  4738  	p := testProvider("aws")
  4739  	pr := testProvisioner()
  4740  	p.ApplyFn = testApplyFn
  4741  	p.DiffFn = testDiffFn
  4742  
  4743  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  4744  		return fmt.Errorf("provisioner error")
  4745  	}
  4746  
  4747  	ctx := testContext2(t, &ContextOpts{
  4748  		Module: m,
  4749  		ProviderResolver: ResourceProviderResolverFixed(
  4750  			map[string]ResourceProviderFactory{
  4751  				"aws": testProviderFuncFixed(p),
  4752  			},
  4753  		),
  4754  		Provisioners: map[string]ResourceProvisionerFactory{
  4755  			"shell": testProvisionerFuncFixed(pr),
  4756  		},
  4757  	})
  4758  
  4759  	if _, err := ctx.Plan(); err != nil {
  4760  		t.Fatalf("err: %s", err)
  4761  	}
  4762  
  4763  	state, err := ctx.Apply()
  4764  	if err != nil {
  4765  		t.Fatalf("err: %s", err)
  4766  	}
  4767  
  4768  	checkStateString(t, state, `
  4769  aws_instance.foo:
  4770    ID = foo
  4771    provider = provider.aws
  4772    foo = bar
  4773    type = aws_instance
  4774    `)
  4775  
  4776  	// Verify apply was invoked
  4777  	if !pr.ApplyCalled {
  4778  		t.Fatalf("provisioner not invoked")
  4779  	}
  4780  }
  4781  
  4782  // Verify that a normal provisioner with on_failure "continue" records
  4783  // the error with the hook.
  4784  func TestContext2Apply_provisionerFailContinueHook(t *testing.T) {
  4785  	h := new(MockHook)
  4786  	m := testModule(t, "apply-provisioner-fail-continue")
  4787  	p := testProvider("aws")
  4788  	pr := testProvisioner()
  4789  	p.ApplyFn = testApplyFn
  4790  	p.DiffFn = testDiffFn
  4791  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  4792  		return fmt.Errorf("provisioner error")
  4793  	}
  4794  
  4795  	ctx := testContext2(t, &ContextOpts{
  4796  		Module: m,
  4797  		Hooks:  []Hook{h},
  4798  		ProviderResolver: ResourceProviderResolverFixed(
  4799  			map[string]ResourceProviderFactory{
  4800  				"aws": testProviderFuncFixed(p),
  4801  			},
  4802  		),
  4803  		Provisioners: map[string]ResourceProvisionerFactory{
  4804  			"shell": testProvisionerFuncFixed(pr),
  4805  		},
  4806  	})
  4807  
  4808  	if _, err := ctx.Plan(); err != nil {
  4809  		t.Fatalf("err: %s", err)
  4810  	}
  4811  
  4812  	if _, err := ctx.Apply(); err != nil {
  4813  		t.Fatalf("err: %s", err)
  4814  	}
  4815  
  4816  	if !h.PostProvisionCalled {
  4817  		t.Fatal("PostProvision not called")
  4818  	}
  4819  	if h.PostProvisionErrorArg == nil {
  4820  		t.Fatal("should have error")
  4821  	}
  4822  }
  4823  
  4824  func TestContext2Apply_provisionerDestroy(t *testing.T) {
  4825  	m := testModule(t, "apply-provisioner-destroy")
  4826  	p := testProvider("aws")
  4827  	pr := testProvisioner()
  4828  	p.ApplyFn = testApplyFn
  4829  	p.DiffFn = testDiffFn
  4830  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  4831  		val, ok := c.Config["foo"]
  4832  		if !ok || val != "destroy" {
  4833  			t.Fatalf("bad value for foo: %v %#v", val, c)
  4834  		}
  4835  
  4836  		return nil
  4837  	}
  4838  
  4839  	state := &State{
  4840  		Modules: []*ModuleState{
  4841  			&ModuleState{
  4842  				Path: rootModulePath,
  4843  				Resources: map[string]*ResourceState{
  4844  					"aws_instance.foo": &ResourceState{
  4845  						Type: "aws_instance",
  4846  						Primary: &InstanceState{
  4847  							ID: "bar",
  4848  						},
  4849  					},
  4850  				},
  4851  			},
  4852  		},
  4853  	}
  4854  
  4855  	ctx := testContext2(t, &ContextOpts{
  4856  		Module:  m,
  4857  		State:   state,
  4858  		Destroy: true,
  4859  		ProviderResolver: ResourceProviderResolverFixed(
  4860  			map[string]ResourceProviderFactory{
  4861  				"aws": testProviderFuncFixed(p),
  4862  			},
  4863  		),
  4864  		Provisioners: map[string]ResourceProvisionerFactory{
  4865  			"shell": testProvisionerFuncFixed(pr),
  4866  		},
  4867  	})
  4868  
  4869  	if _, err := ctx.Plan(); err != nil {
  4870  		t.Fatalf("err: %s", err)
  4871  	}
  4872  
  4873  	state, err := ctx.Apply()
  4874  	if err != nil {
  4875  		t.Fatalf("err: %s", err)
  4876  	}
  4877  
  4878  	checkStateString(t, state, `<no state>`)
  4879  
  4880  	// Verify apply was invoked
  4881  	if !pr.ApplyCalled {
  4882  		t.Fatalf("provisioner not invoked")
  4883  	}
  4884  }
  4885  
  4886  // Verify that on destroy provisioner failure, nothing happens to the instance
  4887  func TestContext2Apply_provisionerDestroyFail(t *testing.T) {
  4888  	m := testModule(t, "apply-provisioner-destroy")
  4889  	p := testProvider("aws")
  4890  	pr := testProvisioner()
  4891  	p.ApplyFn = testApplyFn
  4892  	p.DiffFn = testDiffFn
  4893  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  4894  		return fmt.Errorf("provisioner error")
  4895  	}
  4896  
  4897  	state := &State{
  4898  		Modules: []*ModuleState{
  4899  			&ModuleState{
  4900  				Path: rootModulePath,
  4901  				Resources: map[string]*ResourceState{
  4902  					"aws_instance.foo": &ResourceState{
  4903  						Type: "aws_instance",
  4904  						Primary: &InstanceState{
  4905  							ID: "bar",
  4906  						},
  4907  					},
  4908  				},
  4909  			},
  4910  		},
  4911  	}
  4912  
  4913  	ctx := testContext2(t, &ContextOpts{
  4914  		Module:  m,
  4915  		State:   state,
  4916  		Destroy: true,
  4917  		ProviderResolver: ResourceProviderResolverFixed(
  4918  			map[string]ResourceProviderFactory{
  4919  				"aws": testProviderFuncFixed(p),
  4920  			},
  4921  		),
  4922  		Provisioners: map[string]ResourceProvisionerFactory{
  4923  			"shell": testProvisionerFuncFixed(pr),
  4924  		},
  4925  	})
  4926  
  4927  	if _, err := ctx.Plan(); err != nil {
  4928  		t.Fatalf("err: %s", err)
  4929  	}
  4930  
  4931  	state, err := ctx.Apply()
  4932  	if err == nil {
  4933  		t.Fatal("should error")
  4934  	}
  4935  
  4936  	checkStateString(t, state, `
  4937  aws_instance.foo:
  4938    ID = bar
  4939  	`)
  4940  
  4941  	// Verify apply was invoked
  4942  	if !pr.ApplyCalled {
  4943  		t.Fatalf("provisioner not invoked")
  4944  	}
  4945  }
  4946  
  4947  // Verify that on destroy provisioner failure with "continue" that
  4948  // we continue to the next provisioner.
  4949  func TestContext2Apply_provisionerDestroyFailContinue(t *testing.T) {
  4950  	m := testModule(t, "apply-provisioner-destroy-continue")
  4951  	p := testProvider("aws")
  4952  	pr := testProvisioner()
  4953  	p.ApplyFn = testApplyFn
  4954  	p.DiffFn = testDiffFn
  4955  
  4956  	var l sync.Mutex
  4957  	var calls []string
  4958  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  4959  		val, ok := c.Config["foo"]
  4960  		if !ok {
  4961  			t.Fatalf("bad value for foo: %v %#v", val, c)
  4962  		}
  4963  
  4964  		l.Lock()
  4965  		defer l.Unlock()
  4966  		calls = append(calls, val.(string))
  4967  		return fmt.Errorf("provisioner error")
  4968  	}
  4969  
  4970  	state := &State{
  4971  		Modules: []*ModuleState{
  4972  			&ModuleState{
  4973  				Path: rootModulePath,
  4974  				Resources: map[string]*ResourceState{
  4975  					"aws_instance.foo": &ResourceState{
  4976  						Type: "aws_instance",
  4977  						Primary: &InstanceState{
  4978  							ID: "bar",
  4979  						},
  4980  					},
  4981  				},
  4982  			},
  4983  		},
  4984  	}
  4985  
  4986  	ctx := testContext2(t, &ContextOpts{
  4987  		Module:  m,
  4988  		State:   state,
  4989  		Destroy: true,
  4990  		ProviderResolver: ResourceProviderResolverFixed(
  4991  			map[string]ResourceProviderFactory{
  4992  				"aws": testProviderFuncFixed(p),
  4993  			},
  4994  		),
  4995  		Provisioners: map[string]ResourceProvisionerFactory{
  4996  			"shell": testProvisionerFuncFixed(pr),
  4997  		},
  4998  	})
  4999  
  5000  	if _, err := ctx.Plan(); err != nil {
  5001  		t.Fatalf("err: %s", err)
  5002  	}
  5003  
  5004  	state, err := ctx.Apply()
  5005  	if err != nil {
  5006  		t.Fatalf("err: %s", err)
  5007  	}
  5008  
  5009  	checkStateString(t, state, `<no state>`)
  5010  
  5011  	// Verify apply was invoked
  5012  	if !pr.ApplyCalled {
  5013  		t.Fatalf("provisioner not invoked")
  5014  	}
  5015  
  5016  	expected := []string{"one", "two"}
  5017  	if !reflect.DeepEqual(calls, expected) {
  5018  		t.Fatalf("bad: %#v", calls)
  5019  	}
  5020  }
  5021  
  5022  // Verify that on destroy provisioner failure with "continue" that
  5023  // we continue to the next provisioner. But if the next provisioner defines
  5024  // to fail, then we fail after running it.
  5025  func TestContext2Apply_provisionerDestroyFailContinueFail(t *testing.T) {
  5026  	m := testModule(t, "apply-provisioner-destroy-fail")
  5027  	p := testProvider("aws")
  5028  	pr := testProvisioner()
  5029  	p.ApplyFn = testApplyFn
  5030  	p.DiffFn = testDiffFn
  5031  
  5032  	var l sync.Mutex
  5033  	var calls []string
  5034  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  5035  		val, ok := c.Config["foo"]
  5036  		if !ok {
  5037  			t.Fatalf("bad value for foo: %v %#v", val, c)
  5038  		}
  5039  
  5040  		l.Lock()
  5041  		defer l.Unlock()
  5042  		calls = append(calls, val.(string))
  5043  		return fmt.Errorf("provisioner error")
  5044  	}
  5045  
  5046  	state := &State{
  5047  		Modules: []*ModuleState{
  5048  			&ModuleState{
  5049  				Path: rootModulePath,
  5050  				Resources: map[string]*ResourceState{
  5051  					"aws_instance.foo": &ResourceState{
  5052  						Type: "aws_instance",
  5053  						Primary: &InstanceState{
  5054  							ID: "bar",
  5055  						},
  5056  					},
  5057  				},
  5058  			},
  5059  		},
  5060  	}
  5061  
  5062  	ctx := testContext2(t, &ContextOpts{
  5063  		Module:  m,
  5064  		State:   state,
  5065  		Destroy: true,
  5066  		ProviderResolver: ResourceProviderResolverFixed(
  5067  			map[string]ResourceProviderFactory{
  5068  				"aws": testProviderFuncFixed(p),
  5069  			},
  5070  		),
  5071  		Provisioners: map[string]ResourceProvisionerFactory{
  5072  			"shell": testProvisionerFuncFixed(pr),
  5073  		},
  5074  	})
  5075  
  5076  	if _, err := ctx.Plan(); err != nil {
  5077  		t.Fatalf("err: %s", err)
  5078  	}
  5079  
  5080  	state, err := ctx.Apply()
  5081  	if err == nil {
  5082  		t.Fatal("should error")
  5083  	}
  5084  
  5085  	checkStateString(t, state, `
  5086  aws_instance.foo:
  5087    ID = bar
  5088    `)
  5089  
  5090  	// Verify apply was invoked
  5091  	if !pr.ApplyCalled {
  5092  		t.Fatalf("provisioner not invoked")
  5093  	}
  5094  
  5095  	expected := []string{"one", "two"}
  5096  	if !reflect.DeepEqual(calls, expected) {
  5097  		t.Fatalf("bad: %#v", calls)
  5098  	}
  5099  }
  5100  
  5101  // Verify destroy provisioners are not run for tainted instances.
  5102  func TestContext2Apply_provisionerDestroyTainted(t *testing.T) {
  5103  	m := testModule(t, "apply-provisioner-destroy")
  5104  	p := testProvider("aws")
  5105  	pr := testProvisioner()
  5106  	p.ApplyFn = testApplyFn
  5107  	p.DiffFn = testDiffFn
  5108  
  5109  	destroyCalled := false
  5110  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  5111  		expected := "create"
  5112  		if rs.ID == "bar" {
  5113  			destroyCalled = true
  5114  			return nil
  5115  		}
  5116  
  5117  		val, ok := c.Config["foo"]
  5118  		if !ok || val != expected {
  5119  			t.Fatalf("bad value for foo: %v %#v", val, c)
  5120  		}
  5121  
  5122  		return nil
  5123  	}
  5124  
  5125  	state := &State{
  5126  		Modules: []*ModuleState{
  5127  			&ModuleState{
  5128  				Path: rootModulePath,
  5129  				Resources: map[string]*ResourceState{
  5130  					"aws_instance.foo": &ResourceState{
  5131  						Type: "aws_instance",
  5132  						Primary: &InstanceState{
  5133  							ID:      "bar",
  5134  							Tainted: true,
  5135  						},
  5136  					},
  5137  				},
  5138  			},
  5139  		},
  5140  	}
  5141  
  5142  	ctx := testContext2(t, &ContextOpts{
  5143  		Module: m,
  5144  		State:  state,
  5145  		ProviderResolver: ResourceProviderResolverFixed(
  5146  			map[string]ResourceProviderFactory{
  5147  				"aws": testProviderFuncFixed(p),
  5148  			},
  5149  		),
  5150  		Provisioners: map[string]ResourceProvisionerFactory{
  5151  			"shell": testProvisionerFuncFixed(pr),
  5152  		},
  5153  	})
  5154  
  5155  	if _, err := ctx.Plan(); err != nil {
  5156  		t.Fatalf("err: %s", err)
  5157  	}
  5158  
  5159  	state, err := ctx.Apply()
  5160  	if err != nil {
  5161  		t.Fatalf("err: %s", err)
  5162  	}
  5163  
  5164  	checkStateString(t, state, `
  5165  aws_instance.foo:
  5166    ID = foo
  5167    provider = provider.aws
  5168    foo = bar
  5169    type = aws_instance
  5170  	`)
  5171  
  5172  	// Verify apply was invoked
  5173  	if !pr.ApplyCalled {
  5174  		t.Fatalf("provisioner not invoked")
  5175  	}
  5176  
  5177  	if destroyCalled {
  5178  		t.Fatal("destroy should not be called")
  5179  	}
  5180  }
  5181  
  5182  func TestContext2Apply_provisionerDestroyModule(t *testing.T) {
  5183  	m := testModule(t, "apply-provisioner-destroy-module")
  5184  	p := testProvider("aws")
  5185  	pr := testProvisioner()
  5186  	p.ApplyFn = testApplyFn
  5187  	p.DiffFn = testDiffFn
  5188  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  5189  		val, ok := c.Config["foo"]
  5190  		if !ok || val != "value" {
  5191  			t.Fatalf("bad value for foo: %v %#v", val, c)
  5192  		}
  5193  
  5194  		return nil
  5195  	}
  5196  
  5197  	state := &State{
  5198  		Modules: []*ModuleState{
  5199  			&ModuleState{
  5200  				Path: []string{"root", "child"},
  5201  				Resources: map[string]*ResourceState{
  5202  					"aws_instance.foo": &ResourceState{
  5203  						Type: "aws_instance",
  5204  						Primary: &InstanceState{
  5205  							ID: "bar",
  5206  						},
  5207  					},
  5208  				},
  5209  			},
  5210  		},
  5211  	}
  5212  
  5213  	ctx := testContext2(t, &ContextOpts{
  5214  		Module:  m,
  5215  		State:   state,
  5216  		Destroy: true,
  5217  		ProviderResolver: ResourceProviderResolverFixed(
  5218  			map[string]ResourceProviderFactory{
  5219  				"aws": testProviderFuncFixed(p),
  5220  			},
  5221  		),
  5222  		Provisioners: map[string]ResourceProvisionerFactory{
  5223  			"shell": testProvisionerFuncFixed(pr),
  5224  		},
  5225  	})
  5226  
  5227  	if _, err := ctx.Plan(); err != nil {
  5228  		t.Fatalf("err: %s", err)
  5229  	}
  5230  
  5231  	state, err := ctx.Apply()
  5232  	if err != nil {
  5233  		t.Fatalf("err: %s", err)
  5234  	}
  5235  
  5236  	checkStateString(t, state, `
  5237  module.child:
  5238    <no state>`)
  5239  
  5240  	// Verify apply was invoked
  5241  	if !pr.ApplyCalled {
  5242  		t.Fatalf("provisioner not invoked")
  5243  	}
  5244  }
  5245  
  5246  func TestContext2Apply_provisionerDestroyRef(t *testing.T) {
  5247  	m := testModule(t, "apply-provisioner-destroy-ref")
  5248  	p := testProvider("aws")
  5249  	pr := testProvisioner()
  5250  	p.ApplyFn = testApplyFn
  5251  	p.DiffFn = testDiffFn
  5252  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  5253  		val, ok := c.Config["foo"]
  5254  		if !ok || val != "hello" {
  5255  			return fmt.Errorf("bad value for foo: %v %#v", val, c)
  5256  		}
  5257  
  5258  		return nil
  5259  	}
  5260  
  5261  	state := &State{
  5262  		Modules: []*ModuleState{
  5263  			&ModuleState{
  5264  				Path: rootModulePath,
  5265  				Resources: map[string]*ResourceState{
  5266  					"aws_instance.bar": &ResourceState{
  5267  						Type: "aws_instance",
  5268  						Primary: &InstanceState{
  5269  							ID: "bar",
  5270  							Attributes: map[string]string{
  5271  								"key": "hello",
  5272  							},
  5273  						},
  5274  					},
  5275  
  5276  					"aws_instance.foo": &ResourceState{
  5277  						Type: "aws_instance",
  5278  						Primary: &InstanceState{
  5279  							ID: "bar",
  5280  						},
  5281  					},
  5282  				},
  5283  			},
  5284  		},
  5285  	}
  5286  
  5287  	ctx := testContext2(t, &ContextOpts{
  5288  		Module:  m,
  5289  		State:   state,
  5290  		Destroy: true,
  5291  		ProviderResolver: ResourceProviderResolverFixed(
  5292  			map[string]ResourceProviderFactory{
  5293  				"aws": testProviderFuncFixed(p),
  5294  			},
  5295  		),
  5296  		Provisioners: map[string]ResourceProvisionerFactory{
  5297  			"shell": testProvisionerFuncFixed(pr),
  5298  		},
  5299  	})
  5300  
  5301  	if _, err := ctx.Plan(); err != nil {
  5302  		t.Fatalf("err: %s", err)
  5303  	}
  5304  
  5305  	state, err := ctx.Apply()
  5306  	if err != nil {
  5307  		t.Fatalf("err: %s", err)
  5308  	}
  5309  
  5310  	checkStateString(t, state, `<no state>`)
  5311  
  5312  	// Verify apply was invoked
  5313  	if !pr.ApplyCalled {
  5314  		t.Fatalf("provisioner not invoked")
  5315  	}
  5316  }
  5317  
  5318  // Test that a destroy provisioner referencing an invalid key errors.
  5319  func TestContext2Apply_provisionerDestroyRefInvalid(t *testing.T) {
  5320  	m := testModule(t, "apply-provisioner-destroy-ref")
  5321  	p := testProvider("aws")
  5322  	pr := testProvisioner()
  5323  	p.ApplyFn = testApplyFn
  5324  	p.DiffFn = testDiffFn
  5325  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  5326  		return nil
  5327  	}
  5328  
  5329  	state := &State{
  5330  		Modules: []*ModuleState{
  5331  			&ModuleState{
  5332  				Path: rootModulePath,
  5333  				Resources: map[string]*ResourceState{
  5334  					"aws_instance.bar": &ResourceState{
  5335  						Type: "aws_instance",
  5336  						Primary: &InstanceState{
  5337  							ID: "bar",
  5338  						},
  5339  					},
  5340  
  5341  					"aws_instance.foo": &ResourceState{
  5342  						Type: "aws_instance",
  5343  						Primary: &InstanceState{
  5344  							ID: "bar",
  5345  						},
  5346  					},
  5347  				},
  5348  			},
  5349  		},
  5350  	}
  5351  
  5352  	ctx := testContext2(t, &ContextOpts{
  5353  		Module:  m,
  5354  		State:   state,
  5355  		Destroy: true,
  5356  		ProviderResolver: ResourceProviderResolverFixed(
  5357  			map[string]ResourceProviderFactory{
  5358  				"aws": testProviderFuncFixed(p),
  5359  			},
  5360  		),
  5361  		Provisioners: map[string]ResourceProvisionerFactory{
  5362  			"shell": testProvisionerFuncFixed(pr),
  5363  		},
  5364  	})
  5365  
  5366  	if _, err := ctx.Plan(); err != nil {
  5367  		t.Fatalf("err: %s", err)
  5368  	}
  5369  
  5370  	if _, err := ctx.Apply(); err == nil {
  5371  		t.Fatal("expected error")
  5372  	}
  5373  }
  5374  
  5375  func TestContext2Apply_provisionerResourceRef(t *testing.T) {
  5376  	m := testModule(t, "apply-provisioner-resource-ref")
  5377  	p := testProvider("aws")
  5378  	pr := testProvisioner()
  5379  	p.ApplyFn = testApplyFn
  5380  	p.DiffFn = testDiffFn
  5381  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  5382  		val, ok := c.Config["foo"]
  5383  		if !ok || val != "2" {
  5384  			t.Fatalf("bad value for foo: %v %#v", val, c)
  5385  		}
  5386  
  5387  		return nil
  5388  	}
  5389  
  5390  	ctx := testContext2(t, &ContextOpts{
  5391  		Module: m,
  5392  		ProviderResolver: ResourceProviderResolverFixed(
  5393  			map[string]ResourceProviderFactory{
  5394  				"aws": testProviderFuncFixed(p),
  5395  			},
  5396  		),
  5397  		Provisioners: map[string]ResourceProvisionerFactory{
  5398  			"shell": testProvisionerFuncFixed(pr),
  5399  		},
  5400  	})
  5401  
  5402  	if _, err := ctx.Plan(); err != nil {
  5403  		t.Fatalf("err: %s", err)
  5404  	}
  5405  
  5406  	state, err := ctx.Apply()
  5407  	if err != nil {
  5408  		t.Fatalf("err: %s", err)
  5409  	}
  5410  
  5411  	actual := strings.TrimSpace(state.String())
  5412  	expected := strings.TrimSpace(testTerraformApplyProvisionerResourceRefStr)
  5413  	if actual != expected {
  5414  		t.Fatalf("bad: \n%s", actual)
  5415  	}
  5416  
  5417  	// Verify apply was invoked
  5418  	if !pr.ApplyCalled {
  5419  		t.Fatalf("provisioner not invoked")
  5420  	}
  5421  }
  5422  
  5423  func TestContext2Apply_provisionerSelfRef(t *testing.T) {
  5424  	m := testModule(t, "apply-provisioner-self-ref")
  5425  	p := testProvider("aws")
  5426  	pr := testProvisioner()
  5427  	p.ApplyFn = testApplyFn
  5428  	p.DiffFn = testDiffFn
  5429  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  5430  		val, ok := c.Config["command"]
  5431  		if !ok || val != "bar" {
  5432  			t.Fatalf("bad value for command: %v %#v", val, c)
  5433  		}
  5434  
  5435  		return nil
  5436  	}
  5437  
  5438  	ctx := testContext2(t, &ContextOpts{
  5439  		Module: m,
  5440  		ProviderResolver: ResourceProviderResolverFixed(
  5441  			map[string]ResourceProviderFactory{
  5442  				"aws": testProviderFuncFixed(p),
  5443  			},
  5444  		),
  5445  		Provisioners: map[string]ResourceProvisionerFactory{
  5446  			"shell": testProvisionerFuncFixed(pr),
  5447  		},
  5448  	})
  5449  
  5450  	if _, err := ctx.Plan(); err != nil {
  5451  		t.Fatalf("err: %s", err)
  5452  	}
  5453  
  5454  	state, err := ctx.Apply()
  5455  	if err != nil {
  5456  		t.Fatalf("err: %s", err)
  5457  	}
  5458  
  5459  	actual := strings.TrimSpace(state.String())
  5460  	expected := strings.TrimSpace(testTerraformApplyProvisionerSelfRefStr)
  5461  	if actual != expected {
  5462  		t.Fatalf("bad: \n%s", actual)
  5463  	}
  5464  
  5465  	// Verify apply was invoked
  5466  	if !pr.ApplyCalled {
  5467  		t.Fatalf("provisioner not invoked")
  5468  	}
  5469  }
  5470  
  5471  func TestContext2Apply_provisionerMultiSelfRef(t *testing.T) {
  5472  	var lock sync.Mutex
  5473  	commands := make([]string, 0, 5)
  5474  
  5475  	m := testModule(t, "apply-provisioner-multi-self-ref")
  5476  	p := testProvider("aws")
  5477  	pr := testProvisioner()
  5478  	p.ApplyFn = testApplyFn
  5479  	p.DiffFn = testDiffFn
  5480  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  5481  		lock.Lock()
  5482  		defer lock.Unlock()
  5483  
  5484  		val, ok := c.Config["command"]
  5485  		if !ok {
  5486  			t.Fatalf("bad value for command: %v %#v", val, c)
  5487  		}
  5488  
  5489  		commands = append(commands, val.(string))
  5490  		return nil
  5491  	}
  5492  
  5493  	ctx := testContext2(t, &ContextOpts{
  5494  		Module: m,
  5495  		ProviderResolver: ResourceProviderResolverFixed(
  5496  			map[string]ResourceProviderFactory{
  5497  				"aws": testProviderFuncFixed(p),
  5498  			},
  5499  		),
  5500  		Provisioners: map[string]ResourceProvisionerFactory{
  5501  			"shell": testProvisionerFuncFixed(pr),
  5502  		},
  5503  	})
  5504  
  5505  	if _, err := ctx.Plan(); err != nil {
  5506  		t.Fatalf("err: %s", err)
  5507  	}
  5508  
  5509  	state, err := ctx.Apply()
  5510  	if err != nil {
  5511  		t.Fatalf("err: %s", err)
  5512  	}
  5513  
  5514  	actual := strings.TrimSpace(state.String())
  5515  	expected := strings.TrimSpace(testTerraformApplyProvisionerMultiSelfRefStr)
  5516  	if actual != expected {
  5517  		t.Fatalf("bad: \n%s", actual)
  5518  	}
  5519  
  5520  	// Verify apply was invoked
  5521  	if !pr.ApplyCalled {
  5522  		t.Fatalf("provisioner not invoked")
  5523  	}
  5524  
  5525  	// Verify our result
  5526  	sort.Strings(commands)
  5527  	expectedCommands := []string{"number 0", "number 1", "number 2"}
  5528  	if !reflect.DeepEqual(commands, expectedCommands) {
  5529  		t.Fatalf("bad: %#v", commands)
  5530  	}
  5531  }
  5532  
  5533  func TestContext2Apply_provisionerMultiSelfRefSingle(t *testing.T) {
  5534  	var lock sync.Mutex
  5535  	order := make([]string, 0, 5)
  5536  
  5537  	m := testModule(t, "apply-provisioner-multi-self-ref-single")
  5538  	p := testProvider("aws")
  5539  	pr := testProvisioner()
  5540  	p.ApplyFn = testApplyFn
  5541  	p.DiffFn = testDiffFn
  5542  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  5543  		lock.Lock()
  5544  		defer lock.Unlock()
  5545  
  5546  		val, ok := c.Config["order"]
  5547  		if !ok {
  5548  			t.Fatalf("bad value for order: %v %#v", val, c)
  5549  		}
  5550  
  5551  		order = append(order, val.(string))
  5552  		return nil
  5553  	}
  5554  
  5555  	ctx := testContext2(t, &ContextOpts{
  5556  		Module: m,
  5557  		ProviderResolver: ResourceProviderResolverFixed(
  5558  			map[string]ResourceProviderFactory{
  5559  				"aws": testProviderFuncFixed(p),
  5560  			},
  5561  		),
  5562  		Provisioners: map[string]ResourceProvisionerFactory{
  5563  			"shell": testProvisionerFuncFixed(pr),
  5564  		},
  5565  	})
  5566  
  5567  	if _, err := ctx.Plan(); 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  	actual := strings.TrimSpace(state.String())
  5577  	expected := strings.TrimSpace(testTerraformApplyProvisionerMultiSelfRefSingleStr)
  5578  	if actual != expected {
  5579  		t.Fatalf("bad: \n%s", actual)
  5580  	}
  5581  
  5582  	// Verify apply was invoked
  5583  	if !pr.ApplyCalled {
  5584  		t.Fatalf("provisioner not invoked")
  5585  	}
  5586  
  5587  	// Verify our result
  5588  	sort.Strings(order)
  5589  	expectedOrder := []string{"0", "1", "2"}
  5590  	if !reflect.DeepEqual(order, expectedOrder) {
  5591  		t.Fatalf("bad: %#v", order)
  5592  	}
  5593  }
  5594  
  5595  func TestContext2Apply_provisionerMultiSelfRefCount(t *testing.T) {
  5596  	var lock sync.Mutex
  5597  	commands := make([]string, 0, 5)
  5598  
  5599  	m := testModule(t, "apply-provisioner-multi-self-ref-count")
  5600  	p := testProvider("aws")
  5601  	pr := testProvisioner()
  5602  	p.ApplyFn = testApplyFn
  5603  	p.DiffFn = testDiffFn
  5604  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  5605  		lock.Lock()
  5606  		defer lock.Unlock()
  5607  
  5608  		val, ok := c.Config["command"]
  5609  		if !ok {
  5610  			t.Fatalf("bad value for command: %v %#v", val, c)
  5611  		}
  5612  
  5613  		commands = append(commands, val.(string))
  5614  		return nil
  5615  	}
  5616  
  5617  	ctx := testContext2(t, &ContextOpts{
  5618  		Module: m,
  5619  		ProviderResolver: ResourceProviderResolverFixed(
  5620  			map[string]ResourceProviderFactory{
  5621  				"aws": testProviderFuncFixed(p),
  5622  			},
  5623  		),
  5624  		Provisioners: map[string]ResourceProvisionerFactory{
  5625  			"shell": testProvisionerFuncFixed(pr),
  5626  		},
  5627  	})
  5628  
  5629  	if _, err := ctx.Plan(); err != nil {
  5630  		t.Fatalf("err: %s", err)
  5631  	}
  5632  
  5633  	if _, err := ctx.Apply(); err != nil {
  5634  		t.Fatalf("err: %s", err)
  5635  	}
  5636  
  5637  	// Verify apply was invoked
  5638  	if !pr.ApplyCalled {
  5639  		t.Fatalf("provisioner not invoked")
  5640  	}
  5641  
  5642  	// Verify our result
  5643  	sort.Strings(commands)
  5644  	expectedCommands := []string{"3", "3", "3"}
  5645  	if !reflect.DeepEqual(commands, expectedCommands) {
  5646  		t.Fatalf("bad: %#v", commands)
  5647  	}
  5648  }
  5649  
  5650  func TestContext2Apply_provisionerExplicitSelfRef(t *testing.T) {
  5651  	m := testModule(t, "apply-provisioner-explicit-self-ref")
  5652  	p := testProvider("aws")
  5653  	pr := testProvisioner()
  5654  	p.ApplyFn = testApplyFn
  5655  	p.DiffFn = testDiffFn
  5656  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  5657  		val, ok := c.Config["command"]
  5658  		if !ok || val != "bar" {
  5659  			t.Fatalf("bad value for command: %v %#v", val, c)
  5660  		}
  5661  
  5662  		return nil
  5663  	}
  5664  
  5665  	var state *State
  5666  	{
  5667  		ctx := testContext2(t, &ContextOpts{
  5668  			Module: m,
  5669  			ProviderResolver: ResourceProviderResolverFixed(
  5670  				map[string]ResourceProviderFactory{
  5671  					"aws": testProviderFuncFixed(p),
  5672  				},
  5673  			),
  5674  			Provisioners: map[string]ResourceProvisionerFactory{
  5675  				"shell": testProvisionerFuncFixed(pr),
  5676  			},
  5677  		})
  5678  
  5679  		_, err := ctx.Plan()
  5680  		if err != nil {
  5681  			t.Fatalf("err: %s", err)
  5682  		}
  5683  
  5684  		state, err = ctx.Apply()
  5685  		if err != nil {
  5686  			t.Fatalf("err: %s", err)
  5687  		}
  5688  
  5689  		// Verify apply was invoked
  5690  		if !pr.ApplyCalled {
  5691  			t.Fatalf("provisioner not invoked")
  5692  		}
  5693  	}
  5694  
  5695  	{
  5696  		ctx := testContext2(t, &ContextOpts{
  5697  			Module:  m,
  5698  			Destroy: true,
  5699  			State:   state,
  5700  			ProviderResolver: ResourceProviderResolverFixed(
  5701  				map[string]ResourceProviderFactory{
  5702  					"aws": testProviderFuncFixed(p),
  5703  				},
  5704  			),
  5705  			Provisioners: map[string]ResourceProvisionerFactory{
  5706  				"shell": testProvisionerFuncFixed(pr),
  5707  			},
  5708  		})
  5709  
  5710  		_, err := ctx.Plan()
  5711  		if err != nil {
  5712  			t.Fatalf("err: %s", err)
  5713  		}
  5714  
  5715  		state, err = ctx.Apply()
  5716  		if err != nil {
  5717  			t.Fatalf("err: %s", err)
  5718  		}
  5719  
  5720  		checkStateString(t, state, `<no state>`)
  5721  	}
  5722  }
  5723  
  5724  // Provisioner should NOT run on a diff, only create
  5725  func TestContext2Apply_Provisioner_Diff(t *testing.T) {
  5726  	m := testModule(t, "apply-provisioner-diff")
  5727  	p := testProvider("aws")
  5728  	pr := testProvisioner()
  5729  	p.ApplyFn = testApplyFn
  5730  	p.DiffFn = testDiffFn
  5731  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  5732  		return nil
  5733  	}
  5734  	ctx := testContext2(t, &ContextOpts{
  5735  		Module: m,
  5736  		ProviderResolver: ResourceProviderResolverFixed(
  5737  			map[string]ResourceProviderFactory{
  5738  				"aws": testProviderFuncFixed(p),
  5739  			},
  5740  		),
  5741  		Provisioners: map[string]ResourceProvisionerFactory{
  5742  			"shell": testProvisionerFuncFixed(pr),
  5743  		},
  5744  	})
  5745  
  5746  	if _, err := ctx.Plan(); err != nil {
  5747  		t.Fatalf("err: %s", err)
  5748  	}
  5749  
  5750  	state, err := ctx.Apply()
  5751  	if err != nil {
  5752  		t.Fatalf("err: %s", err)
  5753  	}
  5754  
  5755  	actual := strings.TrimSpace(state.String())
  5756  	expected := strings.TrimSpace(testTerraformApplyProvisionerDiffStr)
  5757  	if actual != expected {
  5758  		t.Fatalf("bad: \n%s", actual)
  5759  	}
  5760  
  5761  	// Verify apply was invoked
  5762  	if !pr.ApplyCalled {
  5763  		t.Fatalf("provisioner not invoked")
  5764  	}
  5765  	pr.ApplyCalled = false
  5766  
  5767  	// Change the state to force a diff
  5768  	mod := state.RootModule()
  5769  	mod.Resources["aws_instance.bar"].Primary.Attributes["foo"] = "baz"
  5770  
  5771  	// Re-create context with state
  5772  	ctx = testContext2(t, &ContextOpts{
  5773  		Module: m,
  5774  		ProviderResolver: ResourceProviderResolverFixed(
  5775  			map[string]ResourceProviderFactory{
  5776  				"aws": testProviderFuncFixed(p),
  5777  			},
  5778  		),
  5779  		Provisioners: map[string]ResourceProvisionerFactory{
  5780  			"shell": testProvisionerFuncFixed(pr),
  5781  		},
  5782  		State: state,
  5783  	})
  5784  
  5785  	if _, err := ctx.Plan(); err != nil {
  5786  		t.Fatalf("err: %s", err)
  5787  	}
  5788  
  5789  	state2, err := ctx.Apply()
  5790  	if err != nil {
  5791  		t.Fatalf("err: %s", err)
  5792  	}
  5793  
  5794  	actual = strings.TrimSpace(state2.String())
  5795  	if actual != expected {
  5796  		t.Fatalf("bad: \n%s", actual)
  5797  	}
  5798  
  5799  	// Verify apply was NOT invoked
  5800  	if pr.ApplyCalled {
  5801  		t.Fatalf("provisioner invoked")
  5802  	}
  5803  }
  5804  
  5805  func TestContext2Apply_outputDiffVars(t *testing.T) {
  5806  	m := testModule(t, "apply-good")
  5807  	p := testProvider("aws")
  5808  	s := &State{
  5809  		Modules: []*ModuleState{
  5810  			&ModuleState{
  5811  				Path: rootModulePath,
  5812  				Resources: map[string]*ResourceState{
  5813  					"aws_instance.baz": &ResourceState{
  5814  						Type: "aws_instance",
  5815  						Primary: &InstanceState{
  5816  							ID: "bar",
  5817  						},
  5818  					},
  5819  				},
  5820  			},
  5821  		},
  5822  	}
  5823  	ctx := testContext2(t, &ContextOpts{
  5824  		Module: m,
  5825  		ProviderResolver: ResourceProviderResolverFixed(
  5826  			map[string]ResourceProviderFactory{
  5827  				"aws": testProviderFuncFixed(p),
  5828  			},
  5829  		),
  5830  		State: s,
  5831  	})
  5832  
  5833  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  5834  		for k, ad := range d.Attributes {
  5835  			if ad.NewComputed {
  5836  				return nil, fmt.Errorf("%s: computed", k)
  5837  			}
  5838  		}
  5839  
  5840  		result := s.MergeDiff(d)
  5841  		result.ID = "foo"
  5842  		return result, nil
  5843  	}
  5844  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  5845  		return &InstanceDiff{
  5846  			Attributes: map[string]*ResourceAttrDiff{
  5847  				"foo": &ResourceAttrDiff{
  5848  					NewComputed: true,
  5849  					Type:        DiffAttrOutput,
  5850  				},
  5851  				"bar": &ResourceAttrDiff{
  5852  					New: "baz",
  5853  				},
  5854  			},
  5855  		}, nil
  5856  	}
  5857  
  5858  	if _, err := ctx.Plan(); err != nil {
  5859  		t.Fatalf("err: %s", err)
  5860  	}
  5861  	if _, err := ctx.Apply(); err != nil {
  5862  		t.Fatalf("err: %s", err)
  5863  	}
  5864  }
  5865  
  5866  func TestContext2Apply_Provisioner_ConnInfo(t *testing.T) {
  5867  	m := testModule(t, "apply-provisioner-conninfo")
  5868  	p := testProvider("aws")
  5869  	pr := testProvisioner()
  5870  
  5871  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  5872  		if s.Ephemeral.ConnInfo == nil {
  5873  			t.Fatalf("ConnInfo not initialized")
  5874  		}
  5875  
  5876  		result, _ := testApplyFn(info, s, d)
  5877  		result.Ephemeral.ConnInfo = map[string]string{
  5878  			"type": "ssh",
  5879  			"host": "127.0.0.1",
  5880  			"port": "22",
  5881  		}
  5882  		return result, nil
  5883  	}
  5884  	p.DiffFn = testDiffFn
  5885  
  5886  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  5887  		conn := rs.Ephemeral.ConnInfo
  5888  		if conn["type"] != "telnet" {
  5889  			t.Fatalf("Bad: %#v", conn)
  5890  		}
  5891  		if conn["host"] != "127.0.0.1" {
  5892  			t.Fatalf("Bad: %#v", conn)
  5893  		}
  5894  		if conn["port"] != "2222" {
  5895  			t.Fatalf("Bad: %#v", conn)
  5896  		}
  5897  		if conn["user"] != "superuser" {
  5898  			t.Fatalf("Bad: %#v", conn)
  5899  		}
  5900  		if conn["pass"] != "test" {
  5901  			t.Fatalf("Bad: %#v", conn)
  5902  		}
  5903  
  5904  		return nil
  5905  	}
  5906  
  5907  	ctx := testContext2(t, &ContextOpts{
  5908  		Module: m,
  5909  		ProviderResolver: ResourceProviderResolverFixed(
  5910  			map[string]ResourceProviderFactory{
  5911  				"aws": testProviderFuncFixed(p),
  5912  			},
  5913  		),
  5914  		Provisioners: map[string]ResourceProvisionerFactory{
  5915  			"shell": testProvisionerFuncFixed(pr),
  5916  		},
  5917  		Variables: map[string]interface{}{
  5918  			"value": "1",
  5919  			"pass":  "test",
  5920  		},
  5921  	})
  5922  
  5923  	if _, err := ctx.Plan(); err != nil {
  5924  		t.Fatalf("err: %s", err)
  5925  	}
  5926  
  5927  	state, err := ctx.Apply()
  5928  	if err != nil {
  5929  		t.Fatalf("err: %s", err)
  5930  	}
  5931  
  5932  	actual := strings.TrimSpace(state.String())
  5933  	expected := strings.TrimSpace(testTerraformApplyProvisionerStr)
  5934  	if actual != expected {
  5935  		t.Fatalf("bad: \n%s", actual)
  5936  	}
  5937  
  5938  	// Verify apply was invoked
  5939  	if !pr.ApplyCalled {
  5940  		t.Fatalf("provisioner not invoked")
  5941  	}
  5942  }
  5943  
  5944  func TestContext2Apply_destroyX(t *testing.T) {
  5945  	m := testModule(t, "apply-destroy")
  5946  	h := new(HookRecordApplyOrder)
  5947  	p := testProvider("aws")
  5948  	p.ApplyFn = testApplyFn
  5949  	p.DiffFn = testDiffFn
  5950  	ctx := testContext2(t, &ContextOpts{
  5951  		Module: m,
  5952  		Hooks:  []Hook{h},
  5953  		ProviderResolver: ResourceProviderResolverFixed(
  5954  			map[string]ResourceProviderFactory{
  5955  				"aws": testProviderFuncFixed(p),
  5956  			},
  5957  		),
  5958  	})
  5959  
  5960  	// First plan and apply a create operation
  5961  	if _, err := ctx.Plan(); err != nil {
  5962  		t.Fatalf("err: %s", err)
  5963  	}
  5964  
  5965  	state, err := ctx.Apply()
  5966  	if err != nil {
  5967  		t.Fatalf("err: %s", err)
  5968  	}
  5969  
  5970  	// Next, plan and apply a destroy operation
  5971  	h.Active = true
  5972  	ctx = testContext2(t, &ContextOpts{
  5973  		Destroy: true,
  5974  		State:   state,
  5975  		Module:  m,
  5976  		Hooks:   []Hook{h},
  5977  		ProviderResolver: ResourceProviderResolverFixed(
  5978  			map[string]ResourceProviderFactory{
  5979  				"aws": testProviderFuncFixed(p),
  5980  			},
  5981  		),
  5982  	})
  5983  
  5984  	if _, err := ctx.Plan(); err != nil {
  5985  		t.Fatalf("err: %s", err)
  5986  	}
  5987  
  5988  	state, err = ctx.Apply()
  5989  	if err != nil {
  5990  		t.Fatalf("err: %s", err)
  5991  	}
  5992  
  5993  	// Test that things were destroyed
  5994  	actual := strings.TrimSpace(state.String())
  5995  	expected := strings.TrimSpace(testTerraformApplyDestroyStr)
  5996  	if actual != expected {
  5997  		t.Fatalf("bad: \n%s", actual)
  5998  	}
  5999  
  6000  	// Test that things were destroyed _in the right order_
  6001  	expected2 := []string{"aws_instance.bar", "aws_instance.foo"}
  6002  	actual2 := h.IDs
  6003  	if !reflect.DeepEqual(actual2, expected2) {
  6004  		t.Fatalf("expected: %#v\n\ngot:%#v", expected2, actual2)
  6005  	}
  6006  }
  6007  
  6008  func TestContext2Apply_destroyOrder(t *testing.T) {
  6009  	m := testModule(t, "apply-destroy")
  6010  	h := new(HookRecordApplyOrder)
  6011  	p := testProvider("aws")
  6012  	p.ApplyFn = testApplyFn
  6013  	p.DiffFn = testDiffFn
  6014  	ctx := testContext2(t, &ContextOpts{
  6015  		Module: m,
  6016  		Hooks:  []Hook{h},
  6017  		ProviderResolver: ResourceProviderResolverFixed(
  6018  			map[string]ResourceProviderFactory{
  6019  				"aws": testProviderFuncFixed(p),
  6020  			},
  6021  		),
  6022  	})
  6023  
  6024  	// First plan and apply a create operation
  6025  	if _, err := ctx.Plan(); err != nil {
  6026  		t.Fatalf("err: %s", err)
  6027  	}
  6028  
  6029  	state, err := ctx.Apply()
  6030  	if err != nil {
  6031  		t.Fatalf("err: %s", err)
  6032  	}
  6033  
  6034  	t.Logf("State 1: %s", state)
  6035  
  6036  	// Next, plan and apply a destroy
  6037  	h.Active = true
  6038  	ctx = testContext2(t, &ContextOpts{
  6039  		Destroy: true,
  6040  		State:   state,
  6041  		Module:  m,
  6042  		Hooks:   []Hook{h},
  6043  		ProviderResolver: ResourceProviderResolverFixed(
  6044  			map[string]ResourceProviderFactory{
  6045  				"aws": testProviderFuncFixed(p),
  6046  			},
  6047  		),
  6048  	})
  6049  
  6050  	if _, err := ctx.Plan(); err != nil {
  6051  		t.Fatalf("err: %s", err)
  6052  	}
  6053  
  6054  	state, err = ctx.Apply()
  6055  	if err != nil {
  6056  		t.Fatalf("err: %s", err)
  6057  	}
  6058  
  6059  	// Test that things were destroyed
  6060  	actual := strings.TrimSpace(state.String())
  6061  	expected := strings.TrimSpace(testTerraformApplyDestroyStr)
  6062  	if actual != expected {
  6063  		t.Fatalf("bad: \n%s", actual)
  6064  	}
  6065  
  6066  	// Test that things were destroyed _in the right order_
  6067  	expected2 := []string{"aws_instance.bar", "aws_instance.foo"}
  6068  	actual2 := h.IDs
  6069  	if !reflect.DeepEqual(actual2, expected2) {
  6070  		t.Fatalf("expected: %#v\n\ngot:%#v", expected2, actual2)
  6071  	}
  6072  }
  6073  
  6074  // https://github.com/hashicorp/terraform/issues/2767
  6075  func TestContext2Apply_destroyModulePrefix(t *testing.T) {
  6076  	m := testModule(t, "apply-destroy-module-resource-prefix")
  6077  	h := new(MockHook)
  6078  	p := testProvider("aws")
  6079  	p.ApplyFn = testApplyFn
  6080  	p.DiffFn = testDiffFn
  6081  	ctx := testContext2(t, &ContextOpts{
  6082  		Module: m,
  6083  		Hooks:  []Hook{h},
  6084  		ProviderResolver: ResourceProviderResolverFixed(
  6085  			map[string]ResourceProviderFactory{
  6086  				"aws": testProviderFuncFixed(p),
  6087  			},
  6088  		),
  6089  	})
  6090  
  6091  	// First plan and apply a create operation
  6092  	if _, err := ctx.Plan(); err != nil {
  6093  		t.Fatalf("err: %s", err)
  6094  	}
  6095  
  6096  	state, err := ctx.Apply()
  6097  	if err != nil {
  6098  		t.Fatalf("err: %s", err)
  6099  	}
  6100  
  6101  	// Verify that we got the apply info correct
  6102  	if v := h.PreApplyInfo.HumanId(); v != "module.child.aws_instance.foo" {
  6103  		t.Fatalf("bad: %s", v)
  6104  	}
  6105  
  6106  	// Next, plan and apply a destroy operation and reset the hook
  6107  	h = new(MockHook)
  6108  	ctx = testContext2(t, &ContextOpts{
  6109  		Destroy: true,
  6110  		State:   state,
  6111  		Module:  m,
  6112  		Hooks:   []Hook{h},
  6113  		ProviderResolver: ResourceProviderResolverFixed(
  6114  			map[string]ResourceProviderFactory{
  6115  				"aws": testProviderFuncFixed(p),
  6116  			},
  6117  		),
  6118  	})
  6119  
  6120  	if _, err := ctx.Plan(); err != nil {
  6121  		t.Fatalf("err: %s", err)
  6122  	}
  6123  
  6124  	state, err = ctx.Apply()
  6125  	if err != nil {
  6126  		t.Fatalf("err: %s", err)
  6127  	}
  6128  
  6129  	// Test that things were destroyed
  6130  	if v := h.PreApplyInfo.HumanId(); v != "module.child.aws_instance.foo" {
  6131  		t.Fatalf("bad: %s", v)
  6132  	}
  6133  }
  6134  
  6135  func TestContext2Apply_destroyNestedModule(t *testing.T) {
  6136  	m := testModule(t, "apply-destroy-nested-module")
  6137  	p := testProvider("aws")
  6138  	p.ApplyFn = testApplyFn
  6139  	p.DiffFn = testDiffFn
  6140  
  6141  	s := &State{
  6142  		Modules: []*ModuleState{
  6143  			&ModuleState{
  6144  				Path: []string{"root", "child", "subchild"},
  6145  				Resources: map[string]*ResourceState{
  6146  					"aws_instance.bar": &ResourceState{
  6147  						Type: "aws_instance",
  6148  						Primary: &InstanceState{
  6149  							ID: "bar",
  6150  						},
  6151  					},
  6152  				},
  6153  			},
  6154  		},
  6155  	}
  6156  
  6157  	ctx := testContext2(t, &ContextOpts{
  6158  		Module: m,
  6159  		ProviderResolver: ResourceProviderResolverFixed(
  6160  			map[string]ResourceProviderFactory{
  6161  				"aws": testProviderFuncFixed(p),
  6162  			},
  6163  		),
  6164  		State: s,
  6165  	})
  6166  
  6167  	// First plan and apply a create operation
  6168  	if _, err := ctx.Plan(); err != nil {
  6169  		t.Fatalf("err: %s", err)
  6170  	}
  6171  
  6172  	state, err := ctx.Apply()
  6173  	if err != nil {
  6174  		t.Fatalf("err: %s", err)
  6175  	}
  6176  
  6177  	// Test that things were destroyed
  6178  	actual := strings.TrimSpace(state.String())
  6179  	if actual != "" {
  6180  		t.Fatalf("expected no state, got: %s", actual)
  6181  	}
  6182  }
  6183  
  6184  func TestContext2Apply_destroyDeeplyNestedModule(t *testing.T) {
  6185  	m := testModule(t, "apply-destroy-deeply-nested-module")
  6186  	p := testProvider("aws")
  6187  	p.ApplyFn = testApplyFn
  6188  	p.DiffFn = testDiffFn
  6189  
  6190  	s := &State{
  6191  		Modules: []*ModuleState{
  6192  			&ModuleState{
  6193  				Path: []string{"root", "child", "subchild", "subsubchild"},
  6194  				Resources: map[string]*ResourceState{
  6195  					"aws_instance.bar": &ResourceState{
  6196  						Type: "aws_instance",
  6197  						Primary: &InstanceState{
  6198  							ID: "bar",
  6199  						},
  6200  					},
  6201  				},
  6202  			},
  6203  		},
  6204  	}
  6205  
  6206  	ctx := testContext2(t, &ContextOpts{
  6207  		Module: m,
  6208  		ProviderResolver: ResourceProviderResolverFixed(
  6209  			map[string]ResourceProviderFactory{
  6210  				"aws": testProviderFuncFixed(p),
  6211  			},
  6212  		),
  6213  		State: s,
  6214  	})
  6215  
  6216  	// First plan and apply a create operation
  6217  	if _, err := ctx.Plan(); err != nil {
  6218  		t.Fatalf("err: %s", err)
  6219  	}
  6220  
  6221  	state, err := ctx.Apply()
  6222  	if err != nil {
  6223  		t.Fatalf("err: %s", err)
  6224  	}
  6225  
  6226  	// Test that things were destroyed
  6227  	actual := strings.TrimSpace(state.String())
  6228  	if actual != "" {
  6229  		t.Fatalf("epected no state, got: %s", actual)
  6230  	}
  6231  }
  6232  
  6233  // https://github.com/hashicorp/terraform/issues/5440
  6234  func TestContext2Apply_destroyModuleWithAttrsReferencingResource(t *testing.T) {
  6235  	m := testModule(t, "apply-destroy-module-with-attrs")
  6236  	p := testProvider("aws")
  6237  	p.ApplyFn = testApplyFn
  6238  	p.DiffFn = testDiffFn
  6239  
  6240  	var state *State
  6241  	var err error
  6242  	{
  6243  		ctx := testContext2(t, &ContextOpts{
  6244  			Module: m,
  6245  			ProviderResolver: ResourceProviderResolverFixed(
  6246  				map[string]ResourceProviderFactory{
  6247  					"aws": testProviderFuncFixed(p),
  6248  				},
  6249  			),
  6250  		})
  6251  
  6252  		// First plan and apply a create operation
  6253  		if p, err := ctx.Plan(); err != nil {
  6254  			t.Fatalf("plan err: %s", err)
  6255  		} else {
  6256  			t.Logf("Step 1 plan: %s", p)
  6257  		}
  6258  
  6259  		state, err = ctx.Apply()
  6260  		if err != nil {
  6261  			t.Fatalf("apply err: %s", err)
  6262  		}
  6263  
  6264  		t.Logf("Step 1 state: %s", state)
  6265  	}
  6266  
  6267  	h := new(HookRecordApplyOrder)
  6268  	h.Active = true
  6269  
  6270  	{
  6271  		ctx := testContext2(t, &ContextOpts{
  6272  			Destroy: true,
  6273  			Module:  m,
  6274  			State:   state,
  6275  			Hooks:   []Hook{h},
  6276  			ProviderResolver: ResourceProviderResolverFixed(
  6277  				map[string]ResourceProviderFactory{
  6278  					"aws": testProviderFuncFixed(p),
  6279  				},
  6280  			),
  6281  			Variables: map[string]interface{}{
  6282  				"key_name": "foobarkey",
  6283  			},
  6284  		})
  6285  
  6286  		// First plan and apply a create operation
  6287  		plan, err := ctx.Plan()
  6288  		if err != nil {
  6289  			t.Fatalf("destroy plan err: %s", err)
  6290  		}
  6291  
  6292  		t.Logf("Step 2 plan: %s", plan)
  6293  
  6294  		var buf bytes.Buffer
  6295  		if err := WritePlan(plan, &buf); err != nil {
  6296  			t.Fatalf("plan write err: %s", err)
  6297  		}
  6298  
  6299  		planFromFile, err := ReadPlan(&buf)
  6300  		if err != nil {
  6301  			t.Fatalf("plan read err: %s", err)
  6302  		}
  6303  
  6304  		ctx, err = planFromFile.Context(&ContextOpts{
  6305  			ProviderResolver: ResourceProviderResolverFixed(
  6306  				map[string]ResourceProviderFactory{
  6307  					"aws": testProviderFuncFixed(p),
  6308  				},
  6309  			),
  6310  		})
  6311  		if err != nil {
  6312  			t.Fatalf("err: %s", err)
  6313  		}
  6314  
  6315  		state, err = ctx.Apply()
  6316  		if err != nil {
  6317  			t.Fatalf("destroy apply err: %s", err)
  6318  		}
  6319  
  6320  		t.Logf("Step 2 state: %s", state)
  6321  	}
  6322  
  6323  	//Test that things were destroyed
  6324  	actual := strings.TrimSpace(state.String())
  6325  	expected := strings.TrimSpace(`
  6326  <no state>
  6327  module.child:
  6328    <no state>
  6329  		`)
  6330  	if actual != expected {
  6331  		t.Fatalf("expected:\n\n%s\n\nactual:\n\n%s", expected, actual)
  6332  	}
  6333  }
  6334  
  6335  func TestContext2Apply_destroyWithModuleVariableAndCount(t *testing.T) {
  6336  	m := testModule(t, "apply-destroy-mod-var-and-count")
  6337  	p := testProvider("aws")
  6338  	p.ApplyFn = testApplyFn
  6339  	p.DiffFn = testDiffFn
  6340  
  6341  	var state *State
  6342  	var err error
  6343  	{
  6344  		ctx := testContext2(t, &ContextOpts{
  6345  			Module: m,
  6346  			ProviderResolver: ResourceProviderResolverFixed(
  6347  				map[string]ResourceProviderFactory{
  6348  					"aws": testProviderFuncFixed(p),
  6349  				},
  6350  			),
  6351  		})
  6352  
  6353  		// First plan and apply a create operation
  6354  		if _, err := ctx.Plan(); err != nil {
  6355  			t.Fatalf("plan err: %s", err)
  6356  		}
  6357  
  6358  		state, err = ctx.Apply()
  6359  		if err != nil {
  6360  			t.Fatalf("apply err: %s", err)
  6361  		}
  6362  	}
  6363  
  6364  	h := new(HookRecordApplyOrder)
  6365  	h.Active = true
  6366  
  6367  	{
  6368  		ctx := testContext2(t, &ContextOpts{
  6369  			Destroy: true,
  6370  			Module:  m,
  6371  			State:   state,
  6372  			Hooks:   []Hook{h},
  6373  			ProviderResolver: ResourceProviderResolverFixed(
  6374  				map[string]ResourceProviderFactory{
  6375  					"aws": testProviderFuncFixed(p),
  6376  				},
  6377  			),
  6378  		})
  6379  
  6380  		// First plan and apply a create operation
  6381  		plan, err := ctx.Plan()
  6382  		if err != nil {
  6383  			t.Fatalf("destroy plan err: %s", err)
  6384  		}
  6385  
  6386  		var buf bytes.Buffer
  6387  		if err := WritePlan(plan, &buf); err != nil {
  6388  			t.Fatalf("plan write err: %s", err)
  6389  		}
  6390  
  6391  		planFromFile, err := ReadPlan(&buf)
  6392  		if err != nil {
  6393  			t.Fatalf("plan read err: %s", err)
  6394  		}
  6395  
  6396  		ctx, err = planFromFile.Context(&ContextOpts{
  6397  			ProviderResolver: ResourceProviderResolverFixed(
  6398  				map[string]ResourceProviderFactory{
  6399  					"aws": testProviderFuncFixed(p),
  6400  				},
  6401  			),
  6402  		})
  6403  		if err != nil {
  6404  			t.Fatalf("err: %s", err)
  6405  		}
  6406  
  6407  		state, err = ctx.Apply()
  6408  		if err != nil {
  6409  			t.Fatalf("destroy apply err: %s", err)
  6410  		}
  6411  	}
  6412  
  6413  	//Test that things were destroyed
  6414  	actual := strings.TrimSpace(state.String())
  6415  	expected := strings.TrimSpace(`
  6416  <no state>
  6417  module.child:
  6418    <no state>
  6419  		`)
  6420  	if actual != expected {
  6421  		t.Fatalf("expected: \n%s\n\nbad: \n%s", expected, actual)
  6422  	}
  6423  }
  6424  
  6425  func TestContext2Apply_destroyTargetWithModuleVariableAndCount(t *testing.T) {
  6426  	m := testModule(t, "apply-destroy-mod-var-and-count")
  6427  	p := testProvider("aws")
  6428  	p.ApplyFn = testApplyFn
  6429  	p.DiffFn = testDiffFn
  6430  
  6431  	var state *State
  6432  	var err error
  6433  	{
  6434  		ctx := testContext2(t, &ContextOpts{
  6435  			Module: m,
  6436  			ProviderResolver: ResourceProviderResolverFixed(
  6437  				map[string]ResourceProviderFactory{
  6438  					"aws": testProviderFuncFixed(p),
  6439  				},
  6440  			),
  6441  		})
  6442  
  6443  		// First plan and apply a create operation
  6444  		if _, err := ctx.Plan(); err != nil {
  6445  			t.Fatalf("plan err: %s", err)
  6446  		}
  6447  
  6448  		state, err = ctx.Apply()
  6449  		if err != nil {
  6450  			t.Fatalf("apply err: %s", err)
  6451  		}
  6452  	}
  6453  
  6454  	{
  6455  		ctx := testContext2(t, &ContextOpts{
  6456  			Destroy: true,
  6457  			Module:  m,
  6458  			State:   state,
  6459  			ProviderResolver: ResourceProviderResolverFixed(
  6460  				map[string]ResourceProviderFactory{
  6461  					"aws": testProviderFuncFixed(p),
  6462  				},
  6463  			),
  6464  			Targets: []string{"module.child"},
  6465  		})
  6466  
  6467  		_, err := ctx.Plan()
  6468  		if err != nil {
  6469  			t.Fatalf("plan err: %s", err)
  6470  		}
  6471  
  6472  		// Destroy, targeting the module explicitly
  6473  		state, err = ctx.Apply()
  6474  		if err != nil {
  6475  			t.Fatalf("destroy apply err: %s", err)
  6476  		}
  6477  	}
  6478  
  6479  	//Test that things were destroyed
  6480  	actual := strings.TrimSpace(state.String())
  6481  	expected := strings.TrimSpace(`
  6482  <no state>
  6483  module.child:
  6484    <no state>
  6485  		`)
  6486  	if actual != expected {
  6487  		t.Fatalf("expected: \n%s\n\nbad: \n%s", expected, actual)
  6488  	}
  6489  }
  6490  
  6491  func TestContext2Apply_destroyWithModuleVariableAndCountNested(t *testing.T) {
  6492  	m := testModule(t, "apply-destroy-mod-var-and-count-nested")
  6493  	p := testProvider("aws")
  6494  	p.ApplyFn = testApplyFn
  6495  	p.DiffFn = testDiffFn
  6496  
  6497  	var state *State
  6498  	var err error
  6499  	{
  6500  		ctx := testContext2(t, &ContextOpts{
  6501  			Module: m,
  6502  			ProviderResolver: ResourceProviderResolverFixed(
  6503  				map[string]ResourceProviderFactory{
  6504  					"aws": testProviderFuncFixed(p),
  6505  				},
  6506  			),
  6507  		})
  6508  
  6509  		// First plan and apply a create operation
  6510  		if _, err := ctx.Plan(); err != nil {
  6511  			t.Fatalf("plan err: %s", err)
  6512  		}
  6513  
  6514  		state, err = ctx.Apply()
  6515  		if err != nil {
  6516  			t.Fatalf("apply err: %s", err)
  6517  		}
  6518  	}
  6519  
  6520  	h := new(HookRecordApplyOrder)
  6521  	h.Active = true
  6522  
  6523  	{
  6524  		ctx := testContext2(t, &ContextOpts{
  6525  			Destroy: true,
  6526  			Module:  m,
  6527  			State:   state,
  6528  			Hooks:   []Hook{h},
  6529  			ProviderResolver: ResourceProviderResolverFixed(
  6530  				map[string]ResourceProviderFactory{
  6531  					"aws": testProviderFuncFixed(p),
  6532  				},
  6533  			),
  6534  		})
  6535  
  6536  		// First plan and apply a create operation
  6537  		plan, err := ctx.Plan()
  6538  		if err != nil {
  6539  			t.Fatalf("destroy plan err: %s", err)
  6540  		}
  6541  
  6542  		var buf bytes.Buffer
  6543  		if err := WritePlan(plan, &buf); err != nil {
  6544  			t.Fatalf("plan write err: %s", err)
  6545  		}
  6546  
  6547  		planFromFile, err := ReadPlan(&buf)
  6548  		if err != nil {
  6549  			t.Fatalf("plan read err: %s", err)
  6550  		}
  6551  
  6552  		ctx, err = planFromFile.Context(&ContextOpts{
  6553  			ProviderResolver: ResourceProviderResolverFixed(
  6554  				map[string]ResourceProviderFactory{
  6555  					"aws": testProviderFuncFixed(p),
  6556  				},
  6557  			),
  6558  		})
  6559  		if err != nil {
  6560  			t.Fatalf("err: %s", err)
  6561  		}
  6562  
  6563  		state, err = ctx.Apply()
  6564  		if err != nil {
  6565  			t.Fatalf("destroy apply err: %s", err)
  6566  		}
  6567  	}
  6568  
  6569  	//Test that things were destroyed
  6570  	actual := strings.TrimSpace(state.String())
  6571  	expected := strings.TrimSpace(`
  6572  <no state>
  6573  module.child:
  6574    <no state>
  6575  module.child.child2:
  6576    <no state>
  6577  		`)
  6578  	if actual != expected {
  6579  		t.Fatalf("expected: \n%s\n\nbad: \n%s", expected, actual)
  6580  	}
  6581  }
  6582  
  6583  func TestContext2Apply_destroyOutputs(t *testing.T) {
  6584  	m := testModule(t, "apply-destroy-outputs")
  6585  	p := testProvider("aws")
  6586  	p.ApplyFn = testApplyFn
  6587  	p.DiffFn = testDiffFn
  6588  	ctx := testContext2(t, &ContextOpts{
  6589  		Module: m,
  6590  		ProviderResolver: ResourceProviderResolverFixed(
  6591  			map[string]ResourceProviderFactory{
  6592  				"aws": testProviderFuncFixed(p),
  6593  			},
  6594  		),
  6595  	})
  6596  
  6597  	// First plan and apply a create operation
  6598  	if _, err := ctx.Plan(); err != nil {
  6599  		t.Fatalf("err: %s", err)
  6600  	}
  6601  
  6602  	state, err := ctx.Apply()
  6603  
  6604  	if err != nil {
  6605  		t.Fatalf("err: %s", err)
  6606  	}
  6607  
  6608  	// Next, plan and apply a destroy operation
  6609  	ctx = testContext2(t, &ContextOpts{
  6610  		Destroy: true,
  6611  		State:   state,
  6612  		Module:  m,
  6613  		ProviderResolver: ResourceProviderResolverFixed(
  6614  			map[string]ResourceProviderFactory{
  6615  				"aws": testProviderFuncFixed(p),
  6616  			},
  6617  		),
  6618  	})
  6619  
  6620  	if _, err := ctx.Plan(); err != nil {
  6621  		t.Fatal(err)
  6622  	}
  6623  
  6624  	state, err = ctx.Apply()
  6625  	if err != nil {
  6626  		t.Fatal(err)
  6627  	}
  6628  
  6629  	mod := state.RootModule()
  6630  	if len(mod.Resources) > 0 {
  6631  		t.Fatalf("expected no resources, got: %#v", mod)
  6632  	}
  6633  
  6634  	// destroying again should produce no errors
  6635  	ctx = testContext2(t, &ContextOpts{
  6636  		Destroy: true,
  6637  		State:   state,
  6638  		Module:  m,
  6639  		ProviderResolver: ResourceProviderResolverFixed(
  6640  			map[string]ResourceProviderFactory{
  6641  				"aws": testProviderFuncFixed(p),
  6642  			},
  6643  		),
  6644  	})
  6645  	if _, err := ctx.Plan(); err != nil {
  6646  		t.Fatal(err)
  6647  	}
  6648  
  6649  	if _, err = ctx.Apply(); err != nil {
  6650  		t.Fatal(err)
  6651  	}
  6652  }
  6653  
  6654  func TestContext2Apply_destroyOrphan(t *testing.T) {
  6655  	m := testModule(t, "apply-error")
  6656  	p := testProvider("aws")
  6657  	s := &State{
  6658  		Modules: []*ModuleState{
  6659  			&ModuleState{
  6660  				Path: rootModulePath,
  6661  				Resources: map[string]*ResourceState{
  6662  					"aws_instance.baz": &ResourceState{
  6663  						Type: "aws_instance",
  6664  						Primary: &InstanceState{
  6665  							ID: "bar",
  6666  						},
  6667  					},
  6668  				},
  6669  			},
  6670  		},
  6671  	}
  6672  	ctx := testContext2(t, &ContextOpts{
  6673  		Module: m,
  6674  		ProviderResolver: ResourceProviderResolverFixed(
  6675  			map[string]ResourceProviderFactory{
  6676  				"aws": testProviderFuncFixed(p),
  6677  			},
  6678  		),
  6679  		State: s,
  6680  	})
  6681  
  6682  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  6683  		if d.Destroy {
  6684  			return nil, nil
  6685  		}
  6686  
  6687  		result := s.MergeDiff(d)
  6688  		result.ID = "foo"
  6689  		return result, nil
  6690  	}
  6691  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  6692  		return &InstanceDiff{
  6693  			Attributes: map[string]*ResourceAttrDiff{
  6694  				"num": &ResourceAttrDiff{
  6695  					New: "bar",
  6696  				},
  6697  			},
  6698  		}, nil
  6699  	}
  6700  
  6701  	if _, err := ctx.Plan(); err != nil {
  6702  		t.Fatalf("err: %s", err)
  6703  	}
  6704  
  6705  	state, err := ctx.Apply()
  6706  	if err != nil {
  6707  		t.Fatalf("err: %s", err)
  6708  	}
  6709  
  6710  	mod := state.RootModule()
  6711  	if _, ok := mod.Resources["aws_instance.baz"]; ok {
  6712  		t.Fatalf("bad: %#v", mod.Resources)
  6713  	}
  6714  }
  6715  
  6716  func TestContext2Apply_destroyTaintedProvisioner(t *testing.T) {
  6717  	m := testModule(t, "apply-destroy-provisioner")
  6718  	p := testProvider("aws")
  6719  	pr := testProvisioner()
  6720  	p.ApplyFn = testApplyFn
  6721  	p.DiffFn = testDiffFn
  6722  
  6723  	called := false
  6724  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  6725  		called = true
  6726  		return nil
  6727  	}
  6728  
  6729  	s := &State{
  6730  		Modules: []*ModuleState{
  6731  			&ModuleState{
  6732  				Path: rootModulePath,
  6733  				Resources: map[string]*ResourceState{
  6734  					"aws_instance.foo": &ResourceState{
  6735  						Type: "aws_instance",
  6736  						Primary: &InstanceState{
  6737  							ID: "bar",
  6738  							Attributes: map[string]string{
  6739  								"id": "bar",
  6740  							},
  6741  							Tainted: true,
  6742  						},
  6743  					},
  6744  				},
  6745  			},
  6746  		},
  6747  	}
  6748  
  6749  	ctx := testContext2(t, &ContextOpts{
  6750  		Module: m,
  6751  		ProviderResolver: ResourceProviderResolverFixed(
  6752  			map[string]ResourceProviderFactory{
  6753  				"aws": testProviderFuncFixed(p),
  6754  			},
  6755  		),
  6756  		Provisioners: map[string]ResourceProvisionerFactory{
  6757  			"shell": testProvisionerFuncFixed(pr),
  6758  		},
  6759  		State:   s,
  6760  		Destroy: true,
  6761  	})
  6762  
  6763  	if _, err := ctx.Plan(); err != nil {
  6764  		t.Fatalf("err: %s", err)
  6765  	}
  6766  
  6767  	state, err := ctx.Apply()
  6768  	if err != nil {
  6769  		t.Fatalf("err: %s", err)
  6770  	}
  6771  
  6772  	if called {
  6773  		t.Fatal("provisioner should not be called")
  6774  	}
  6775  
  6776  	actual := strings.TrimSpace(state.String())
  6777  	expected := strings.TrimSpace("<no state>")
  6778  	if actual != expected {
  6779  		t.Fatalf("bad: \n%s", actual)
  6780  	}
  6781  }
  6782  
  6783  func TestContext2Apply_error(t *testing.T) {
  6784  	errored := false
  6785  
  6786  	m := testModule(t, "apply-error")
  6787  	p := testProvider("aws")
  6788  	ctx := testContext2(t, &ContextOpts{
  6789  		Module: m,
  6790  		ProviderResolver: ResourceProviderResolverFixed(
  6791  			map[string]ResourceProviderFactory{
  6792  				"aws": testProviderFuncFixed(p),
  6793  			},
  6794  		),
  6795  	})
  6796  
  6797  	p.ApplyFn = func(*InstanceInfo, *InstanceState, *InstanceDiff) (*InstanceState, error) {
  6798  		if errored {
  6799  			state := &InstanceState{
  6800  				ID: "bar",
  6801  			}
  6802  			return state, fmt.Errorf("error")
  6803  		}
  6804  		errored = true
  6805  
  6806  		return &InstanceState{
  6807  			ID: "foo",
  6808  			Attributes: map[string]string{
  6809  				"num": "2",
  6810  			},
  6811  		}, nil
  6812  	}
  6813  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  6814  		return &InstanceDiff{
  6815  			Attributes: map[string]*ResourceAttrDiff{
  6816  				"num": &ResourceAttrDiff{
  6817  					New: "bar",
  6818  				},
  6819  			},
  6820  		}, nil
  6821  	}
  6822  
  6823  	if _, err := ctx.Plan(); err != nil {
  6824  		t.Fatalf("err: %s", err)
  6825  	}
  6826  
  6827  	state, err := ctx.Apply()
  6828  	if err == nil {
  6829  		t.Fatal("should have error")
  6830  	}
  6831  
  6832  	actual := strings.TrimSpace(state.String())
  6833  	expected := strings.TrimSpace(testTerraformApplyErrorStr)
  6834  	if actual != expected {
  6835  		t.Fatalf("bad: \n%s", actual)
  6836  	}
  6837  }
  6838  
  6839  func TestContext2Apply_errorPartial(t *testing.T) {
  6840  	errored := false
  6841  
  6842  	m := testModule(t, "apply-error")
  6843  	p := testProvider("aws")
  6844  	s := &State{
  6845  		Modules: []*ModuleState{
  6846  			&ModuleState{
  6847  				Path: rootModulePath,
  6848  				Resources: map[string]*ResourceState{
  6849  					"aws_instance.bar": &ResourceState{
  6850  						Type: "aws_instance",
  6851  						Primary: &InstanceState{
  6852  							ID: "bar",
  6853  						},
  6854  					},
  6855  				},
  6856  			},
  6857  		},
  6858  	}
  6859  	ctx := testContext2(t, &ContextOpts{
  6860  		Module: m,
  6861  		ProviderResolver: ResourceProviderResolverFixed(
  6862  			map[string]ResourceProviderFactory{
  6863  				"aws": testProviderFuncFixed(p),
  6864  			},
  6865  		),
  6866  		State: s,
  6867  	})
  6868  
  6869  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  6870  		if errored {
  6871  			return s, fmt.Errorf("error")
  6872  		}
  6873  		errored = true
  6874  
  6875  		return &InstanceState{
  6876  			ID: "foo",
  6877  			Attributes: map[string]string{
  6878  				"num": "2",
  6879  			},
  6880  		}, nil
  6881  	}
  6882  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  6883  		return &InstanceDiff{
  6884  			Attributes: map[string]*ResourceAttrDiff{
  6885  				"num": &ResourceAttrDiff{
  6886  					New: "bar",
  6887  				},
  6888  			},
  6889  		}, nil
  6890  	}
  6891  
  6892  	if _, err := ctx.Plan(); err != nil {
  6893  		t.Fatalf("err: %s", err)
  6894  	}
  6895  
  6896  	state, err := ctx.Apply()
  6897  	if err == nil {
  6898  		t.Fatal("should have error")
  6899  	}
  6900  
  6901  	mod := state.RootModule()
  6902  	if len(mod.Resources) != 2 {
  6903  		t.Fatalf("bad: %#v", mod.Resources)
  6904  	}
  6905  
  6906  	actual := strings.TrimSpace(state.String())
  6907  	expected := strings.TrimSpace(testTerraformApplyErrorPartialStr)
  6908  	if actual != expected {
  6909  		t.Fatalf("bad: \n%s", actual)
  6910  	}
  6911  }
  6912  
  6913  func TestContext2Apply_hook(t *testing.T) {
  6914  	m := testModule(t, "apply-good")
  6915  	h := new(MockHook)
  6916  	p := testProvider("aws")
  6917  	p.ApplyFn = testApplyFn
  6918  	p.DiffFn = testDiffFn
  6919  	ctx := testContext2(t, &ContextOpts{
  6920  		Module: m,
  6921  		Hooks:  []Hook{h},
  6922  		ProviderResolver: ResourceProviderResolverFixed(
  6923  			map[string]ResourceProviderFactory{
  6924  				"aws": testProviderFuncFixed(p),
  6925  			},
  6926  		),
  6927  	})
  6928  
  6929  	if _, err := ctx.Plan(); err != nil {
  6930  		t.Fatalf("err: %s", err)
  6931  	}
  6932  
  6933  	if _, err := ctx.Apply(); err != nil {
  6934  		t.Fatalf("err: %s", err)
  6935  	}
  6936  
  6937  	if !h.PreApplyCalled {
  6938  		t.Fatal("should be called")
  6939  	}
  6940  	if !h.PostApplyCalled {
  6941  		t.Fatal("should be called")
  6942  	}
  6943  	if !h.PostStateUpdateCalled {
  6944  		t.Fatalf("should call post state update")
  6945  	}
  6946  }
  6947  
  6948  func TestContext2Apply_hookOrphan(t *testing.T) {
  6949  	m := testModule(t, "apply-blank")
  6950  	h := new(MockHook)
  6951  	p := testProvider("aws")
  6952  	p.ApplyFn = testApplyFn
  6953  	p.DiffFn = testDiffFn
  6954  
  6955  	state := &State{
  6956  		Modules: []*ModuleState{
  6957  			&ModuleState{
  6958  				Path: rootModulePath,
  6959  				Resources: map[string]*ResourceState{
  6960  					"aws_instance.bar": &ResourceState{
  6961  						Type: "aws_instance",
  6962  						Primary: &InstanceState{
  6963  							ID: "bar",
  6964  						},
  6965  					},
  6966  				},
  6967  			},
  6968  		},
  6969  	}
  6970  
  6971  	ctx := testContext2(t, &ContextOpts{
  6972  		Module: m,
  6973  		State:  state,
  6974  		Hooks:  []Hook{h},
  6975  		ProviderResolver: ResourceProviderResolverFixed(
  6976  			map[string]ResourceProviderFactory{
  6977  				"aws": testProviderFuncFixed(p),
  6978  			},
  6979  		),
  6980  	})
  6981  
  6982  	if _, err := ctx.Plan(); err != nil {
  6983  		t.Fatalf("err: %s", err)
  6984  	}
  6985  
  6986  	if _, err := ctx.Apply(); err != nil {
  6987  		t.Fatalf("err: %s", err)
  6988  	}
  6989  
  6990  	if !h.PreApplyCalled {
  6991  		t.Fatal("should be called")
  6992  	}
  6993  	if !h.PostApplyCalled {
  6994  		t.Fatal("should be called")
  6995  	}
  6996  	if !h.PostStateUpdateCalled {
  6997  		t.Fatalf("should call post state update")
  6998  	}
  6999  }
  7000  
  7001  func TestContext2Apply_idAttr(t *testing.T) {
  7002  	m := testModule(t, "apply-idattr")
  7003  	p := testProvider("aws")
  7004  	ctx := testContext2(t, &ContextOpts{
  7005  		Module: m,
  7006  		ProviderResolver: ResourceProviderResolverFixed(
  7007  			map[string]ResourceProviderFactory{
  7008  				"aws": testProviderFuncFixed(p),
  7009  			},
  7010  		),
  7011  	})
  7012  
  7013  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  7014  		result := s.MergeDiff(d)
  7015  		result.ID = "foo"
  7016  		result.Attributes = map[string]string{
  7017  			"id": "bar",
  7018  		}
  7019  
  7020  		return result, nil
  7021  	}
  7022  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  7023  		return &InstanceDiff{
  7024  			Attributes: map[string]*ResourceAttrDiff{
  7025  				"num": &ResourceAttrDiff{
  7026  					New: "bar",
  7027  				},
  7028  			},
  7029  		}, nil
  7030  	}
  7031  
  7032  	if _, err := ctx.Plan(); err != nil {
  7033  		t.Fatalf("err: %s", err)
  7034  	}
  7035  
  7036  	state, err := ctx.Apply()
  7037  	if err != nil {
  7038  		t.Fatalf("err: %s", err)
  7039  	}
  7040  
  7041  	mod := state.RootModule()
  7042  	rs, ok := mod.Resources["aws_instance.foo"]
  7043  	if !ok {
  7044  		t.Fatal("not in state")
  7045  	}
  7046  	if rs.Primary.ID != "foo" {
  7047  		t.Fatalf("bad: %#v", rs.Primary.ID)
  7048  	}
  7049  	if rs.Primary.Attributes["id"] != "foo" {
  7050  		t.Fatalf("bad: %#v", rs.Primary.Attributes)
  7051  	}
  7052  }
  7053  
  7054  func TestContext2Apply_outputBasic(t *testing.T) {
  7055  	m := testModule(t, "apply-output")
  7056  	p := testProvider("aws")
  7057  	p.ApplyFn = testApplyFn
  7058  	p.DiffFn = testDiffFn
  7059  	ctx := testContext2(t, &ContextOpts{
  7060  		Module: m,
  7061  		ProviderResolver: ResourceProviderResolverFixed(
  7062  			map[string]ResourceProviderFactory{
  7063  				"aws": testProviderFuncFixed(p),
  7064  			},
  7065  		),
  7066  	})
  7067  
  7068  	if _, err := ctx.Plan(); err != nil {
  7069  		t.Fatalf("err: %s", err)
  7070  	}
  7071  
  7072  	state, err := ctx.Apply()
  7073  	if err != nil {
  7074  		t.Fatalf("err: %s", err)
  7075  	}
  7076  
  7077  	actual := strings.TrimSpace(state.String())
  7078  	expected := strings.TrimSpace(testTerraformApplyOutputStr)
  7079  	if actual != expected {
  7080  		t.Fatalf("bad: \n%s", actual)
  7081  	}
  7082  }
  7083  
  7084  func TestContext2Apply_outputInvalid(t *testing.T) {
  7085  	m := testModule(t, "apply-output-invalid")
  7086  	p := testProvider("aws")
  7087  	p.ApplyFn = testApplyFn
  7088  	p.DiffFn = testDiffFn
  7089  	ctx := testContext2(t, &ContextOpts{
  7090  		Module: m,
  7091  		ProviderResolver: ResourceProviderResolverFixed(
  7092  			map[string]ResourceProviderFactory{
  7093  				"aws": testProviderFuncFixed(p),
  7094  			},
  7095  		),
  7096  	})
  7097  
  7098  	_, err := ctx.Plan()
  7099  	if err == nil {
  7100  		t.Fatalf("err: %s", err)
  7101  	}
  7102  	if !strings.Contains(err.Error(), "is not a valid type") {
  7103  		t.Fatalf("err: %s", err)
  7104  	}
  7105  }
  7106  
  7107  func TestContext2Apply_outputAdd(t *testing.T) {
  7108  	m1 := testModule(t, "apply-output-add-before")
  7109  	p1 := testProvider("aws")
  7110  	p1.ApplyFn = testApplyFn
  7111  	p1.DiffFn = testDiffFn
  7112  	ctx1 := testContext2(t, &ContextOpts{
  7113  		Module: m1,
  7114  		ProviderResolver: ResourceProviderResolverFixed(
  7115  			map[string]ResourceProviderFactory{
  7116  				"aws": testProviderFuncFixed(p1),
  7117  			},
  7118  		),
  7119  	})
  7120  
  7121  	if _, err := ctx1.Plan(); err != nil {
  7122  		t.Fatalf("err: %s", err)
  7123  	}
  7124  
  7125  	state1, err := ctx1.Apply()
  7126  	if err != nil {
  7127  		t.Fatalf("err: %s", err)
  7128  	}
  7129  
  7130  	m2 := testModule(t, "apply-output-add-after")
  7131  	p2 := testProvider("aws")
  7132  	p2.ApplyFn = testApplyFn
  7133  	p2.DiffFn = testDiffFn
  7134  	ctx2 := testContext2(t, &ContextOpts{
  7135  		Module: m2,
  7136  		ProviderResolver: ResourceProviderResolverFixed(
  7137  			map[string]ResourceProviderFactory{
  7138  				"aws": testProviderFuncFixed(p2),
  7139  			},
  7140  		),
  7141  		State: state1,
  7142  	})
  7143  
  7144  	if _, err := ctx2.Plan(); err != nil {
  7145  		t.Fatalf("err: %s", err)
  7146  	}
  7147  
  7148  	state2, err := ctx2.Apply()
  7149  	if err != nil {
  7150  		t.Fatalf("err: %s", err)
  7151  	}
  7152  
  7153  	actual := strings.TrimSpace(state2.String())
  7154  	expected := strings.TrimSpace(testTerraformApplyOutputAddStr)
  7155  	if actual != expected {
  7156  		t.Fatalf("bad: \n%s", actual)
  7157  	}
  7158  }
  7159  
  7160  func TestContext2Apply_outputList(t *testing.T) {
  7161  	m := testModule(t, "apply-output-list")
  7162  	p := testProvider("aws")
  7163  	p.ApplyFn = testApplyFn
  7164  	p.DiffFn = testDiffFn
  7165  	ctx := testContext2(t, &ContextOpts{
  7166  		Module: m,
  7167  		ProviderResolver: ResourceProviderResolverFixed(
  7168  			map[string]ResourceProviderFactory{
  7169  				"aws": testProviderFuncFixed(p),
  7170  			},
  7171  		),
  7172  	})
  7173  
  7174  	if _, err := ctx.Plan(); err != nil {
  7175  		t.Fatalf("err: %s", err)
  7176  	}
  7177  
  7178  	state, err := ctx.Apply()
  7179  	if err != nil {
  7180  		t.Fatalf("err: %s", err)
  7181  	}
  7182  
  7183  	actual := strings.TrimSpace(state.String())
  7184  	expected := strings.TrimSpace(testTerraformApplyOutputListStr)
  7185  	if actual != expected {
  7186  		t.Fatalf("expected: \n%s\n\nbad: \n%s", expected, actual)
  7187  	}
  7188  }
  7189  
  7190  func TestContext2Apply_outputMulti(t *testing.T) {
  7191  	m := testModule(t, "apply-output-multi")
  7192  	p := testProvider("aws")
  7193  	p.ApplyFn = testApplyFn
  7194  	p.DiffFn = testDiffFn
  7195  	ctx := testContext2(t, &ContextOpts{
  7196  		Module: m,
  7197  		ProviderResolver: ResourceProviderResolverFixed(
  7198  			map[string]ResourceProviderFactory{
  7199  				"aws": testProviderFuncFixed(p),
  7200  			},
  7201  		),
  7202  	})
  7203  
  7204  	if _, err := ctx.Plan(); err != nil {
  7205  		t.Fatalf("err: %s", err)
  7206  	}
  7207  
  7208  	state, err := ctx.Apply()
  7209  	if err != nil {
  7210  		t.Fatalf("err: %s", err)
  7211  	}
  7212  
  7213  	actual := strings.TrimSpace(state.String())
  7214  	expected := strings.TrimSpace(testTerraformApplyOutputMultiStr)
  7215  	if actual != expected {
  7216  		t.Fatalf("bad: \n%s", actual)
  7217  	}
  7218  }
  7219  
  7220  func TestContext2Apply_outputMultiIndex(t *testing.T) {
  7221  	m := testModule(t, "apply-output-multi-index")
  7222  	p := testProvider("aws")
  7223  	p.ApplyFn = testApplyFn
  7224  	p.DiffFn = testDiffFn
  7225  	ctx := testContext2(t, &ContextOpts{
  7226  		Module: m,
  7227  		ProviderResolver: ResourceProviderResolverFixed(
  7228  			map[string]ResourceProviderFactory{
  7229  				"aws": testProviderFuncFixed(p),
  7230  			},
  7231  		),
  7232  	})
  7233  
  7234  	if _, err := ctx.Plan(); err != nil {
  7235  		t.Fatalf("err: %s", err)
  7236  	}
  7237  
  7238  	state, err := ctx.Apply()
  7239  	if err != nil {
  7240  		t.Fatalf("err: %s", err)
  7241  	}
  7242  
  7243  	actual := strings.TrimSpace(state.String())
  7244  	expected := strings.TrimSpace(testTerraformApplyOutputMultiIndexStr)
  7245  	if actual != expected {
  7246  		t.Fatalf("bad: \n%s", actual)
  7247  	}
  7248  }
  7249  
  7250  func TestContext2Apply_taintX(t *testing.T) {
  7251  	m := testModule(t, "apply-taint")
  7252  	p := testProvider("aws")
  7253  
  7254  	// destroyCount tests against regression of
  7255  	// https://github.com/hashicorp/terraform/issues/1056
  7256  	var destroyCount = int32(0)
  7257  	var once sync.Once
  7258  	simulateProviderDelay := func() {
  7259  		time.Sleep(10 * time.Millisecond)
  7260  	}
  7261  
  7262  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  7263  		once.Do(simulateProviderDelay)
  7264  		if d.Destroy {
  7265  			atomic.AddInt32(&destroyCount, 1)
  7266  		}
  7267  		return testApplyFn(info, s, d)
  7268  	}
  7269  	p.DiffFn = testDiffFn
  7270  	s := &State{
  7271  		Modules: []*ModuleState{
  7272  			&ModuleState{
  7273  				Path: rootModulePath,
  7274  				Resources: map[string]*ResourceState{
  7275  					"aws_instance.bar": &ResourceState{
  7276  						Type: "aws_instance",
  7277  						Primary: &InstanceState{
  7278  							ID: "baz",
  7279  							Attributes: map[string]string{
  7280  								"num":  "2",
  7281  								"type": "aws_instance",
  7282  							},
  7283  							Tainted: true,
  7284  						},
  7285  					},
  7286  				},
  7287  			},
  7288  		},
  7289  	}
  7290  	ctx := testContext2(t, &ContextOpts{
  7291  		Module: m,
  7292  		ProviderResolver: ResourceProviderResolverFixed(
  7293  			map[string]ResourceProviderFactory{
  7294  				"aws": testProviderFuncFixed(p),
  7295  			},
  7296  		),
  7297  		State: s,
  7298  	})
  7299  
  7300  	if p, err := ctx.Plan(); err != nil {
  7301  		t.Fatalf("err: %s", err)
  7302  	} else {
  7303  		t.Logf("plan: %s", p)
  7304  	}
  7305  
  7306  	state, err := ctx.Apply()
  7307  	if err != nil {
  7308  		t.Fatalf("err: %s", err)
  7309  	}
  7310  
  7311  	actual := strings.TrimSpace(state.String())
  7312  	expected := strings.TrimSpace(testTerraformApplyTaintStr)
  7313  	if actual != expected {
  7314  		t.Fatalf("bad:\n%s", actual)
  7315  	}
  7316  
  7317  	if destroyCount != 1 {
  7318  		t.Fatalf("Expected 1 destroy, got %d", destroyCount)
  7319  	}
  7320  }
  7321  
  7322  func TestContext2Apply_taintDep(t *testing.T) {
  7323  	m := testModule(t, "apply-taint-dep")
  7324  	p := testProvider("aws")
  7325  	p.ApplyFn = testApplyFn
  7326  	p.DiffFn = testDiffFn
  7327  	s := &State{
  7328  		Modules: []*ModuleState{
  7329  			&ModuleState{
  7330  				Path: rootModulePath,
  7331  				Resources: map[string]*ResourceState{
  7332  					"aws_instance.foo": &ResourceState{
  7333  						Type: "aws_instance",
  7334  						Primary: &InstanceState{
  7335  							ID: "baz",
  7336  							Attributes: map[string]string{
  7337  								"num":  "2",
  7338  								"type": "aws_instance",
  7339  							},
  7340  							Tainted: true,
  7341  						},
  7342  					},
  7343  					"aws_instance.bar": &ResourceState{
  7344  						Type: "aws_instance",
  7345  						Primary: &InstanceState{
  7346  							ID: "bar",
  7347  							Attributes: map[string]string{
  7348  								"foo":  "baz",
  7349  								"num":  "2",
  7350  								"type": "aws_instance",
  7351  							},
  7352  						},
  7353  					},
  7354  				},
  7355  			},
  7356  		},
  7357  	}
  7358  	ctx := testContext2(t, &ContextOpts{
  7359  		Module: m,
  7360  		ProviderResolver: ResourceProviderResolverFixed(
  7361  			map[string]ResourceProviderFactory{
  7362  				"aws": testProviderFuncFixed(p),
  7363  			},
  7364  		),
  7365  		State: s,
  7366  	})
  7367  
  7368  	if p, err := ctx.Plan(); err != nil {
  7369  		t.Fatalf("err: %s", err)
  7370  	} else {
  7371  		t.Logf("plan: %s", p)
  7372  	}
  7373  
  7374  	state, err := ctx.Apply()
  7375  	if err != nil {
  7376  		t.Fatalf("err: %s", err)
  7377  	}
  7378  
  7379  	actual := strings.TrimSpace(state.String())
  7380  	expected := strings.TrimSpace(testTerraformApplyTaintDepStr)
  7381  	if actual != expected {
  7382  		t.Fatalf("bad:\n%s", actual)
  7383  	}
  7384  }
  7385  
  7386  func TestContext2Apply_taintDepRequiresNew(t *testing.T) {
  7387  	m := testModule(t, "apply-taint-dep-requires-new")
  7388  	p := testProvider("aws")
  7389  	p.ApplyFn = testApplyFn
  7390  	p.DiffFn = testDiffFn
  7391  	s := &State{
  7392  		Modules: []*ModuleState{
  7393  			&ModuleState{
  7394  				Path: rootModulePath,
  7395  				Resources: map[string]*ResourceState{
  7396  					"aws_instance.foo": &ResourceState{
  7397  						Type: "aws_instance",
  7398  						Primary: &InstanceState{
  7399  							ID: "baz",
  7400  							Attributes: map[string]string{
  7401  								"num":  "2",
  7402  								"type": "aws_instance",
  7403  							},
  7404  							Tainted: true,
  7405  						},
  7406  					},
  7407  					"aws_instance.bar": &ResourceState{
  7408  						Type: "aws_instance",
  7409  						Primary: &InstanceState{
  7410  							ID: "bar",
  7411  							Attributes: map[string]string{
  7412  								"foo":  "baz",
  7413  								"num":  "2",
  7414  								"type": "aws_instance",
  7415  							},
  7416  						},
  7417  					},
  7418  				},
  7419  			},
  7420  		},
  7421  	}
  7422  	ctx := testContext2(t, &ContextOpts{
  7423  		Module: m,
  7424  		ProviderResolver: ResourceProviderResolverFixed(
  7425  			map[string]ResourceProviderFactory{
  7426  				"aws": testProviderFuncFixed(p),
  7427  			},
  7428  		),
  7429  		State: s,
  7430  	})
  7431  
  7432  	if p, err := ctx.Plan(); err != nil {
  7433  		t.Fatalf("err: %s", err)
  7434  	} else {
  7435  		t.Logf("plan: %s", p)
  7436  	}
  7437  
  7438  	state, err := ctx.Apply()
  7439  	if err != nil {
  7440  		t.Fatalf("err: %s", err)
  7441  	}
  7442  
  7443  	actual := strings.TrimSpace(state.String())
  7444  	expected := strings.TrimSpace(testTerraformApplyTaintDepRequireNewStr)
  7445  	if actual != expected {
  7446  		t.Fatalf("bad:\n%s", actual)
  7447  	}
  7448  }
  7449  
  7450  func TestContext2Apply_targeted(t *testing.T) {
  7451  	m := testModule(t, "apply-targeted")
  7452  	p := testProvider("aws")
  7453  	p.ApplyFn = testApplyFn
  7454  	p.DiffFn = testDiffFn
  7455  	ctx := testContext2(t, &ContextOpts{
  7456  		Module: m,
  7457  		ProviderResolver: ResourceProviderResolverFixed(
  7458  			map[string]ResourceProviderFactory{
  7459  				"aws": testProviderFuncFixed(p),
  7460  			},
  7461  		),
  7462  		Targets: []string{"aws_instance.foo"},
  7463  	})
  7464  
  7465  	if _, err := ctx.Plan(); err != nil {
  7466  		t.Fatalf("err: %s", err)
  7467  	}
  7468  
  7469  	state, err := ctx.Apply()
  7470  	if err != nil {
  7471  		t.Fatalf("err: %s", err)
  7472  	}
  7473  
  7474  	mod := state.RootModule()
  7475  	if len(mod.Resources) != 1 {
  7476  		t.Fatalf("expected 1 resource, got: %#v", mod.Resources)
  7477  	}
  7478  
  7479  	checkStateString(t, state, `
  7480  aws_instance.foo:
  7481    ID = foo
  7482    provider = provider.aws
  7483    num = 2
  7484    type = aws_instance
  7485  	`)
  7486  }
  7487  
  7488  func TestContext2Apply_targetEmpty(t *testing.T) {
  7489  	m := testModule(t, "apply-targeted")
  7490  	p := testProvider("aws")
  7491  	p.ApplyFn = testApplyFn
  7492  	p.DiffFn = testDiffFn
  7493  	ctx := testContext2(t, &ContextOpts{
  7494  		Module: m,
  7495  		ProviderResolver: ResourceProviderResolverFixed(
  7496  			map[string]ResourceProviderFactory{
  7497  				"aws": testProviderFuncFixed(p),
  7498  			},
  7499  		),
  7500  		Targets: []string{""},
  7501  	})
  7502  
  7503  	_, err := ctx.Apply()
  7504  	if err == nil {
  7505  		t.Fatalf("should error")
  7506  	}
  7507  }
  7508  
  7509  func TestContext2Apply_targetedCount(t *testing.T) {
  7510  	m := testModule(t, "apply-targeted-count")
  7511  	p := testProvider("aws")
  7512  	p.ApplyFn = testApplyFn
  7513  	p.DiffFn = testDiffFn
  7514  	ctx := testContext2(t, &ContextOpts{
  7515  		Module: m,
  7516  		ProviderResolver: ResourceProviderResolverFixed(
  7517  			map[string]ResourceProviderFactory{
  7518  				"aws": testProviderFuncFixed(p),
  7519  			},
  7520  		),
  7521  		Targets: []string{"aws_instance.foo"},
  7522  	})
  7523  
  7524  	if _, err := ctx.Plan(); err != nil {
  7525  		t.Fatalf("err: %s", err)
  7526  	}
  7527  
  7528  	state, err := ctx.Apply()
  7529  	if err != nil {
  7530  		t.Fatalf("err: %s", err)
  7531  	}
  7532  
  7533  	checkStateString(t, state, `
  7534  aws_instance.foo.0:
  7535    ID = foo
  7536    provider = provider.aws
  7537  aws_instance.foo.1:
  7538    ID = foo
  7539    provider = provider.aws
  7540  aws_instance.foo.2:
  7541    ID = foo
  7542    provider = provider.aws
  7543  	`)
  7544  }
  7545  
  7546  func TestContext2Apply_targetedCountIndex(t *testing.T) {
  7547  	m := testModule(t, "apply-targeted-count")
  7548  	p := testProvider("aws")
  7549  	p.ApplyFn = testApplyFn
  7550  	p.DiffFn = testDiffFn
  7551  	ctx := testContext2(t, &ContextOpts{
  7552  		Module: m,
  7553  		ProviderResolver: ResourceProviderResolverFixed(
  7554  			map[string]ResourceProviderFactory{
  7555  				"aws": testProviderFuncFixed(p),
  7556  			},
  7557  		),
  7558  		Targets: []string{"aws_instance.foo[1]"},
  7559  	})
  7560  
  7561  	if _, err := ctx.Plan(); err != nil {
  7562  		t.Fatalf("err: %s", err)
  7563  	}
  7564  
  7565  	state, err := ctx.Apply()
  7566  	if err != nil {
  7567  		t.Fatalf("err: %s", err)
  7568  	}
  7569  
  7570  	checkStateString(t, state, `
  7571  aws_instance.foo.1:
  7572    ID = foo
  7573    provider = provider.aws
  7574  	`)
  7575  }
  7576  
  7577  func TestContext2Apply_targetedDestroy(t *testing.T) {
  7578  	m := testModule(t, "apply-targeted")
  7579  	p := testProvider("aws")
  7580  	p.ApplyFn = testApplyFn
  7581  	p.DiffFn = testDiffFn
  7582  	ctx := testContext2(t, &ContextOpts{
  7583  		Module: m,
  7584  		ProviderResolver: ResourceProviderResolverFixed(
  7585  			map[string]ResourceProviderFactory{
  7586  				"aws": testProviderFuncFixed(p),
  7587  			},
  7588  		),
  7589  		State: &State{
  7590  			Modules: []*ModuleState{
  7591  				&ModuleState{
  7592  					Path: rootModulePath,
  7593  					Resources: map[string]*ResourceState{
  7594  						"aws_instance.foo": resourceState("aws_instance", "i-bcd345"),
  7595  						"aws_instance.bar": resourceState("aws_instance", "i-abc123"),
  7596  					},
  7597  				},
  7598  			},
  7599  		},
  7600  		Targets: []string{"aws_instance.foo"},
  7601  		Destroy: true,
  7602  	})
  7603  
  7604  	if _, err := ctx.Plan(); err != nil {
  7605  		t.Fatalf("err: %s", err)
  7606  	}
  7607  
  7608  	state, err := ctx.Apply()
  7609  	if err != nil {
  7610  		t.Fatalf("err: %s", err)
  7611  	}
  7612  
  7613  	mod := state.RootModule()
  7614  	if len(mod.Resources) != 1 {
  7615  		t.Fatalf("expected 1 resource, got: %#v", mod.Resources)
  7616  	}
  7617  
  7618  	checkStateString(t, state, `
  7619  aws_instance.bar:
  7620    ID = i-abc123
  7621  	`)
  7622  }
  7623  
  7624  func TestContext2Apply_destroyProvisionerWithLocals(t *testing.T) {
  7625  	m := testModule(t, "apply-provisioner-destroy-locals")
  7626  	p := testProvider("aws")
  7627  	p.ApplyFn = testApplyFn
  7628  	p.DiffFn = testDiffFn
  7629  
  7630  	pr := testProvisioner()
  7631  	pr.ApplyFn = func(_ *InstanceState, rc *ResourceConfig) error {
  7632  		cmd, ok := rc.Get("command")
  7633  		if !ok || cmd != "local" {
  7634  			fmt.Printf("%#v\n", rc.Config)
  7635  			return fmt.Errorf("provisioner got %v:%s", ok, cmd)
  7636  		}
  7637  		return nil
  7638  	}
  7639  
  7640  	ctx := testContext2(t, &ContextOpts{
  7641  		Module: m,
  7642  		ProviderResolver: ResourceProviderResolverFixed(
  7643  			map[string]ResourceProviderFactory{
  7644  				"aws": testProviderFuncFixed(p),
  7645  			},
  7646  		),
  7647  		Provisioners: map[string]ResourceProvisionerFactory{
  7648  			"shell": testProvisionerFuncFixed(pr),
  7649  		},
  7650  		State: &State{
  7651  			Modules: []*ModuleState{
  7652  				&ModuleState{
  7653  					Path: []string{"root"},
  7654  					Resources: map[string]*ResourceState{
  7655  						"aws_instance.foo": resourceState("aws_instance", "1234"),
  7656  					},
  7657  				},
  7658  			},
  7659  		},
  7660  		Destroy: true,
  7661  		// the test works without targeting, but this also tests that the local
  7662  		// node isn't inadvertently pruned because of the wrong evaluation
  7663  		// order.
  7664  		Targets: []string{"aws_instance.foo"},
  7665  	})
  7666  
  7667  	if _, err := ctx.Plan(); err != nil {
  7668  		t.Fatal(err)
  7669  	}
  7670  
  7671  	if _, err := ctx.Apply(); err != nil {
  7672  		t.Fatal(err)
  7673  	}
  7674  
  7675  	if !pr.ApplyCalled {
  7676  		t.Fatal("provisioner not called")
  7677  	}
  7678  }
  7679  
  7680  // this also tests a local value in the config referencing a resource that
  7681  // wasn't in the state during destroy.
  7682  func TestContext2Apply_destroyProvisionerWithMultipleLocals(t *testing.T) {
  7683  	m := testModule(t, "apply-provisioner-destroy-multiple-locals")
  7684  	p := testProvider("aws")
  7685  	p.ApplyFn = testApplyFn
  7686  	p.DiffFn = testDiffFn
  7687  
  7688  	pr := testProvisioner()
  7689  	pr.ApplyFn = func(is *InstanceState, rc *ResourceConfig) error {
  7690  		cmd, ok := rc.Get("command")
  7691  		if !ok {
  7692  			return errors.New("no command in provisioner")
  7693  		}
  7694  
  7695  		switch is.ID {
  7696  		case "1234":
  7697  			if cmd != "local" {
  7698  				return fmt.Errorf("provisioner %q got:%q", is.ID, cmd)
  7699  			}
  7700  		case "3456":
  7701  			if cmd != "1234" {
  7702  				return fmt.Errorf("provisioner %q got:%q", is.ID, cmd)
  7703  			}
  7704  		default:
  7705  			t.Fatal("unknown instance")
  7706  		}
  7707  		return nil
  7708  	}
  7709  
  7710  	ctx := testContext2(t, &ContextOpts{
  7711  		Module: m,
  7712  		ProviderResolver: ResourceProviderResolverFixed(
  7713  			map[string]ResourceProviderFactory{
  7714  				"aws": testProviderFuncFixed(p),
  7715  			},
  7716  		),
  7717  		Provisioners: map[string]ResourceProvisionerFactory{
  7718  			"shell": testProvisionerFuncFixed(pr),
  7719  		},
  7720  		State: &State{
  7721  			Modules: []*ModuleState{
  7722  				&ModuleState{
  7723  					Path: []string{"root"},
  7724  					Resources: map[string]*ResourceState{
  7725  						"aws_instance.foo": resourceState("aws_instance", "1234"),
  7726  						"aws_instance.bar": resourceState("aws_instance", "3456"),
  7727  					},
  7728  				},
  7729  			},
  7730  		},
  7731  		Destroy: true,
  7732  	})
  7733  
  7734  	if _, err := ctx.Plan(); err != nil {
  7735  		t.Fatal(err)
  7736  	}
  7737  
  7738  	if _, err := ctx.Apply(); err != nil {
  7739  		t.Fatal(err)
  7740  	}
  7741  
  7742  	if !pr.ApplyCalled {
  7743  		t.Fatal("provisioner not called")
  7744  	}
  7745  }
  7746  
  7747  func TestContext2Apply_destroyProvisionerWithOutput(t *testing.T) {
  7748  	m := testModule(t, "apply-provisioner-destroy-outputs")
  7749  	p := testProvider("aws")
  7750  	p.ApplyFn = testApplyFn
  7751  	p.DiffFn = testDiffFn
  7752  
  7753  	pr := testProvisioner()
  7754  	pr.ApplyFn = func(is *InstanceState, rc *ResourceConfig) error {
  7755  		cmd, ok := rc.Get("command")
  7756  		if !ok || cmd != "3" {
  7757  			fmt.Printf("%#v\n", rc.Config)
  7758  			return fmt.Errorf("provisioner for %s got %v:%s", is.ID, ok, cmd)
  7759  		}
  7760  		return nil
  7761  	}
  7762  
  7763  	ctx := testContext2(t, &ContextOpts{
  7764  		Module: m,
  7765  		ProviderResolver: ResourceProviderResolverFixed(
  7766  			map[string]ResourceProviderFactory{
  7767  				"aws": testProviderFuncFixed(p),
  7768  			},
  7769  		),
  7770  		Provisioners: map[string]ResourceProvisionerFactory{
  7771  			"shell": testProvisionerFuncFixed(pr),
  7772  		},
  7773  		State: &State{
  7774  			Modules: []*ModuleState{
  7775  				&ModuleState{
  7776  					Path: []string{"root"},
  7777  					Resources: map[string]*ResourceState{
  7778  						"aws_instance.foo": resourceState("aws_instance", "1"),
  7779  					},
  7780  					Outputs: map[string]*OutputState{
  7781  						"value": {
  7782  							Type:  "string",
  7783  							Value: "3",
  7784  						},
  7785  					},
  7786  				},
  7787  				&ModuleState{
  7788  					Path: []string{"root", "mod"},
  7789  					Resources: map[string]*ResourceState{
  7790  						"aws_instance.baz": resourceState("aws_instance", "3"),
  7791  					},
  7792  					// state needs to be properly initialized
  7793  					Outputs: map[string]*OutputState{},
  7794  				},
  7795  				&ModuleState{
  7796  					Path: []string{"root", "mod2"},
  7797  					Resources: map[string]*ResourceState{
  7798  						"aws_instance.bar": resourceState("aws_instance", "2"),
  7799  					},
  7800  				},
  7801  			},
  7802  		},
  7803  		Destroy: true,
  7804  
  7805  		// targeting the source of the value used by all resources should still
  7806  		// destroy them all.
  7807  		Targets: []string{"module.mod.aws_instance.baz"},
  7808  	})
  7809  
  7810  	if _, err := ctx.Plan(); err != nil {
  7811  		t.Fatal(err)
  7812  	}
  7813  
  7814  	state, err := ctx.Apply()
  7815  	if err != nil {
  7816  		t.Fatal(err)
  7817  	}
  7818  	if !pr.ApplyCalled {
  7819  		t.Fatal("provisioner not called")
  7820  	}
  7821  
  7822  	// confirm all outputs were removed too
  7823  	for _, mod := range state.Modules {
  7824  		if len(mod.Outputs) > 0 {
  7825  			t.Fatalf("output left in module state: %#v\n", mod)
  7826  		}
  7827  	}
  7828  }
  7829  
  7830  func TestContext2Apply_targetedDestroyCountDeps(t *testing.T) {
  7831  	m := testModule(t, "apply-destroy-targeted-count")
  7832  	p := testProvider("aws")
  7833  	p.ApplyFn = testApplyFn
  7834  	p.DiffFn = testDiffFn
  7835  	ctx := testContext2(t, &ContextOpts{
  7836  		Module: m,
  7837  		ProviderResolver: ResourceProviderResolverFixed(
  7838  			map[string]ResourceProviderFactory{
  7839  				"aws": testProviderFuncFixed(p),
  7840  			},
  7841  		),
  7842  		State: &State{
  7843  			Modules: []*ModuleState{
  7844  				&ModuleState{
  7845  					Path: rootModulePath,
  7846  					Resources: map[string]*ResourceState{
  7847  						"aws_instance.foo": resourceState("aws_instance", "i-bcd345"),
  7848  						"aws_instance.bar": resourceState("aws_instance", "i-abc123"),
  7849  					},
  7850  				},
  7851  			},
  7852  		},
  7853  		Targets: []string{"aws_instance.foo"},
  7854  		Destroy: true,
  7855  	})
  7856  
  7857  	if _, err := ctx.Plan(); err != nil {
  7858  		t.Fatalf("err: %s", err)
  7859  	}
  7860  
  7861  	state, err := ctx.Apply()
  7862  	if err != nil {
  7863  		t.Fatalf("err: %s", err)
  7864  	}
  7865  
  7866  	checkStateString(t, state, `<no state>`)
  7867  }
  7868  
  7869  // https://github.com/hashicorp/terraform/issues/4462
  7870  func TestContext2Apply_targetedDestroyModule(t *testing.T) {
  7871  	m := testModule(t, "apply-targeted-module")
  7872  	p := testProvider("aws")
  7873  	p.ApplyFn = testApplyFn
  7874  	p.DiffFn = testDiffFn
  7875  	ctx := testContext2(t, &ContextOpts{
  7876  		Module: m,
  7877  		ProviderResolver: ResourceProviderResolverFixed(
  7878  			map[string]ResourceProviderFactory{
  7879  				"aws": testProviderFuncFixed(p),
  7880  			},
  7881  		),
  7882  		State: &State{
  7883  			Modules: []*ModuleState{
  7884  				&ModuleState{
  7885  					Path: rootModulePath,
  7886  					Resources: map[string]*ResourceState{
  7887  						"aws_instance.foo": resourceState("aws_instance", "i-bcd345"),
  7888  						"aws_instance.bar": resourceState("aws_instance", "i-abc123"),
  7889  					},
  7890  				},
  7891  				&ModuleState{
  7892  					Path: []string{"root", "child"},
  7893  					Resources: map[string]*ResourceState{
  7894  						"aws_instance.foo": resourceState("aws_instance", "i-bcd345"),
  7895  						"aws_instance.bar": resourceState("aws_instance", "i-abc123"),
  7896  					},
  7897  				},
  7898  			},
  7899  		},
  7900  		Targets: []string{"module.child.aws_instance.foo"},
  7901  		Destroy: true,
  7902  	})
  7903  
  7904  	if _, err := ctx.Plan(); err != nil {
  7905  		t.Fatalf("err: %s", err)
  7906  	}
  7907  
  7908  	state, err := ctx.Apply()
  7909  	if err != nil {
  7910  		t.Fatalf("err: %s", err)
  7911  	}
  7912  
  7913  	checkStateString(t, state, `
  7914  aws_instance.bar:
  7915    ID = i-abc123
  7916  aws_instance.foo:
  7917    ID = i-bcd345
  7918  
  7919  module.child:
  7920    aws_instance.bar:
  7921      ID = i-abc123
  7922  	`)
  7923  }
  7924  
  7925  func TestContext2Apply_targetedDestroyCountIndex(t *testing.T) {
  7926  	m := testModule(t, "apply-targeted-count")
  7927  	p := testProvider("aws")
  7928  	p.ApplyFn = testApplyFn
  7929  	p.DiffFn = testDiffFn
  7930  	ctx := testContext2(t, &ContextOpts{
  7931  		Module: m,
  7932  		ProviderResolver: ResourceProviderResolverFixed(
  7933  			map[string]ResourceProviderFactory{
  7934  				"aws": testProviderFuncFixed(p),
  7935  			},
  7936  		),
  7937  		State: &State{
  7938  			Modules: []*ModuleState{
  7939  				&ModuleState{
  7940  					Path: rootModulePath,
  7941  					Resources: map[string]*ResourceState{
  7942  						"aws_instance.foo.0": resourceState("aws_instance", "i-bcd345"),
  7943  						"aws_instance.foo.1": resourceState("aws_instance", "i-bcd345"),
  7944  						"aws_instance.foo.2": resourceState("aws_instance", "i-bcd345"),
  7945  						"aws_instance.bar.0": resourceState("aws_instance", "i-abc123"),
  7946  						"aws_instance.bar.1": resourceState("aws_instance", "i-abc123"),
  7947  						"aws_instance.bar.2": resourceState("aws_instance", "i-abc123"),
  7948  					},
  7949  				},
  7950  			},
  7951  		},
  7952  		Targets: []string{
  7953  			"aws_instance.foo[2]",
  7954  			"aws_instance.bar[1]",
  7955  		},
  7956  		Destroy: true,
  7957  	})
  7958  
  7959  	if _, err := ctx.Plan(); err != nil {
  7960  		t.Fatalf("err: %s", err)
  7961  	}
  7962  
  7963  	state, err := ctx.Apply()
  7964  	if err != nil {
  7965  		t.Fatalf("err: %s", err)
  7966  	}
  7967  
  7968  	checkStateString(t, state, `
  7969  aws_instance.bar.0:
  7970    ID = i-abc123
  7971  aws_instance.bar.2:
  7972    ID = i-abc123
  7973  aws_instance.foo.0:
  7974    ID = i-bcd345
  7975  aws_instance.foo.1:
  7976    ID = i-bcd345
  7977  	`)
  7978  }
  7979  
  7980  func TestContext2Apply_targetedModule(t *testing.T) {
  7981  	m := testModule(t, "apply-targeted-module")
  7982  	p := testProvider("aws")
  7983  	p.ApplyFn = testApplyFn
  7984  	p.DiffFn = testDiffFn
  7985  	ctx := testContext2(t, &ContextOpts{
  7986  		Module: m,
  7987  		ProviderResolver: ResourceProviderResolverFixed(
  7988  			map[string]ResourceProviderFactory{
  7989  				"aws": testProviderFuncFixed(p),
  7990  			},
  7991  		),
  7992  		Targets: []string{"module.child"},
  7993  	})
  7994  
  7995  	if _, err := ctx.Plan(); err != nil {
  7996  		t.Fatalf("err: %s", err)
  7997  	}
  7998  
  7999  	state, err := ctx.Apply()
  8000  	if err != nil {
  8001  		t.Fatalf("err: %s", err)
  8002  	}
  8003  
  8004  	mod := state.ModuleByPath([]string{"root", "child"})
  8005  	if mod == nil {
  8006  		t.Fatalf("no child module found in the state!\n\n%#v", state)
  8007  	}
  8008  	if len(mod.Resources) != 2 {
  8009  		t.Fatalf("expected 2 resources, got: %#v", mod.Resources)
  8010  	}
  8011  
  8012  	checkStateString(t, state, `
  8013  <no state>
  8014  module.child:
  8015    aws_instance.bar:
  8016      ID = foo
  8017      provider = provider.aws
  8018      num = 2
  8019      type = aws_instance
  8020    aws_instance.foo:
  8021      ID = foo
  8022      provider = provider.aws
  8023      num = 2
  8024      type = aws_instance
  8025  	`)
  8026  }
  8027  
  8028  // GH-1858
  8029  func TestContext2Apply_targetedModuleDep(t *testing.T) {
  8030  	m := testModule(t, "apply-targeted-module-dep")
  8031  	p := testProvider("aws")
  8032  	p.ApplyFn = testApplyFn
  8033  	p.DiffFn = testDiffFn
  8034  	ctx := testContext2(t, &ContextOpts{
  8035  		Module: m,
  8036  		ProviderResolver: ResourceProviderResolverFixed(
  8037  			map[string]ResourceProviderFactory{
  8038  				"aws": testProviderFuncFixed(p),
  8039  			},
  8040  		),
  8041  		Targets: []string{"aws_instance.foo"},
  8042  	})
  8043  
  8044  	if p, err := ctx.Plan(); err != nil {
  8045  		t.Fatalf("err: %s", err)
  8046  	} else {
  8047  		t.Logf("Diff: %s", p)
  8048  	}
  8049  
  8050  	state, err := ctx.Apply()
  8051  	if err != nil {
  8052  		t.Fatalf("err: %s", err)
  8053  	}
  8054  
  8055  	checkStateString(t, state, `
  8056  aws_instance.foo:
  8057    ID = foo
  8058    provider = provider.aws
  8059    foo = foo
  8060    type = aws_instance
  8061  
  8062    Dependencies:
  8063      module.child
  8064  
  8065  module.child:
  8066    aws_instance.mod:
  8067      ID = foo
  8068      provider = provider.aws
  8069  
  8070    Outputs:
  8071  
  8072    output = foo
  8073  	`)
  8074  }
  8075  
  8076  // GH-10911 untargeted outputs should not be in the graph, and therefore
  8077  // not execute.
  8078  func TestContext2Apply_targetedModuleUnrelatedOutputs(t *testing.T) {
  8079  	m := testModule(t, "apply-targeted-module-unrelated-outputs")
  8080  	p := testProvider("aws")
  8081  	p.ApplyFn = testApplyFn
  8082  	p.DiffFn = testDiffFn
  8083  	ctx := testContext2(t, &ContextOpts{
  8084  		Module: m,
  8085  		ProviderResolver: ResourceProviderResolverFixed(
  8086  			map[string]ResourceProviderFactory{
  8087  				"aws": testProviderFuncFixed(p),
  8088  			},
  8089  		),
  8090  		Targets: []string{"module.child2"},
  8091  		State: &State{
  8092  			Modules: []*ModuleState{
  8093  				{
  8094  					Path:      []string{"root"},
  8095  					Outputs:   map[string]*OutputState{},
  8096  					Resources: map[string]*ResourceState{},
  8097  				},
  8098  				{
  8099  					Path: []string{"root", "child1"},
  8100  					Outputs: map[string]*OutputState{
  8101  						"instance_id": {
  8102  							Type:  "string",
  8103  							Value: "foo-bar-baz",
  8104  						},
  8105  					},
  8106  					Resources: map[string]*ResourceState{},
  8107  				},
  8108  				{
  8109  					Path:      []string{"root", "child2"},
  8110  					Outputs:   map[string]*OutputState{},
  8111  					Resources: map[string]*ResourceState{},
  8112  				},
  8113  			},
  8114  		},
  8115  	})
  8116  
  8117  	if _, err := ctx.Plan(); err != nil {
  8118  		t.Fatalf("err: %s", err)
  8119  	}
  8120  
  8121  	state, err := ctx.Apply()
  8122  	if err != nil {
  8123  		t.Fatalf("err: %s", err)
  8124  	}
  8125  
  8126  	// module.child1's instance_id output should be retained from state
  8127  	// module.child2's instance_id is updated because its dependency is updated
  8128  	// child2_id is updated because if its transitive dependency via module.child2
  8129  	checkStateString(t, state, `
  8130  <no state>
  8131  Outputs:
  8132  
  8133  child2_id = foo
  8134  
  8135  module.child1:
  8136    <no state>
  8137    Outputs:
  8138  
  8139    instance_id = foo-bar-baz
  8140  module.child2:
  8141    aws_instance.foo:
  8142      ID = foo
  8143      provider = provider.aws
  8144  
  8145    Outputs:
  8146  
  8147    instance_id = foo
  8148  `)
  8149  }
  8150  
  8151  func TestContext2Apply_targetedModuleResource(t *testing.T) {
  8152  	m := testModule(t, "apply-targeted-module-resource")
  8153  	p := testProvider("aws")
  8154  	p.ApplyFn = testApplyFn
  8155  	p.DiffFn = testDiffFn
  8156  	ctx := testContext2(t, &ContextOpts{
  8157  		Module: m,
  8158  		ProviderResolver: ResourceProviderResolverFixed(
  8159  			map[string]ResourceProviderFactory{
  8160  				"aws": testProviderFuncFixed(p),
  8161  			},
  8162  		),
  8163  		Targets: []string{"module.child.aws_instance.foo"},
  8164  	})
  8165  
  8166  	if _, err := ctx.Plan(); err != nil {
  8167  		t.Fatalf("err: %s", err)
  8168  	}
  8169  
  8170  	state, err := ctx.Apply()
  8171  	if err != nil {
  8172  		t.Fatalf("err: %s", err)
  8173  	}
  8174  
  8175  	mod := state.ModuleByPath([]string{"root", "child"})
  8176  	if mod == nil || len(mod.Resources) != 1 {
  8177  		t.Fatalf("expected 1 resource, got: %#v", mod)
  8178  	}
  8179  
  8180  	checkStateString(t, state, `
  8181  <no state>
  8182  module.child:
  8183    aws_instance.foo:
  8184      ID = foo
  8185      provider = provider.aws
  8186      num = 2
  8187      type = aws_instance
  8188  	`)
  8189  }
  8190  
  8191  func TestContext2Apply_unknownAttribute(t *testing.T) {
  8192  	m := testModule(t, "apply-unknown")
  8193  	p := testProvider("aws")
  8194  	p.ApplyFn = testApplyFn
  8195  	p.DiffFn = testDiffFn
  8196  	ctx := testContext2(t, &ContextOpts{
  8197  		Module: m,
  8198  		ProviderResolver: ResourceProviderResolverFixed(
  8199  			map[string]ResourceProviderFactory{
  8200  				"aws": testProviderFuncFixed(p),
  8201  			},
  8202  		),
  8203  	})
  8204  
  8205  	if _, err := ctx.Plan(); err != nil {
  8206  		t.Fatalf("err: %s", err)
  8207  	}
  8208  
  8209  	state, err := ctx.Apply()
  8210  	if err == nil {
  8211  		t.Fatal("should error")
  8212  	}
  8213  
  8214  	actual := strings.TrimSpace(state.String())
  8215  	expected := strings.TrimSpace(testTerraformApplyUnknownAttrStr)
  8216  	if actual != expected {
  8217  		t.Fatalf("bad: \n%s", actual)
  8218  	}
  8219  }
  8220  
  8221  func TestContext2Apply_unknownAttributeInterpolate(t *testing.T) {
  8222  	m := testModule(t, "apply-unknown-interpolate")
  8223  	p := testProvider("aws")
  8224  	p.ApplyFn = testApplyFn
  8225  	p.DiffFn = testDiffFn
  8226  	ctx := testContext2(t, &ContextOpts{
  8227  		Module: m,
  8228  		ProviderResolver: ResourceProviderResolverFixed(
  8229  			map[string]ResourceProviderFactory{
  8230  				"aws": testProviderFuncFixed(p),
  8231  			},
  8232  		),
  8233  	})
  8234  
  8235  	if _, err := ctx.Plan(); err == nil {
  8236  		t.Fatal("should error")
  8237  	}
  8238  }
  8239  
  8240  func TestContext2Apply_vars(t *testing.T) {
  8241  	m := testModule(t, "apply-vars")
  8242  	p := testProvider("aws")
  8243  	p.ApplyFn = testApplyFn
  8244  	p.DiffFn = testDiffFn
  8245  	ctx := testContext2(t, &ContextOpts{
  8246  		Module: m,
  8247  		ProviderResolver: ResourceProviderResolverFixed(
  8248  			map[string]ResourceProviderFactory{
  8249  				"aws": testProviderFuncFixed(p),
  8250  			},
  8251  		),
  8252  		Variables: map[string]interface{}{
  8253  			"foo":       "us-west-2",
  8254  			"test_list": []interface{}{"Hello", "World"},
  8255  			"test_map": map[string]interface{}{
  8256  				"Hello": "World",
  8257  				"Foo":   "Bar",
  8258  				"Baz":   "Foo",
  8259  			},
  8260  			"amis": []map[string]interface{}{
  8261  				map[string]interface{}{
  8262  					"us-east-1": "override",
  8263  				},
  8264  			},
  8265  		},
  8266  	})
  8267  
  8268  	diags := ctx.Validate()
  8269  	if len(diags) != 0 {
  8270  		t.Fatalf("bad: %#v", diags)
  8271  	}
  8272  
  8273  	if _, err := ctx.Plan(); err != nil {
  8274  		t.Fatalf("err: %s", err)
  8275  	}
  8276  
  8277  	state, err := ctx.Apply()
  8278  	if err != nil {
  8279  		t.Fatalf("err: %s", err)
  8280  	}
  8281  
  8282  	actual := strings.TrimSpace(state.String())
  8283  	expected := strings.TrimSpace(testTerraformApplyVarsStr)
  8284  	if actual != expected {
  8285  		t.Fatalf("expected: %s\n got:\n%s", expected, actual)
  8286  	}
  8287  }
  8288  
  8289  func TestContext2Apply_varsEnv(t *testing.T) {
  8290  	// Set the env var
  8291  	defer tempEnv(t, "TF_VAR_ami", "baz")()
  8292  	defer tempEnv(t, "TF_VAR_list", `["Hello", "World"]`)()
  8293  	defer tempEnv(t, "TF_VAR_map", `{"Hello" = "World", "Foo" = "Bar", "Baz" = "Foo"}`)()
  8294  
  8295  	m := testModule(t, "apply-vars-env")
  8296  	p := testProvider("aws")
  8297  	p.ApplyFn = testApplyFn
  8298  	p.DiffFn = testDiffFn
  8299  	ctx := testContext2(t, &ContextOpts{
  8300  		Module: m,
  8301  		ProviderResolver: ResourceProviderResolverFixed(
  8302  			map[string]ResourceProviderFactory{
  8303  				"aws": testProviderFuncFixed(p),
  8304  			},
  8305  		),
  8306  	})
  8307  
  8308  	diags := ctx.Validate()
  8309  	if len(diags) != 0 {
  8310  		t.Fatalf("bad: %#v", diags)
  8311  	}
  8312  
  8313  	if _, err := ctx.Plan(); err != nil {
  8314  		t.Fatalf("err: %s", err)
  8315  	}
  8316  
  8317  	state, err := ctx.Apply()
  8318  	if err != nil {
  8319  		t.Fatalf("err: %s", err)
  8320  	}
  8321  
  8322  	actual := strings.TrimSpace(state.String())
  8323  	expected := strings.TrimSpace(testTerraformApplyVarsEnvStr)
  8324  	if actual != expected {
  8325  		t.Fatalf("bad: \n%s", actual)
  8326  	}
  8327  }
  8328  
  8329  func TestContext2Apply_createBefore_depends(t *testing.T) {
  8330  	m := testModule(t, "apply-depends-create-before")
  8331  	h := new(HookRecordApplyOrder)
  8332  	p := testProvider("aws")
  8333  	p.ApplyFn = testApplyFn
  8334  	p.DiffFn = testDiffFn
  8335  	state := &State{
  8336  		Modules: []*ModuleState{
  8337  			&ModuleState{
  8338  				Path: rootModulePath,
  8339  				Resources: map[string]*ResourceState{
  8340  					"aws_instance.web": &ResourceState{
  8341  						Type: "aws_instance",
  8342  						Primary: &InstanceState{
  8343  							ID: "bar",
  8344  							Attributes: map[string]string{
  8345  								"require_new": "ami-old",
  8346  							},
  8347  						},
  8348  					},
  8349  					"aws_instance.lb": &ResourceState{
  8350  						Type: "aws_instance",
  8351  						Primary: &InstanceState{
  8352  							ID: "baz",
  8353  							Attributes: map[string]string{
  8354  								"instance": "bar",
  8355  							},
  8356  						},
  8357  					},
  8358  				},
  8359  			},
  8360  		},
  8361  	}
  8362  	ctx := testContext2(t, &ContextOpts{
  8363  		Module: m,
  8364  		Hooks:  []Hook{h},
  8365  		ProviderResolver: ResourceProviderResolverFixed(
  8366  			map[string]ResourceProviderFactory{
  8367  				"aws": testProviderFuncFixed(p),
  8368  			},
  8369  		),
  8370  		State: state,
  8371  	})
  8372  
  8373  	if p, err := ctx.Plan(); err != nil {
  8374  		t.Fatalf("err: %s", err)
  8375  	} else {
  8376  		t.Logf("plan: %s", p)
  8377  	}
  8378  
  8379  	h.Active = true
  8380  	state, err := ctx.Apply()
  8381  	if err != nil {
  8382  		t.Fatalf("err: %s", err)
  8383  	}
  8384  
  8385  	mod := state.RootModule()
  8386  	if len(mod.Resources) < 2 {
  8387  		t.Fatalf("bad: %#v", mod.Resources)
  8388  	}
  8389  
  8390  	actual := strings.TrimSpace(state.String())
  8391  	expected := strings.TrimSpace(testTerraformApplyDependsCreateBeforeStr)
  8392  	if actual != expected {
  8393  		t.Fatalf("bad: \n%s\n\n%s", actual, expected)
  8394  	}
  8395  
  8396  	// Test that things were managed _in the right order_
  8397  	order := h.States
  8398  	diffs := h.Diffs
  8399  	if order[0].ID != "" || diffs[0].Destroy {
  8400  		t.Fatalf("should create new instance first: %#v", order)
  8401  	}
  8402  
  8403  	if order[1].ID != "baz" {
  8404  		t.Fatalf("update must happen after create: %#v", order)
  8405  	}
  8406  
  8407  	if order[2].ID != "bar" || !diffs[2].Destroy {
  8408  		t.Fatalf("destroy must happen after update: %#v", order)
  8409  	}
  8410  }
  8411  
  8412  func TestContext2Apply_singleDestroy(t *testing.T) {
  8413  	m := testModule(t, "apply-depends-create-before")
  8414  	h := new(HookRecordApplyOrder)
  8415  	p := testProvider("aws")
  8416  
  8417  	invokeCount := 0
  8418  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  8419  		invokeCount++
  8420  		switch invokeCount {
  8421  		case 1:
  8422  			if d.Destroy {
  8423  				t.Fatalf("should not destroy")
  8424  			}
  8425  			if s.ID != "" {
  8426  				t.Fatalf("should not have ID")
  8427  			}
  8428  		case 2:
  8429  			if d.Destroy {
  8430  				t.Fatalf("should not destroy")
  8431  			}
  8432  			if s.ID != "baz" {
  8433  				t.Fatalf("should have id")
  8434  			}
  8435  		case 3:
  8436  			if !d.Destroy {
  8437  				t.Fatalf("should destroy")
  8438  			}
  8439  			if s.ID == "" {
  8440  				t.Fatalf("should have ID")
  8441  			}
  8442  		default:
  8443  			t.Fatalf("bad invoke count %d", invokeCount)
  8444  		}
  8445  		return testApplyFn(info, s, d)
  8446  	}
  8447  	p.DiffFn = testDiffFn
  8448  	state := &State{
  8449  		Modules: []*ModuleState{
  8450  			&ModuleState{
  8451  				Path: rootModulePath,
  8452  				Resources: map[string]*ResourceState{
  8453  					"aws_instance.web": &ResourceState{
  8454  						Type: "aws_instance",
  8455  						Primary: &InstanceState{
  8456  							ID: "bar",
  8457  							Attributes: map[string]string{
  8458  								"require_new": "ami-old",
  8459  							},
  8460  						},
  8461  					},
  8462  					"aws_instance.lb": &ResourceState{
  8463  						Type: "aws_instance",
  8464  						Primary: &InstanceState{
  8465  							ID: "baz",
  8466  							Attributes: map[string]string{
  8467  								"instance": "bar",
  8468  							},
  8469  						},
  8470  					},
  8471  				},
  8472  			},
  8473  		},
  8474  	}
  8475  	ctx := testContext2(t, &ContextOpts{
  8476  		Module: m,
  8477  		Hooks:  []Hook{h},
  8478  		ProviderResolver: ResourceProviderResolverFixed(
  8479  			map[string]ResourceProviderFactory{
  8480  				"aws": testProviderFuncFixed(p),
  8481  			},
  8482  		),
  8483  		State: state,
  8484  	})
  8485  
  8486  	if _, err := ctx.Plan(); err != nil {
  8487  		t.Fatalf("err: %s", err)
  8488  	}
  8489  
  8490  	h.Active = true
  8491  	state, err := ctx.Apply()
  8492  	if err != nil {
  8493  		t.Fatalf("err: %s", err)
  8494  	}
  8495  
  8496  	if invokeCount != 3 {
  8497  		t.Fatalf("bad: %d", invokeCount)
  8498  	}
  8499  }
  8500  
  8501  // GH-7824
  8502  func TestContext2Apply_issue7824(t *testing.T) {
  8503  	p := testProvider("template")
  8504  	p.ResourcesReturn = append(p.ResourcesReturn, ResourceType{
  8505  		Name: "template_file",
  8506  	})
  8507  
  8508  	p.ApplyFn = testApplyFn
  8509  	p.DiffFn = testDiffFn
  8510  
  8511  	// Apply cleanly step 0
  8512  	ctx := testContext2(t, &ContextOpts{
  8513  		Module: testModule(t, "issue-7824"),
  8514  		ProviderResolver: ResourceProviderResolverFixed(
  8515  			map[string]ResourceProviderFactory{
  8516  				"template": testProviderFuncFixed(p),
  8517  			},
  8518  		),
  8519  	})
  8520  
  8521  	plan, err := ctx.Plan()
  8522  	if err != nil {
  8523  		t.Fatalf("err: %s", err)
  8524  	}
  8525  
  8526  	// Write / Read plan to simulate running it through a Plan file
  8527  	var buf bytes.Buffer
  8528  	if err := WritePlan(plan, &buf); err != nil {
  8529  		t.Fatalf("err: %s", err)
  8530  	}
  8531  
  8532  	planFromFile, err := ReadPlan(&buf)
  8533  	if err != nil {
  8534  		t.Fatalf("err: %s", err)
  8535  	}
  8536  
  8537  	ctx, err = planFromFile.Context(&ContextOpts{
  8538  		ProviderResolver: ResourceProviderResolverFixed(
  8539  			map[string]ResourceProviderFactory{
  8540  				"template": testProviderFuncFixed(p),
  8541  			},
  8542  		),
  8543  	})
  8544  	if err != nil {
  8545  		t.Fatalf("err: %s", err)
  8546  	}
  8547  
  8548  	_, err = ctx.Apply()
  8549  	if err != nil {
  8550  		t.Fatalf("err: %s", err)
  8551  	}
  8552  }
  8553  
  8554  // GH-5254
  8555  func TestContext2Apply_issue5254(t *testing.T) {
  8556  	// Create a provider. We use "template" here just to match the repro
  8557  	// we got from the issue itself.
  8558  	p := testProvider("template")
  8559  	p.ResourcesReturn = append(p.ResourcesReturn, ResourceType{
  8560  		Name: "template_file",
  8561  	})
  8562  
  8563  	p.ApplyFn = testApplyFn
  8564  	p.DiffFn = testDiffFn
  8565  
  8566  	// Apply cleanly step 0
  8567  	ctx := testContext2(t, &ContextOpts{
  8568  		Module: testModule(t, "issue-5254/step-0"),
  8569  		ProviderResolver: ResourceProviderResolverFixed(
  8570  			map[string]ResourceProviderFactory{
  8571  				"template": testProviderFuncFixed(p),
  8572  			},
  8573  		),
  8574  	})
  8575  
  8576  	plan, err := ctx.Plan()
  8577  	if err != nil {
  8578  		t.Fatalf("err: %s", err)
  8579  	}
  8580  
  8581  	state, err := ctx.Apply()
  8582  	if err != nil {
  8583  		t.Fatalf("err: %s", err)
  8584  	}
  8585  
  8586  	// Application success. Now make the modification and store a plan
  8587  	ctx = testContext2(t, &ContextOpts{
  8588  		Module: testModule(t, "issue-5254/step-1"),
  8589  		State:  state,
  8590  		ProviderResolver: ResourceProviderResolverFixed(
  8591  			map[string]ResourceProviderFactory{
  8592  				"template": testProviderFuncFixed(p),
  8593  			},
  8594  		),
  8595  	})
  8596  
  8597  	plan, err = ctx.Plan()
  8598  	if err != nil {
  8599  		t.Fatalf("err: %s", err)
  8600  	}
  8601  
  8602  	// Write / Read plan to simulate running it through a Plan file
  8603  	var buf bytes.Buffer
  8604  	if err := WritePlan(plan, &buf); err != nil {
  8605  		t.Fatalf("err: %s", err)
  8606  	}
  8607  
  8608  	planFromFile, err := ReadPlan(&buf)
  8609  	if err != nil {
  8610  		t.Fatalf("err: %s", err)
  8611  	}
  8612  
  8613  	ctx, err = planFromFile.Context(&ContextOpts{
  8614  		ProviderResolver: ResourceProviderResolverFixed(
  8615  			map[string]ResourceProviderFactory{
  8616  				"template": testProviderFuncFixed(p),
  8617  			},
  8618  		),
  8619  	})
  8620  	if err != nil {
  8621  		t.Fatalf("err: %s", err)
  8622  	}
  8623  
  8624  	state, err = ctx.Apply()
  8625  	if err != nil {
  8626  		t.Fatalf("err: %s", err)
  8627  	}
  8628  
  8629  	actual := strings.TrimSpace(state.String())
  8630  	expected := strings.TrimSpace(`
  8631  template_file.child:
  8632    ID = foo
  8633    provider = provider.template
  8634    template = Hi
  8635    type = template_file
  8636  
  8637    Dependencies:
  8638      template_file.parent.*
  8639  template_file.parent:
  8640    ID = foo
  8641    provider = provider.template
  8642    template = Hi
  8643    type = template_file
  8644  		`)
  8645  	if actual != expected {
  8646  		t.Fatalf("expected state: \n%s\ngot: \n%s", expected, actual)
  8647  	}
  8648  }
  8649  
  8650  func TestContext2Apply_targetedWithTaintedInState(t *testing.T) {
  8651  	p := testProvider("aws")
  8652  	p.DiffFn = testDiffFn
  8653  	p.ApplyFn = testApplyFn
  8654  	ctx := testContext2(t, &ContextOpts{
  8655  		Module: testModule(t, "apply-tainted-targets"),
  8656  		ProviderResolver: ResourceProviderResolverFixed(
  8657  			map[string]ResourceProviderFactory{
  8658  				"aws": testProviderFuncFixed(p),
  8659  			},
  8660  		),
  8661  		Targets: []string{"aws_instance.iambeingadded"},
  8662  		State: &State{
  8663  			Modules: []*ModuleState{
  8664  				&ModuleState{
  8665  					Path: rootModulePath,
  8666  					Resources: map[string]*ResourceState{
  8667  						"aws_instance.ifailedprovisioners": &ResourceState{
  8668  							Type: "aws_instance",
  8669  							Primary: &InstanceState{
  8670  								ID:      "ifailedprovisioners",
  8671  								Tainted: true,
  8672  							},
  8673  						},
  8674  					},
  8675  				},
  8676  			},
  8677  		},
  8678  	})
  8679  
  8680  	plan, err := ctx.Plan()
  8681  	if err != nil {
  8682  		t.Fatalf("err: %s", err)
  8683  	}
  8684  
  8685  	// Write / Read plan to simulate running it through a Plan file
  8686  	var buf bytes.Buffer
  8687  	if err := WritePlan(plan, &buf); err != nil {
  8688  		t.Fatalf("err: %s", err)
  8689  	}
  8690  
  8691  	planFromFile, err := ReadPlan(&buf)
  8692  	if err != nil {
  8693  		t.Fatalf("err: %s", err)
  8694  	}
  8695  
  8696  	ctx, err = planFromFile.Context(&ContextOpts{
  8697  		Module: testModule(t, "apply-tainted-targets"),
  8698  		ProviderResolver: ResourceProviderResolverFixed(
  8699  			map[string]ResourceProviderFactory{
  8700  				"aws": testProviderFuncFixed(p),
  8701  			},
  8702  		),
  8703  	})
  8704  	if err != nil {
  8705  		t.Fatalf("err: %s", err)
  8706  	}
  8707  
  8708  	state, err := ctx.Apply()
  8709  	if err != nil {
  8710  		t.Fatalf("err: %s", err)
  8711  	}
  8712  
  8713  	actual := strings.TrimSpace(state.String())
  8714  	expected := strings.TrimSpace(`
  8715  aws_instance.iambeingadded:
  8716    ID = foo
  8717    provider = provider.aws
  8718  aws_instance.ifailedprovisioners: (tainted)
  8719    ID = ifailedprovisioners
  8720  		`)
  8721  	if actual != expected {
  8722  		t.Fatalf("expected state: \n%s\ngot: \n%s", expected, actual)
  8723  	}
  8724  }
  8725  
  8726  // Higher level test exposing the bug this covers in
  8727  // TestResource_ignoreChangesRequired
  8728  func TestContext2Apply_ignoreChangesCreate(t *testing.T) {
  8729  	m := testModule(t, "apply-ignore-changes-create")
  8730  	p := testProvider("aws")
  8731  	p.ApplyFn = testApplyFn
  8732  	p.DiffFn = testDiffFn
  8733  	ctx := testContext2(t, &ContextOpts{
  8734  		Module: m,
  8735  		ProviderResolver: ResourceProviderResolverFixed(
  8736  			map[string]ResourceProviderFactory{
  8737  				"aws": testProviderFuncFixed(p),
  8738  			},
  8739  		),
  8740  	})
  8741  
  8742  	if p, err := ctx.Plan(); err != nil {
  8743  		t.Fatalf("err: %s", err)
  8744  	} else {
  8745  		t.Logf(p.String())
  8746  	}
  8747  
  8748  	state, err := ctx.Apply()
  8749  	if err != nil {
  8750  		t.Fatalf("err: %s", err)
  8751  	}
  8752  
  8753  	mod := state.RootModule()
  8754  	if len(mod.Resources) != 1 {
  8755  		t.Fatalf("bad: %s", state)
  8756  	}
  8757  
  8758  	actual := strings.TrimSpace(state.String())
  8759  	// Expect no changes from original state
  8760  	expected := strings.TrimSpace(`
  8761  aws_instance.foo:
  8762    ID = foo
  8763    provider = provider.aws
  8764    required_field = set
  8765    type = aws_instance
  8766  `)
  8767  	if actual != expected {
  8768  		t.Fatalf("expected:\n%s\ngot:\n%s", expected, actual)
  8769  	}
  8770  }
  8771  
  8772  func TestContext2Apply_ignoreChangesWithDep(t *testing.T) {
  8773  	m := testModule(t, "apply-ignore-changes-dep")
  8774  	p := testProvider("aws")
  8775  	p.ApplyFn = testApplyFn
  8776  	p.DiffFn = func(i *InstanceInfo, s *InstanceState, c *ResourceConfig) (*InstanceDiff, error) {
  8777  		switch i.Type {
  8778  		case "aws_instance":
  8779  			newAmi, _ := c.Get("ami")
  8780  			return &InstanceDiff{
  8781  				Attributes: map[string]*ResourceAttrDiff{
  8782  					"ami": &ResourceAttrDiff{
  8783  						Old:         s.Attributes["ami"],
  8784  						New:         newAmi.(string),
  8785  						RequiresNew: true,
  8786  					},
  8787  				},
  8788  			}, nil
  8789  		case "aws_eip":
  8790  			return testDiffFn(i, s, c)
  8791  		default:
  8792  			t.Fatalf("Unexpected type: %s", i.Type)
  8793  			return nil, nil
  8794  		}
  8795  	}
  8796  	s := &State{
  8797  		Modules: []*ModuleState{
  8798  			&ModuleState{
  8799  				Path: rootModulePath,
  8800  				Resources: map[string]*ResourceState{
  8801  					"aws_instance.foo.0": &ResourceState{
  8802  						Type: "aws_instance",
  8803  						Primary: &InstanceState{
  8804  							ID: "i-abc123",
  8805  							Attributes: map[string]string{
  8806  								"ami": "ami-abcd1234",
  8807  								"id":  "i-abc123",
  8808  							},
  8809  						},
  8810  					},
  8811  					"aws_instance.foo.1": &ResourceState{
  8812  						Type: "aws_instance",
  8813  						Primary: &InstanceState{
  8814  							ID: "i-bcd234",
  8815  							Attributes: map[string]string{
  8816  								"ami": "ami-abcd1234",
  8817  								"id":  "i-bcd234",
  8818  							},
  8819  						},
  8820  					},
  8821  					"aws_eip.foo.0": &ResourceState{
  8822  						Type: "aws_instance",
  8823  						Primary: &InstanceState{
  8824  							ID: "eip-abc123",
  8825  							Attributes: map[string]string{
  8826  								"id":       "eip-abc123",
  8827  								"instance": "i-abc123",
  8828  							},
  8829  						},
  8830  					},
  8831  					"aws_eip.foo.1": &ResourceState{
  8832  						Type: "aws_instance",
  8833  						Primary: &InstanceState{
  8834  							ID: "eip-bcd234",
  8835  							Attributes: map[string]string{
  8836  								"id":       "eip-bcd234",
  8837  								"instance": "i-bcd234",
  8838  							},
  8839  						},
  8840  					},
  8841  				},
  8842  			},
  8843  		},
  8844  	}
  8845  	ctx := testContext2(t, &ContextOpts{
  8846  		Module: m,
  8847  		ProviderResolver: ResourceProviderResolverFixed(
  8848  			map[string]ResourceProviderFactory{
  8849  				"aws": testProviderFuncFixed(p),
  8850  			},
  8851  		),
  8852  		State: s,
  8853  	})
  8854  
  8855  	if p, err := ctx.Plan(); err != nil {
  8856  		t.Fatalf("err: %s", err)
  8857  	} else {
  8858  		t.Logf(p.String())
  8859  	}
  8860  
  8861  	state, err := ctx.Apply()
  8862  	if err != nil {
  8863  		t.Fatalf("err: %s", err)
  8864  	}
  8865  
  8866  	actual := strings.TrimSpace(state.String())
  8867  	expected := strings.TrimSpace(s.String())
  8868  	if actual != expected {
  8869  		t.Fatalf("bad: \n%s", actual)
  8870  	}
  8871  }
  8872  
  8873  func TestContext2Apply_ignoreChangesWildcard(t *testing.T) {
  8874  	m := testModule(t, "apply-ignore-changes-wildcard")
  8875  	p := testProvider("aws")
  8876  	p.ApplyFn = testApplyFn
  8877  	p.DiffFn = testDiffFn
  8878  	ctx := testContext2(t, &ContextOpts{
  8879  		Module: m,
  8880  		ProviderResolver: ResourceProviderResolverFixed(
  8881  			map[string]ResourceProviderFactory{
  8882  				"aws": testProviderFuncFixed(p),
  8883  			},
  8884  		),
  8885  	})
  8886  
  8887  	if p, err := ctx.Plan(); err != nil {
  8888  		t.Fatalf("err: %s", err)
  8889  	} else {
  8890  		t.Logf(p.String())
  8891  	}
  8892  
  8893  	state, err := ctx.Apply()
  8894  	if err != nil {
  8895  		t.Fatalf("err: %s", err)
  8896  	}
  8897  
  8898  	mod := state.RootModule()
  8899  	if len(mod.Resources) != 1 {
  8900  		t.Fatalf("bad: %s", state)
  8901  	}
  8902  
  8903  	actual := strings.TrimSpace(state.String())
  8904  	// Expect no changes from original state
  8905  	expected := strings.TrimSpace(`
  8906  aws_instance.foo:
  8907    ID = foo
  8908    provider = provider.aws
  8909    required_field = set
  8910    type = aws_instance
  8911  `)
  8912  	if actual != expected {
  8913  		t.Fatalf("expected:\n%s\ngot:\n%s", expected, actual)
  8914  	}
  8915  }
  8916  
  8917  // https://github.com/hashicorp/terraform/issues/7378
  8918  func TestContext2Apply_destroyNestedModuleWithAttrsReferencingResource(t *testing.T) {
  8919  	m := testModule(t, "apply-destroy-nested-module-with-attrs")
  8920  	p := testProvider("null")
  8921  	p.ApplyFn = testApplyFn
  8922  	p.DiffFn = testDiffFn
  8923  
  8924  	var state *State
  8925  	var err error
  8926  	{
  8927  		ctx := testContext2(t, &ContextOpts{
  8928  			Module: m,
  8929  			ProviderResolver: ResourceProviderResolverFixed(
  8930  				map[string]ResourceProviderFactory{
  8931  					"null": testProviderFuncFixed(p),
  8932  				},
  8933  			),
  8934  		})
  8935  
  8936  		// First plan and apply a create operation
  8937  		if _, err := ctx.Plan(); err != nil {
  8938  			t.Fatalf("plan err: %s", err)
  8939  		}
  8940  
  8941  		state, err = ctx.Apply()
  8942  		if err != nil {
  8943  			t.Fatalf("apply err: %s", err)
  8944  		}
  8945  	}
  8946  
  8947  	{
  8948  		ctx := testContext2(t, &ContextOpts{
  8949  			Destroy: true,
  8950  			Module:  m,
  8951  			State:   state,
  8952  			ProviderResolver: ResourceProviderResolverFixed(
  8953  				map[string]ResourceProviderFactory{
  8954  					"null": testProviderFuncFixed(p),
  8955  				},
  8956  			),
  8957  		})
  8958  
  8959  		plan, err := ctx.Plan()
  8960  		if err != nil {
  8961  			t.Fatalf("destroy plan err: %s", err)
  8962  		}
  8963  
  8964  		var buf bytes.Buffer
  8965  		if err := WritePlan(plan, &buf); err != nil {
  8966  			t.Fatalf("plan write err: %s", err)
  8967  		}
  8968  
  8969  		planFromFile, err := ReadPlan(&buf)
  8970  		if err != nil {
  8971  			t.Fatalf("plan read err: %s", err)
  8972  		}
  8973  
  8974  		ctx, err = planFromFile.Context(&ContextOpts{
  8975  			ProviderResolver: ResourceProviderResolverFixed(
  8976  				map[string]ResourceProviderFactory{
  8977  					"null": testProviderFuncFixed(p),
  8978  				},
  8979  			),
  8980  		})
  8981  		if err != nil {
  8982  			t.Fatalf("err: %s", err)
  8983  		}
  8984  
  8985  		state, err = ctx.Apply()
  8986  		if err != nil {
  8987  			t.Fatalf("destroy apply err: %s", err)
  8988  		}
  8989  	}
  8990  
  8991  	//Test that things were destroyed
  8992  	actual := strings.TrimSpace(state.String())
  8993  	expected := strings.TrimSpace(`
  8994  <no state>
  8995  module.middle:
  8996    <no state>
  8997  module.middle.bottom:
  8998    <no state>
  8999  		`)
  9000  	if actual != expected {
  9001  		t.Fatalf("expected: \n%s\n\nbad: \n%s", expected, actual)
  9002  	}
  9003  }
  9004  
  9005  // If a data source explicitly depends on another resource, it's because we need
  9006  // that resource to be applied first.
  9007  func TestContext2Apply_dataDependsOn(t *testing.T) {
  9008  	p := testProvider("null")
  9009  	m := testModule(t, "apply-data-depends-on")
  9010  
  9011  	ctx := testContext2(t, &ContextOpts{
  9012  		Module: m,
  9013  		ProviderResolver: ResourceProviderResolverFixed(
  9014  			map[string]ResourceProviderFactory{
  9015  				"null": testProviderFuncFixed(p),
  9016  			},
  9017  		),
  9018  	})
  9019  
  9020  	// the "provisioner" here writes to this variable, because the intent is to
  9021  	// create a dependency which can't be viewed through the graph, and depends
  9022  	// solely on the configuration providing "depends_on"
  9023  	provisionerOutput := ""
  9024  
  9025  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  9026  		// the side effect of the resource being applied
  9027  		provisionerOutput = "APPLIED"
  9028  		return testApplyFn(info, s, d)
  9029  	}
  9030  
  9031  	p.DiffFn = testDiffFn
  9032  	p.ReadDataDiffFn = testDataDiffFn
  9033  
  9034  	p.ReadDataApplyFn = func(*InstanceInfo, *InstanceDiff) (*InstanceState, error) {
  9035  		// Read the artifact created by our dependency being applied.
  9036  		// Without any "depends_on", this would be skipped as it's assumed the
  9037  		// initial diff during refresh was all that's needed.
  9038  		return &InstanceState{
  9039  			ID: "read",
  9040  			Attributes: map[string]string{
  9041  				"foo": provisionerOutput,
  9042  			},
  9043  		}, nil
  9044  	}
  9045  
  9046  	_, err := ctx.Refresh()
  9047  	if err != nil {
  9048  		t.Fatalf("err: %s", err)
  9049  	}
  9050  
  9051  	if _, err := ctx.Plan(); err != nil {
  9052  		t.Fatalf("err: %s", err)
  9053  	}
  9054  
  9055  	state, err := ctx.Apply()
  9056  	if err != nil {
  9057  		t.Fatalf("err: %s", err)
  9058  	}
  9059  
  9060  	root := state.ModuleByPath(RootModulePath)
  9061  	actual := root.Resources["data.null_data_source.read"].Primary.Attributes["foo"]
  9062  
  9063  	expected := "APPLIED"
  9064  	if actual != expected {
  9065  		t.Fatalf("bad:\n%s", strings.TrimSpace(state.String()))
  9066  	}
  9067  }
  9068  
  9069  func TestContext2Apply_terraformEnv(t *testing.T) {
  9070  	m := testModule(t, "apply-terraform-env")
  9071  	p := testProvider("aws")
  9072  	p.ApplyFn = testApplyFn
  9073  	p.DiffFn = testDiffFn
  9074  
  9075  	ctx := testContext2(t, &ContextOpts{
  9076  		Meta:   &ContextMeta{Env: "foo"},
  9077  		Module: m,
  9078  		ProviderResolver: ResourceProviderResolverFixed(
  9079  			map[string]ResourceProviderFactory{
  9080  				"aws": testProviderFuncFixed(p),
  9081  			},
  9082  		),
  9083  	})
  9084  
  9085  	if _, err := ctx.Plan(); err != nil {
  9086  		t.Fatalf("err: %s", err)
  9087  	}
  9088  
  9089  	state, err := ctx.Apply()
  9090  	if err != nil {
  9091  		t.Fatalf("err: %s", err)
  9092  	}
  9093  
  9094  	actual := state.RootModule().Outputs["output"]
  9095  	expected := "foo"
  9096  	if actual == nil || actual.Value != expected {
  9097  		t.Fatalf("bad: \n%s", actual)
  9098  	}
  9099  }
  9100  
  9101  // verify that multiple config references only create a single depends_on entry
  9102  func TestContext2Apply_multiRef(t *testing.T) {
  9103  	m := testModule(t, "apply-multi-ref")
  9104  	p := testProvider("aws")
  9105  	p.ApplyFn = testApplyFn
  9106  	p.DiffFn = testDiffFn
  9107  
  9108  	ctx := testContext2(t, &ContextOpts{
  9109  		Module: m,
  9110  		ProviderResolver: ResourceProviderResolverFixed(
  9111  			map[string]ResourceProviderFactory{
  9112  				"aws": testProviderFuncFixed(p),
  9113  			},
  9114  		),
  9115  	})
  9116  
  9117  	if _, err := ctx.Plan(); err != nil {
  9118  		t.Fatalf("err: %s", err)
  9119  	}
  9120  
  9121  	state, err := ctx.Apply()
  9122  	if err != nil {
  9123  		t.Fatalf("err: %s", err)
  9124  	}
  9125  
  9126  	deps := state.Modules[0].Resources["aws_instance.other"].Dependencies
  9127  	if len(deps) > 1 || deps[0] != "aws_instance.create" {
  9128  		t.Fatalf("expected 1 depends_on entry for aws_instance.create, got %q", deps)
  9129  	}
  9130  }
  9131  
  9132  func TestContext2Apply_targetedModuleRecursive(t *testing.T) {
  9133  	m := testModule(t, "apply-targeted-module-recursive")
  9134  	p := testProvider("aws")
  9135  	p.ApplyFn = testApplyFn
  9136  	p.DiffFn = testDiffFn
  9137  	ctx := testContext2(t, &ContextOpts{
  9138  		Module: m,
  9139  		ProviderResolver: ResourceProviderResolverFixed(
  9140  			map[string]ResourceProviderFactory{
  9141  				"aws": testProviderFuncFixed(p),
  9142  			},
  9143  		),
  9144  		Targets: []string{"module.child"},
  9145  	})
  9146  
  9147  	if _, err := ctx.Plan(); err != nil {
  9148  		t.Fatalf("err: %s", err)
  9149  	}
  9150  
  9151  	state, err := ctx.Apply()
  9152  	if err != nil {
  9153  		t.Fatalf("err: %s", err)
  9154  	}
  9155  
  9156  	mod := state.ModuleByPath([]string{"root", "child", "subchild"})
  9157  	if mod == nil {
  9158  		t.Fatalf("no subchild module found in the state!\n\n%#v", state)
  9159  	}
  9160  	if len(mod.Resources) != 1 {
  9161  		t.Fatalf("expected 1 resources, got: %#v", mod.Resources)
  9162  	}
  9163  
  9164  	checkStateString(t, state, `
  9165  <no state>
  9166  module.child.subchild:
  9167    aws_instance.foo:
  9168      ID = foo
  9169      provider = provider.aws
  9170      num = 2
  9171      type = aws_instance
  9172  	`)
  9173  }
  9174  
  9175  func TestContext2Apply_localVal(t *testing.T) {
  9176  	m := testModule(t, "apply-local-val")
  9177  	ctx := testContext2(t, &ContextOpts{
  9178  		Module: m,
  9179  		ProviderResolver: ResourceProviderResolverFixed(
  9180  			map[string]ResourceProviderFactory{},
  9181  		),
  9182  	})
  9183  
  9184  	if _, err := ctx.Plan(); err != nil {
  9185  		t.Fatalf("error during plan: %s", err)
  9186  	}
  9187  
  9188  	state, err := ctx.Apply()
  9189  	if err != nil {
  9190  		t.Fatalf("error during apply: %s", err)
  9191  	}
  9192  
  9193  	got := strings.TrimSpace(state.String())
  9194  	want := strings.TrimSpace(`
  9195  <no state>
  9196  Outputs:
  9197  
  9198  result_1 = hello
  9199  result_3 = hello world
  9200  
  9201  module.child:
  9202    <no state>
  9203    Outputs:
  9204  
  9205    result = hello
  9206  `)
  9207  	if got != want {
  9208  		t.Fatalf("wrong final state\ngot:\n%s\nwant:\n%s", got, want)
  9209  	}
  9210  }
  9211  
  9212  func TestContext2Apply_destroyWithLocals(t *testing.T) {
  9213  	m := testModule(t, "apply-destroy-with-locals")
  9214  	p := testProvider("aws")
  9215  	p.ApplyFn = testApplyFn
  9216  	p.DiffFn = func(info *InstanceInfo, s *InstanceState, c *ResourceConfig) (*InstanceDiff, error) {
  9217  		d, err := testDiffFn(info, s, c)
  9218  		return d, err
  9219  	}
  9220  
  9221  	s := &State{
  9222  		Modules: []*ModuleState{
  9223  			&ModuleState{
  9224  				Path: rootModulePath,
  9225  				Outputs: map[string]*OutputState{
  9226  					"name": &OutputState{
  9227  						Type:  "string",
  9228  						Value: "test-bar",
  9229  					},
  9230  				},
  9231  				Resources: map[string]*ResourceState{
  9232  					"aws_instance.foo": &ResourceState{
  9233  						Type: "aws_instance",
  9234  						Primary: &InstanceState{
  9235  							ID: "foo",
  9236  							// FIXME: id should only exist in one place
  9237  							Attributes: map[string]string{
  9238  								"id": "foo",
  9239  							},
  9240  						},
  9241  					},
  9242  				},
  9243  			},
  9244  		},
  9245  	}
  9246  
  9247  	ctx := testContext2(t, &ContextOpts{
  9248  		Module: m,
  9249  		ProviderResolver: ResourceProviderResolverFixed(
  9250  			map[string]ResourceProviderFactory{
  9251  				"aws": testProviderFuncFixed(p),
  9252  			},
  9253  		),
  9254  		State:   s,
  9255  		Destroy: true,
  9256  	})
  9257  
  9258  	if _, err := ctx.Plan(); err != nil {
  9259  		t.Fatalf("err: %s", err)
  9260  	}
  9261  
  9262  	state, err := ctx.Apply()
  9263  	if err != nil {
  9264  		t.Fatalf("error during apply: %s", err)
  9265  	}
  9266  
  9267  	got := strings.TrimSpace(state.String())
  9268  	want := strings.TrimSpace(`<no state>`)
  9269  	if got != want {
  9270  		t.Fatalf("wrong final state\ngot:\n%s\nwant:\n%s", got, want)
  9271  	}
  9272  }
  9273  
  9274  func TestContext2Apply_providerWithLocals(t *testing.T) {
  9275  	m := testModule(t, "provider-with-locals")
  9276  	p := testProvider("aws")
  9277  
  9278  	providerRegion := ""
  9279  	// this should not be overridden during destroy
  9280  	p.ConfigureFn = func(c *ResourceConfig) error {
  9281  		if r, ok := c.Get("region"); ok {
  9282  			providerRegion = r.(string)
  9283  		}
  9284  		return nil
  9285  	}
  9286  	p.DiffFn = testDiffFn
  9287  	p.ApplyFn = testApplyFn
  9288  	ctx := testContext2(t, &ContextOpts{
  9289  		Module: m,
  9290  		ProviderResolver: ResourceProviderResolverFixed(
  9291  			map[string]ResourceProviderFactory{
  9292  				"aws": testProviderFuncFixed(p),
  9293  			},
  9294  		),
  9295  	})
  9296  
  9297  	if _, err := ctx.Plan(); err != nil {
  9298  		t.Fatalf("err: %s", err)
  9299  	}
  9300  
  9301  	state, err := ctx.Apply()
  9302  	if err != nil {
  9303  		t.Fatalf("err: %s", err)
  9304  	}
  9305  
  9306  	ctx = testContext2(t, &ContextOpts{
  9307  		Module: m,
  9308  		ProviderResolver: ResourceProviderResolverFixed(
  9309  			map[string]ResourceProviderFactory{
  9310  				"aws": testProviderFuncFixed(p),
  9311  			},
  9312  		),
  9313  		State:   state,
  9314  		Destroy: true,
  9315  	})
  9316  
  9317  	if _, err = ctx.Plan(); err != nil {
  9318  		t.Fatalf("err: %s", err)
  9319  	}
  9320  
  9321  	state, err = ctx.Apply()
  9322  	if err != nil {
  9323  		t.Fatalf("err: %s", err)
  9324  	}
  9325  
  9326  	if state.HasResources() {
  9327  		t.Fatal("expected no state, got:", state)
  9328  	}
  9329  
  9330  	if providerRegion != "bar" {
  9331  		t.Fatalf("expected region %q, got: %q", "bar", providerRegion)
  9332  	}
  9333  }
  9334  
  9335  func TestContext2Apply_destroyWithProviders(t *testing.T) {
  9336  	m := testModule(t, "destroy-module-with-provider")
  9337  	p := testProvider("aws")
  9338  	p.ApplyFn = testApplyFn
  9339  	p.DiffFn = testDiffFn
  9340  
  9341  	s := &State{
  9342  		Modules: []*ModuleState{
  9343  			&ModuleState{
  9344  				Path: rootModulePath,
  9345  			},
  9346  			&ModuleState{
  9347  				Path: []string{"root", "child"},
  9348  			},
  9349  			&ModuleState{
  9350  				Path: []string{"root", "mod", "removed"},
  9351  				Resources: map[string]*ResourceState{
  9352  					"aws_instance.child": &ResourceState{
  9353  						Type: "aws_instance",
  9354  						Primary: &InstanceState{
  9355  							ID: "bar",
  9356  						},
  9357  						// this provider doesn't exist
  9358  						Provider: "provider.aws.baz",
  9359  					},
  9360  				},
  9361  			},
  9362  		},
  9363  	}
  9364  
  9365  	ctx := testContext2(t, &ContextOpts{
  9366  		Module: m,
  9367  		ProviderResolver: ResourceProviderResolverFixed(
  9368  			map[string]ResourceProviderFactory{
  9369  				"aws": testProviderFuncFixed(p),
  9370  			},
  9371  		),
  9372  		State:   s,
  9373  		Destroy: true,
  9374  	})
  9375  
  9376  	// test that we can't destroy if the provider is missing
  9377  	if _, err := ctx.Plan(); err == nil {
  9378  		t.Fatal("expected plan error, provider.aws.baz doesn't exist")
  9379  	}
  9380  
  9381  	// correct the state
  9382  	s.Modules[2].Resources["aws_instance.child"].Provider = "provider.aws.bar"
  9383  
  9384  	if _, err := ctx.Plan(); err != nil {
  9385  		t.Fatal(err)
  9386  	}
  9387  	state, err := ctx.Apply()
  9388  	if err != nil {
  9389  		t.Fatalf("error during apply: %s", err)
  9390  	}
  9391  
  9392  	got := strings.TrimSpace(state.String())
  9393  
  9394  	want := strings.TrimSpace("<no state>")
  9395  	if got != want {
  9396  		t.Fatalf("wrong final state\ngot:\n%s\nwant:\n%s", got, want)
  9397  	}
  9398  }
  9399  
  9400  func TestContext2Apply_providersFromState(t *testing.T) {
  9401  	m := module.NewEmptyTree()
  9402  	p := testProvider("aws")
  9403  	p.DiffFn = testDiffFn
  9404  
  9405  	for _, tc := range []struct {
  9406  		name   string
  9407  		state  *State
  9408  		output string
  9409  		err    bool
  9410  	}{
  9411  		{
  9412  			name: "add implicit provider",
  9413  			state: &State{
  9414  				Modules: []*ModuleState{
  9415  					&ModuleState{
  9416  						Path: []string{"root"},
  9417  						Resources: map[string]*ResourceState{
  9418  							"aws_instance.a": &ResourceState{
  9419  								Type: "aws_instance",
  9420  								Primary: &InstanceState{
  9421  									ID: "bar",
  9422  								},
  9423  								Provider: "provider.aws",
  9424  							},
  9425  						},
  9426  					},
  9427  				},
  9428  			},
  9429  			err:    false,
  9430  			output: "<no state>",
  9431  		},
  9432  
  9433  		// an aliased provider must be in the config to remove a resource
  9434  		{
  9435  			name: "add aliased provider",
  9436  			state: &State{
  9437  				Modules: []*ModuleState{
  9438  					&ModuleState{
  9439  						Path: []string{"root"},
  9440  						Resources: map[string]*ResourceState{
  9441  							"aws_instance.a": &ResourceState{
  9442  								Type: "aws_instance",
  9443  								Primary: &InstanceState{
  9444  									ID: "bar",
  9445  								},
  9446  								Provider: "provider.aws.bar",
  9447  							},
  9448  						},
  9449  					},
  9450  				},
  9451  			},
  9452  			err: true,
  9453  		},
  9454  
  9455  		// a provider in a module implies some sort of config, so this isn't
  9456  		// allowed even without an alias
  9457  		{
  9458  			name: "add unaliased module provider",
  9459  			state: &State{
  9460  				Modules: []*ModuleState{
  9461  					&ModuleState{
  9462  						Path: []string{"root", "child"},
  9463  						Resources: map[string]*ResourceState{
  9464  							"aws_instance.a": &ResourceState{
  9465  								Type: "aws_instance",
  9466  								Primary: &InstanceState{
  9467  									ID: "bar",
  9468  								},
  9469  								Provider: "module.child.provider.aws",
  9470  							},
  9471  						},
  9472  					},
  9473  				},
  9474  			},
  9475  			err: true,
  9476  		},
  9477  	} {
  9478  
  9479  		t.Run(tc.name, func(t *testing.T) {
  9480  			ctx := testContext2(t, &ContextOpts{
  9481  				Module: m,
  9482  				ProviderResolver: ResourceProviderResolverFixed(
  9483  					map[string]ResourceProviderFactory{
  9484  						"aws": testProviderFuncFixed(p),
  9485  					},
  9486  				),
  9487  				State: tc.state,
  9488  			})
  9489  
  9490  			_, err := ctx.Plan()
  9491  			if tc.err {
  9492  				if err == nil {
  9493  					t.Fatal("expected error")
  9494  				} else {
  9495  					return
  9496  				}
  9497  			}
  9498  			if !tc.err && err != nil {
  9499  				t.Fatal(err)
  9500  			}
  9501  
  9502  			state, err := ctx.Apply()
  9503  			if err != nil {
  9504  				t.Fatalf("err: %s", err)
  9505  			}
  9506  
  9507  			checkStateString(t, state, "<no state>")
  9508  
  9509  		})
  9510  	}
  9511  }
  9512  
  9513  func TestContext2Apply_plannedInterpolatedCount(t *testing.T) {
  9514  	m := testModule(t, "apply-interpolated-count")
  9515  
  9516  	p := testProvider("aws")
  9517  	p.ApplyFn = testApplyFn
  9518  	p.DiffFn = testDiffFn
  9519  
  9520  	providerResolver := ResourceProviderResolverFixed(
  9521  		map[string]ResourceProviderFactory{
  9522  			"aws": testProviderFuncFixed(p),
  9523  		},
  9524  	)
  9525  
  9526  	s := &State{
  9527  		Modules: []*ModuleState{
  9528  			&ModuleState{
  9529  				Path: rootModulePath,
  9530  				Resources: map[string]*ResourceState{
  9531  					"aws_instance.test": {
  9532  						Type: "aws_instance",
  9533  						Primary: &InstanceState{
  9534  							ID: "foo",
  9535  						},
  9536  						Provider: "provider.aws",
  9537  					},
  9538  				},
  9539  			},
  9540  		},
  9541  	}
  9542  
  9543  	ctx := testContext2(t, &ContextOpts{
  9544  		Module:           m,
  9545  		ProviderResolver: providerResolver,
  9546  		State:            s,
  9547  	})
  9548  
  9549  	plan, err := ctx.Plan()
  9550  	if err != nil {
  9551  		t.Fatalf("plan failed: %s", err)
  9552  	}
  9553  
  9554  	// We'll marshal and unmarshal the plan here, to ensure that we have
  9555  	// a clean new context as would be created if we separately ran
  9556  	// terraform plan -out=tfplan && terraform apply tfplan
  9557  	var planBuf bytes.Buffer
  9558  	err = WritePlan(plan, &planBuf)
  9559  	if err != nil {
  9560  		t.Fatalf("failed to write plan: %s", err)
  9561  	}
  9562  	plan, err = ReadPlan(&planBuf)
  9563  	if err != nil {
  9564  		t.Fatalf("failed to read plan: %s", err)
  9565  	}
  9566  
  9567  	ctx, err = plan.Context(&ContextOpts{
  9568  		ProviderResolver: providerResolver,
  9569  	})
  9570  	if err != nil {
  9571  		t.Fatalf("failed to create context for plan: %s", err)
  9572  	}
  9573  
  9574  	// Applying the plan should now succeed
  9575  	_, err = ctx.Apply()
  9576  	if err != nil {
  9577  		t.Fatalf("apply failed: %s", err)
  9578  	}
  9579  }
  9580  
  9581  func TestContext2Apply_plannedDestroyInterpolatedCount(t *testing.T) {
  9582  	m := testModule(t, "plan-destroy-interpolated-count")
  9583  
  9584  	p := testProvider("aws")
  9585  	p.ApplyFn = testApplyFn
  9586  	p.DiffFn = testDiffFn
  9587  
  9588  	providerResolver := ResourceProviderResolverFixed(
  9589  		map[string]ResourceProviderFactory{
  9590  			"aws": testProviderFuncFixed(p),
  9591  		},
  9592  	)
  9593  
  9594  	s := &State{
  9595  		Modules: []*ModuleState{
  9596  			&ModuleState{
  9597  				Path: rootModulePath,
  9598  				Resources: map[string]*ResourceState{
  9599  					"aws_instance.a.0": {
  9600  						Type: "aws_instance",
  9601  						Primary: &InstanceState{
  9602  							ID: "foo",
  9603  						},
  9604  						Provider: "provider.aws",
  9605  					},
  9606  					"aws_instance.a.1": {
  9607  						Type: "aws_instance",
  9608  						Primary: &InstanceState{
  9609  							ID: "foo",
  9610  						},
  9611  						Provider: "provider.aws",
  9612  					},
  9613  				},
  9614  				Outputs: map[string]*OutputState{
  9615  					"out": {
  9616  						Type:  "list",
  9617  						Value: []string{"foo", "foo"},
  9618  					},
  9619  				},
  9620  			},
  9621  		},
  9622  	}
  9623  
  9624  	ctx := testContext2(t, &ContextOpts{
  9625  		Module:           m,
  9626  		ProviderResolver: providerResolver,
  9627  		State:            s,
  9628  		Destroy:          true,
  9629  	})
  9630  
  9631  	plan, err := ctx.Plan()
  9632  	if err != nil {
  9633  		t.Fatalf("plan failed: %s", err)
  9634  	}
  9635  
  9636  	// We'll marshal and unmarshal the plan here, to ensure that we have
  9637  	// a clean new context as would be created if we separately ran
  9638  	// terraform plan -out=tfplan && terraform apply tfplan
  9639  	var planBuf bytes.Buffer
  9640  	err = WritePlan(plan, &planBuf)
  9641  	if err != nil {
  9642  		t.Fatalf("failed to write plan: %s", err)
  9643  	}
  9644  	plan, err = ReadPlan(&planBuf)
  9645  	if err != nil {
  9646  		t.Fatalf("failed to read plan: %s", err)
  9647  	}
  9648  
  9649  	ctx, err = plan.Context(&ContextOpts{
  9650  		ProviderResolver: providerResolver,
  9651  		Destroy:          true,
  9652  	})
  9653  	if err != nil {
  9654  		t.Fatalf("failed to create context for plan: %s", err)
  9655  	}
  9656  
  9657  	// Applying the plan should now succeed
  9658  	_, err = ctx.Apply()
  9659  	if err != nil {
  9660  		t.Fatalf("apply failed: %s", err)
  9661  	}
  9662  }
  9663  
  9664  func TestContext2Apply_scaleInMultivarRef(t *testing.T) {
  9665  	m := testModule(t, "apply-resource-scale-in")
  9666  
  9667  	p := testProvider("aws")
  9668  	p.ApplyFn = testApplyFn
  9669  	p.DiffFn = testDiffFn
  9670  
  9671  	providerResolver := ResourceProviderResolverFixed(
  9672  		map[string]ResourceProviderFactory{
  9673  			"aws": testProviderFuncFixed(p),
  9674  		},
  9675  	)
  9676  
  9677  	s := &State{
  9678  		Modules: []*ModuleState{
  9679  			&ModuleState{
  9680  				Path: rootModulePath,
  9681  				Resources: map[string]*ResourceState{
  9682  					"aws_instance.one": {
  9683  						Type: "aws_instance",
  9684  						Primary: &InstanceState{
  9685  							ID: "foo",
  9686  						},
  9687  						Provider: "provider.aws",
  9688  					},
  9689  					"aws_instance.two": {
  9690  						Type: "aws_instance",
  9691  						Primary: &InstanceState{
  9692  							ID: "foo",
  9693  							Attributes: map[string]string{
  9694  								"val": "foo",
  9695  							},
  9696  						},
  9697  						Provider: "provider.aws",
  9698  					},
  9699  				},
  9700  			},
  9701  		},
  9702  	}
  9703  
  9704  	ctx := testContext2(t, &ContextOpts{
  9705  		Module:           m,
  9706  		ProviderResolver: providerResolver,
  9707  		State:            s,
  9708  		Variables:        map[string]interface{}{"count": "0"},
  9709  	})
  9710  
  9711  	_, err := ctx.Plan()
  9712  	if err != nil {
  9713  		t.Fatalf("plan failed: %s", err)
  9714  	}
  9715  
  9716  	// Applying the plan should now succeed
  9717  	_, err = ctx.Apply()
  9718  	if err != nil {
  9719  		t.Fatalf("apply failed: %s", err)
  9720  	}
  9721  }