github.com/paybyphone/terraform@v0.9.5-0.20170613192930-9706042ddd51/terraform/context_apply_test.go (about)

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