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