github.com/kjmkznr/terraform@v0.5.2-0.20180216194316-1d0f5fdac99e/terraform/context_apply_test.go (about)

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