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