github.com/chentex/terraform@v0.11.2-0.20171208003256-252e8145842e/terraform/context_apply_test.go (about)

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