github.com/skyscape-cloud-services/terraform@v0.9.2-0.20170609144644-7ece028a1747/terraform/context_apply_test.go (about)

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