github.com/nevins-b/terraform@v0.3.8-0.20170215184714-bbae22007d5a/terraform/context_apply_test.go (about)

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