github.com/aspring/terraform@v0.8.2-0.20161216122603-6a8619a5db2e/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  func TestContext2Apply_dataBasic(t *testing.T) {
  1333  	m := testModule(t, "apply-data-basic")
  1334  	p := testProvider("null")
  1335  	p.ApplyFn = testApplyFn
  1336  	p.DiffFn = testDiffFn
  1337  	p.ReadDataApplyReturn = &InstanceState{ID: "yo"}
  1338  
  1339  	ctx := testContext2(t, &ContextOpts{
  1340  		Module: m,
  1341  		Providers: map[string]ResourceProviderFactory{
  1342  			"null": testProviderFuncFixed(p),
  1343  		},
  1344  	})
  1345  
  1346  	if p, err := ctx.Plan(); err != nil {
  1347  		t.Fatalf("err: %s", err)
  1348  	} else {
  1349  		t.Logf(p.String())
  1350  	}
  1351  
  1352  	state, err := ctx.Apply()
  1353  	if err != nil {
  1354  		t.Fatalf("err: %s", err)
  1355  	}
  1356  
  1357  	actual := strings.TrimSpace(state.String())
  1358  	expected := strings.TrimSpace(testTerraformApplyDataBasicStr)
  1359  	if actual != expected {
  1360  		t.Fatalf("bad: \n%s", actual)
  1361  	}
  1362  }
  1363  
  1364  func TestContext2Apply_destroyData(t *testing.T) {
  1365  	m := testModule(t, "apply-destroy-data-resource")
  1366  	p := testProvider("null")
  1367  	p.ApplyFn = testApplyFn
  1368  	p.DiffFn = testDiffFn
  1369  	state := &State{
  1370  		Modules: []*ModuleState{
  1371  			&ModuleState{
  1372  				Path: rootModulePath,
  1373  				Resources: map[string]*ResourceState{
  1374  					"data.null_data_source.testing": &ResourceState{
  1375  						Type: "aws_instance",
  1376  						Primary: &InstanceState{
  1377  							ID: "-",
  1378  							Attributes: map[string]string{
  1379  								"inputs.#":    "1",
  1380  								"inputs.test": "yes",
  1381  							},
  1382  						},
  1383  					},
  1384  				},
  1385  			},
  1386  		},
  1387  	}
  1388  	ctx := testContext2(t, &ContextOpts{
  1389  		Module: m,
  1390  		Providers: map[string]ResourceProviderFactory{
  1391  			"null": testProviderFuncFixed(p),
  1392  		},
  1393  		State:   state,
  1394  		Destroy: true,
  1395  	})
  1396  
  1397  	if p, err := ctx.Plan(); err != nil {
  1398  		t.Fatalf("err: %s", err)
  1399  	} else {
  1400  		t.Logf(p.String())
  1401  	}
  1402  
  1403  	newState, err := ctx.Apply()
  1404  	if err != nil {
  1405  		t.Fatalf("err: %s", err)
  1406  	}
  1407  
  1408  	if got := len(newState.Modules); got != 1 {
  1409  		t.Fatalf("state has %d modules after destroy; want 1", got)
  1410  	}
  1411  
  1412  	if got := len(newState.Modules[0].Resources); got != 0 {
  1413  		t.Fatalf("state has %d resources after destroy; want 0", got)
  1414  	}
  1415  }
  1416  
  1417  // https://github.com/hashicorp/terraform/pull/5096
  1418  func TestContext2Apply_destroySkipsCBD(t *testing.T) {
  1419  	// Config contains CBD resource depending on non-CBD resource, which triggers
  1420  	// a cycle if they are both replaced, but should _not_ trigger a cycle when
  1421  	// just doing a `terraform destroy`.
  1422  	m := testModule(t, "apply-destroy-cbd")
  1423  	p := testProvider("aws")
  1424  	p.ApplyFn = testApplyFn
  1425  	p.DiffFn = testDiffFn
  1426  	state := &State{
  1427  		Modules: []*ModuleState{
  1428  			&ModuleState{
  1429  				Path: rootModulePath,
  1430  				Resources: map[string]*ResourceState{
  1431  					"aws_instance.foo": &ResourceState{
  1432  						Type: "aws_instance",
  1433  						Primary: &InstanceState{
  1434  							ID: "foo",
  1435  						},
  1436  					},
  1437  					"aws_instance.bar": &ResourceState{
  1438  						Type: "aws_instance",
  1439  						Primary: &InstanceState{
  1440  							ID: "foo",
  1441  						},
  1442  					},
  1443  				},
  1444  			},
  1445  		},
  1446  	}
  1447  	ctx := testContext2(t, &ContextOpts{
  1448  		Module: m,
  1449  		Providers: map[string]ResourceProviderFactory{
  1450  			"aws": testProviderFuncFixed(p),
  1451  		},
  1452  		State:   state,
  1453  		Destroy: true,
  1454  	})
  1455  
  1456  	if p, err := ctx.Plan(); err != nil {
  1457  		t.Fatalf("err: %s", err)
  1458  	} else {
  1459  		t.Logf(p.String())
  1460  	}
  1461  
  1462  	if _, err := ctx.Apply(); err != nil {
  1463  		t.Fatalf("err: %s", err)
  1464  	}
  1465  }
  1466  
  1467  func TestContext2Apply_destroyModuleVarProviderConfig(t *testing.T) {
  1468  	m := testModule(t, "apply-destroy-mod-var-provider-config")
  1469  	p := testProvider("aws")
  1470  	p.ApplyFn = testApplyFn
  1471  	p.DiffFn = testDiffFn
  1472  	state := &State{
  1473  		Modules: []*ModuleState{
  1474  			&ModuleState{
  1475  				Path: []string{"root", "child"},
  1476  				Resources: map[string]*ResourceState{
  1477  					"aws_instance.foo": &ResourceState{
  1478  						Type: "aws_instance",
  1479  						Primary: &InstanceState{
  1480  							ID: "foo",
  1481  						},
  1482  					},
  1483  				},
  1484  			},
  1485  		},
  1486  	}
  1487  	ctx := testContext2(t, &ContextOpts{
  1488  		Module: m,
  1489  		Providers: map[string]ResourceProviderFactory{
  1490  			"aws": testProviderFuncFixed(p),
  1491  		},
  1492  		State:   state,
  1493  		Destroy: true,
  1494  	})
  1495  
  1496  	if _, err := ctx.Plan(); err != nil {
  1497  		t.Fatalf("err: %s", err)
  1498  	}
  1499  
  1500  	_, err := ctx.Apply()
  1501  	if err != nil {
  1502  		t.Fatalf("err: %s", err)
  1503  	}
  1504  }
  1505  
  1506  // https://github.com/hashicorp/terraform/issues/2892
  1507  func TestContext2Apply_destroyCrossProviders(t *testing.T) {
  1508  	m := testModule(t, "apply-destroy-cross-providers")
  1509  
  1510  	p_aws := testProvider("aws")
  1511  	p_aws.ApplyFn = testApplyFn
  1512  	p_aws.DiffFn = testDiffFn
  1513  
  1514  	p_tf := testProvider("terraform")
  1515  	p_tf.ApplyFn = testApplyFn
  1516  	p_tf.DiffFn = testDiffFn
  1517  
  1518  	providers := map[string]ResourceProviderFactory{
  1519  		"aws":       testProviderFuncFixed(p_aws),
  1520  		"terraform": testProviderFuncFixed(p_tf),
  1521  	}
  1522  
  1523  	// Bug only appears from time to time,
  1524  	// so we run this test multiple times
  1525  	// to check for the race-condition
  1526  	for i := 0; i <= 10; i++ {
  1527  		ctx := getContextForApply_destroyCrossProviders(
  1528  			t, m, providers)
  1529  
  1530  		if p, err := ctx.Plan(); err != nil {
  1531  			t.Fatalf("err: %s", err)
  1532  		} else {
  1533  			t.Logf(p.String())
  1534  		}
  1535  
  1536  		if _, err := ctx.Apply(); err != nil {
  1537  			t.Fatalf("err: %s", err)
  1538  		}
  1539  	}
  1540  }
  1541  
  1542  func getContextForApply_destroyCrossProviders(
  1543  	t *testing.T,
  1544  	m *module.Tree,
  1545  	providers map[string]ResourceProviderFactory) *Context {
  1546  	state := &State{
  1547  		Modules: []*ModuleState{
  1548  			&ModuleState{
  1549  				Path: rootModulePath,
  1550  				Resources: map[string]*ResourceState{
  1551  					"terraform_remote_state.shared": &ResourceState{
  1552  						Type: "terraform_remote_state",
  1553  						Primary: &InstanceState{
  1554  							ID: "remote-2652591293",
  1555  							Attributes: map[string]string{
  1556  								"output.env_name": "test",
  1557  							},
  1558  						},
  1559  					},
  1560  				},
  1561  			},
  1562  			&ModuleState{
  1563  				Path: []string{"root", "child"},
  1564  				Resources: map[string]*ResourceState{
  1565  					"aws_vpc.bar": &ResourceState{
  1566  						Type: "aws_vpc",
  1567  						Primary: &InstanceState{
  1568  							ID: "vpc-aaabbb12",
  1569  							Attributes: map[string]string{
  1570  								"value": "test",
  1571  							},
  1572  						},
  1573  					},
  1574  				},
  1575  			},
  1576  		},
  1577  	}
  1578  	ctx := testContext2(t, &ContextOpts{
  1579  		Module:    m,
  1580  		Providers: providers,
  1581  		State:     state,
  1582  		Destroy:   true,
  1583  	})
  1584  
  1585  	return ctx
  1586  }
  1587  
  1588  func TestContext2Apply_minimal(t *testing.T) {
  1589  	m := testModule(t, "apply-minimal")
  1590  	p := testProvider("aws")
  1591  	p.ApplyFn = testApplyFn
  1592  	p.DiffFn = testDiffFn
  1593  	ctx := testContext2(t, &ContextOpts{
  1594  		Module: m,
  1595  		Providers: map[string]ResourceProviderFactory{
  1596  			"aws": testProviderFuncFixed(p),
  1597  		},
  1598  	})
  1599  
  1600  	if _, err := ctx.Plan(); err != nil {
  1601  		t.Fatalf("err: %s", err)
  1602  	}
  1603  
  1604  	state, err := ctx.Apply()
  1605  	if err != nil {
  1606  		t.Fatalf("err: %s", err)
  1607  	}
  1608  
  1609  	actual := strings.TrimSpace(state.String())
  1610  	expected := strings.TrimSpace(testTerraformApplyMinimalStr)
  1611  	if actual != expected {
  1612  		t.Fatalf("bad: \n%s", actual)
  1613  	}
  1614  }
  1615  
  1616  func TestContext2Apply_badDiff(t *testing.T) {
  1617  	m := testModule(t, "apply-good")
  1618  	p := testProvider("aws")
  1619  	p.ApplyFn = testApplyFn
  1620  	p.DiffFn = testDiffFn
  1621  	ctx := testContext2(t, &ContextOpts{
  1622  		Module: m,
  1623  		Providers: map[string]ResourceProviderFactory{
  1624  			"aws": testProviderFuncFixed(p),
  1625  		},
  1626  	})
  1627  
  1628  	if _, err := ctx.Plan(); err != nil {
  1629  		t.Fatalf("err: %s", err)
  1630  	}
  1631  
  1632  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  1633  		return &InstanceDiff{
  1634  			Attributes: map[string]*ResourceAttrDiff{
  1635  				"newp": nil,
  1636  			},
  1637  		}, nil
  1638  	}
  1639  
  1640  	if _, err := ctx.Apply(); err == nil {
  1641  		t.Fatal("should error")
  1642  	}
  1643  }
  1644  
  1645  func TestContext2Apply_cancel(t *testing.T) {
  1646  	stopped := false
  1647  
  1648  	m := testModule(t, "apply-cancel")
  1649  	p := testProvider("aws")
  1650  	ctx := testContext2(t, &ContextOpts{
  1651  		Module: m,
  1652  		Providers: map[string]ResourceProviderFactory{
  1653  			"aws": testProviderFuncFixed(p),
  1654  		},
  1655  	})
  1656  
  1657  	p.ApplyFn = func(*InstanceInfo, *InstanceState, *InstanceDiff) (*InstanceState, error) {
  1658  		if !stopped {
  1659  			stopped = true
  1660  			go ctx.Stop()
  1661  
  1662  			for {
  1663  				if ctx.sh.Stopped() {
  1664  					break
  1665  				}
  1666  			}
  1667  		}
  1668  
  1669  		return &InstanceState{
  1670  			ID: "foo",
  1671  			Attributes: map[string]string{
  1672  				"num": "2",
  1673  			},
  1674  		}, nil
  1675  	}
  1676  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  1677  		return &InstanceDiff{
  1678  			Attributes: map[string]*ResourceAttrDiff{
  1679  				"num": &ResourceAttrDiff{
  1680  					New: "bar",
  1681  				},
  1682  			},
  1683  		}, nil
  1684  	}
  1685  
  1686  	if _, err := ctx.Plan(); err != nil {
  1687  		t.Fatalf("err: %s", err)
  1688  	}
  1689  
  1690  	// Start the Apply in a goroutine
  1691  	var applyErr error
  1692  	stateCh := make(chan *State)
  1693  	go func() {
  1694  		state, err := ctx.Apply()
  1695  		if err != nil {
  1696  			applyErr = err
  1697  		}
  1698  
  1699  		stateCh <- state
  1700  	}()
  1701  
  1702  	state := <-stateCh
  1703  	if applyErr != nil {
  1704  		t.Fatalf("err: %s", applyErr)
  1705  	}
  1706  
  1707  	mod := state.RootModule()
  1708  	if len(mod.Resources) != 1 {
  1709  		t.Fatalf("bad: %s", state.String())
  1710  	}
  1711  
  1712  	actual := strings.TrimSpace(state.String())
  1713  	expected := strings.TrimSpace(testTerraformApplyCancelStr)
  1714  	if actual != expected {
  1715  		t.Fatalf("bad: \n%s", actual)
  1716  	}
  1717  
  1718  	if !p.StopCalled {
  1719  		t.Fatal("stop should be called")
  1720  	}
  1721  }
  1722  
  1723  func TestContext2Apply_compute(t *testing.T) {
  1724  	m := testModule(t, "apply-compute")
  1725  	p := testProvider("aws")
  1726  	p.ApplyFn = testApplyFn
  1727  	p.DiffFn = testDiffFn
  1728  	ctx := testContext2(t, &ContextOpts{
  1729  		Module: m,
  1730  		Providers: map[string]ResourceProviderFactory{
  1731  			"aws": testProviderFuncFixed(p),
  1732  		},
  1733  	})
  1734  
  1735  	if _, err := ctx.Plan(); err != nil {
  1736  		t.Fatalf("err: %s", err)
  1737  	}
  1738  
  1739  	ctx.variables = map[string]interface{}{"value": "1"}
  1740  
  1741  	state, err := ctx.Apply()
  1742  	if err != nil {
  1743  		t.Fatalf("err: %s", err)
  1744  	}
  1745  
  1746  	actual := strings.TrimSpace(state.String())
  1747  	expected := strings.TrimSpace(testTerraformApplyComputeStr)
  1748  	if actual != expected {
  1749  		t.Fatalf("bad: \n%s", actual)
  1750  	}
  1751  }
  1752  
  1753  func TestContext2Apply_countDecrease(t *testing.T) {
  1754  	m := testModule(t, "apply-count-dec")
  1755  	p := testProvider("aws")
  1756  	p.DiffFn = testDiffFn
  1757  	s := &State{
  1758  		Modules: []*ModuleState{
  1759  			&ModuleState{
  1760  				Path: rootModulePath,
  1761  				Resources: map[string]*ResourceState{
  1762  					"aws_instance.foo.0": &ResourceState{
  1763  						Type: "aws_instance",
  1764  						Primary: &InstanceState{
  1765  							ID: "bar",
  1766  							Attributes: map[string]string{
  1767  								"foo":  "foo",
  1768  								"type": "aws_instance",
  1769  							},
  1770  						},
  1771  					},
  1772  					"aws_instance.foo.1": &ResourceState{
  1773  						Type: "aws_instance",
  1774  						Primary: &InstanceState{
  1775  							ID: "bar",
  1776  							Attributes: map[string]string{
  1777  								"foo":  "foo",
  1778  								"type": "aws_instance",
  1779  							},
  1780  						},
  1781  					},
  1782  					"aws_instance.foo.2": &ResourceState{
  1783  						Type: "aws_instance",
  1784  						Primary: &InstanceState{
  1785  							ID: "bar",
  1786  							Attributes: map[string]string{
  1787  								"foo":  "foo",
  1788  								"type": "aws_instance",
  1789  							},
  1790  						},
  1791  					},
  1792  				},
  1793  			},
  1794  		},
  1795  	}
  1796  	ctx := testContext2(t, &ContextOpts{
  1797  		Module: m,
  1798  		Providers: map[string]ResourceProviderFactory{
  1799  			"aws": testProviderFuncFixed(p),
  1800  		},
  1801  		State: s,
  1802  	})
  1803  
  1804  	if _, err := ctx.Plan(); err != nil {
  1805  		t.Fatalf("err: %s", err)
  1806  	}
  1807  
  1808  	state, err := ctx.Apply()
  1809  	if err != nil {
  1810  		t.Fatalf("err: %s", err)
  1811  	}
  1812  
  1813  	actual := strings.TrimSpace(state.String())
  1814  	expected := strings.TrimSpace(testTerraformApplyCountDecStr)
  1815  	if actual != expected {
  1816  		t.Fatalf("bad: \n%s", actual)
  1817  	}
  1818  }
  1819  
  1820  func TestContext2Apply_countDecreaseToOneX(t *testing.T) {
  1821  	m := testModule(t, "apply-count-dec-one")
  1822  	p := testProvider("aws")
  1823  	p.ApplyFn = testApplyFn
  1824  	p.DiffFn = testDiffFn
  1825  	s := &State{
  1826  		Modules: []*ModuleState{
  1827  			&ModuleState{
  1828  				Path: rootModulePath,
  1829  				Resources: map[string]*ResourceState{
  1830  					"aws_instance.foo.0": &ResourceState{
  1831  						Type: "aws_instance",
  1832  						Primary: &InstanceState{
  1833  							ID: "bar",
  1834  							Attributes: map[string]string{
  1835  								"foo":  "foo",
  1836  								"type": "aws_instance",
  1837  							},
  1838  						},
  1839  					},
  1840  					"aws_instance.foo.1": &ResourceState{
  1841  						Type: "aws_instance",
  1842  						Primary: &InstanceState{
  1843  							ID: "bar",
  1844  						},
  1845  					},
  1846  					"aws_instance.foo.2": &ResourceState{
  1847  						Type: "aws_instance",
  1848  						Primary: &InstanceState{
  1849  							ID: "bar",
  1850  						},
  1851  					},
  1852  				},
  1853  			},
  1854  		},
  1855  	}
  1856  	ctx := testContext2(t, &ContextOpts{
  1857  		Module: m,
  1858  		Providers: map[string]ResourceProviderFactory{
  1859  			"aws": testProviderFuncFixed(p),
  1860  		},
  1861  		State: s,
  1862  	})
  1863  
  1864  	if _, err := ctx.Plan(); err != nil {
  1865  		t.Fatalf("err: %s", err)
  1866  	}
  1867  
  1868  	state, err := ctx.Apply()
  1869  	if err != nil {
  1870  		t.Fatalf("err: %s", err)
  1871  	}
  1872  
  1873  	actual := strings.TrimSpace(state.String())
  1874  	expected := strings.TrimSpace(testTerraformApplyCountDecToOneStr)
  1875  	if actual != expected {
  1876  		t.Fatalf("bad: \n%s", actual)
  1877  	}
  1878  }
  1879  
  1880  // https://github.com/PeoplePerHour/terraform/pull/11
  1881  //
  1882  // This tests a case where both a "resource" and "resource.0" are in
  1883  // the state file, which apparently is a reasonable backwards compatibility
  1884  // concern found in the above 3rd party repo.
  1885  func TestContext2Apply_countDecreaseToOneCorrupted(t *testing.T) {
  1886  	m := testModule(t, "apply-count-dec-one")
  1887  	p := testProvider("aws")
  1888  	p.ApplyFn = testApplyFn
  1889  	p.DiffFn = testDiffFn
  1890  	s := &State{
  1891  		Modules: []*ModuleState{
  1892  			&ModuleState{
  1893  				Path: rootModulePath,
  1894  				Resources: map[string]*ResourceState{
  1895  					"aws_instance.foo": &ResourceState{
  1896  						Type: "aws_instance",
  1897  						Primary: &InstanceState{
  1898  							ID: "bar",
  1899  							Attributes: map[string]string{
  1900  								"foo":  "foo",
  1901  								"type": "aws_instance",
  1902  							},
  1903  						},
  1904  					},
  1905  					"aws_instance.foo.0": &ResourceState{
  1906  						Type: "aws_instance",
  1907  						Primary: &InstanceState{
  1908  							ID: "baz",
  1909  							Attributes: map[string]string{
  1910  								"type": "aws_instance",
  1911  							},
  1912  						},
  1913  					},
  1914  				},
  1915  			},
  1916  		},
  1917  	}
  1918  	ctx := testContext2(t, &ContextOpts{
  1919  		Module: m,
  1920  		Providers: map[string]ResourceProviderFactory{
  1921  			"aws": testProviderFuncFixed(p),
  1922  		},
  1923  		State: s,
  1924  	})
  1925  
  1926  	if p, err := ctx.Plan(); err != nil {
  1927  		t.Fatalf("err: %s", err)
  1928  	} else {
  1929  		testStringMatch(t, p, testTerraformApplyCountDecToOneCorruptedPlanStr)
  1930  	}
  1931  
  1932  	state, err := ctx.Apply()
  1933  	if err != nil {
  1934  		t.Fatalf("err: %s", err)
  1935  	}
  1936  
  1937  	actual := strings.TrimSpace(state.String())
  1938  	expected := strings.TrimSpace(testTerraformApplyCountDecToOneCorruptedStr)
  1939  	if actual != expected {
  1940  		t.Fatalf("bad: \n%s", actual)
  1941  	}
  1942  }
  1943  
  1944  func TestContext2Apply_countTainted(t *testing.T) {
  1945  	m := testModule(t, "apply-count-tainted")
  1946  	p := testProvider("aws")
  1947  	p.DiffFn = testDiffFn
  1948  	s := &State{
  1949  		Modules: []*ModuleState{
  1950  			&ModuleState{
  1951  				Path: rootModulePath,
  1952  				Resources: map[string]*ResourceState{
  1953  					"aws_instance.foo.0": &ResourceState{
  1954  						Type: "aws_instance",
  1955  						Primary: &InstanceState{
  1956  							ID: "bar",
  1957  							Attributes: map[string]string{
  1958  								"foo":  "foo",
  1959  								"type": "aws_instance",
  1960  							},
  1961  							Tainted: true,
  1962  						},
  1963  					},
  1964  				},
  1965  			},
  1966  		},
  1967  	}
  1968  	ctx := testContext2(t, &ContextOpts{
  1969  		Module: m,
  1970  		Providers: map[string]ResourceProviderFactory{
  1971  			"aws": testProviderFuncFixed(p),
  1972  		},
  1973  		State: s,
  1974  	})
  1975  
  1976  	if _, err := ctx.Plan(); err != nil {
  1977  		t.Fatalf("err: %s", err)
  1978  	}
  1979  
  1980  	state, err := ctx.Apply()
  1981  	if err != nil {
  1982  		t.Fatalf("err: %s", err)
  1983  	}
  1984  
  1985  	actual := strings.TrimSpace(state.String())
  1986  	expected := strings.TrimSpace(testTerraformApplyCountTaintedStr)
  1987  	if actual != expected {
  1988  		t.Fatalf("bad: \n%s", actual)
  1989  	}
  1990  }
  1991  
  1992  func TestContext2Apply_countVariable(t *testing.T) {
  1993  	m := testModule(t, "apply-count-variable")
  1994  	p := testProvider("aws")
  1995  	p.ApplyFn = testApplyFn
  1996  	p.DiffFn = testDiffFn
  1997  	ctx := testContext2(t, &ContextOpts{
  1998  		Module: m,
  1999  		Providers: map[string]ResourceProviderFactory{
  2000  			"aws": testProviderFuncFixed(p),
  2001  		},
  2002  	})
  2003  
  2004  	if _, err := ctx.Plan(); err != nil {
  2005  		t.Fatalf("err: %s", err)
  2006  	}
  2007  
  2008  	state, err := ctx.Apply()
  2009  	if err != nil {
  2010  		t.Fatalf("err: %s", err)
  2011  	}
  2012  
  2013  	actual := strings.TrimSpace(state.String())
  2014  	expected := strings.TrimSpace(testTerraformApplyCountVariableStr)
  2015  	if actual != expected {
  2016  		t.Fatalf("bad: \n%s", actual)
  2017  	}
  2018  }
  2019  
  2020  func TestContext2Apply_countVariableRef(t *testing.T) {
  2021  	m := testModule(t, "apply-count-variable-ref")
  2022  	p := testProvider("aws")
  2023  	p.ApplyFn = testApplyFn
  2024  	p.DiffFn = testDiffFn
  2025  	ctx := testContext2(t, &ContextOpts{
  2026  		Module: m,
  2027  		Providers: map[string]ResourceProviderFactory{
  2028  			"aws": testProviderFuncFixed(p),
  2029  		},
  2030  	})
  2031  
  2032  	if _, err := ctx.Plan(); err != nil {
  2033  		t.Fatalf("err: %s", err)
  2034  	}
  2035  
  2036  	state, err := ctx.Apply()
  2037  	if err != nil {
  2038  		t.Fatalf("err: %s", err)
  2039  	}
  2040  
  2041  	actual := strings.TrimSpace(state.String())
  2042  	expected := strings.TrimSpace(testTerraformApplyCountVariableRefStr)
  2043  	if actual != expected {
  2044  		t.Fatalf("bad: \n%s", actual)
  2045  	}
  2046  }
  2047  
  2048  func TestContext2Apply_mapVariableOverride(t *testing.T) {
  2049  	m := testModule(t, "apply-map-var-override")
  2050  	p := testProvider("aws")
  2051  	p.ApplyFn = testApplyFn
  2052  	p.DiffFn = testDiffFn
  2053  	ctx := testContext2(t, &ContextOpts{
  2054  		Module: m,
  2055  		Providers: map[string]ResourceProviderFactory{
  2056  			"aws": testProviderFuncFixed(p),
  2057  		},
  2058  		Variables: map[string]interface{}{
  2059  			"images": []map[string]interface{}{
  2060  				map[string]interface{}{
  2061  					"us-west-2": "overridden",
  2062  				},
  2063  			},
  2064  		},
  2065  	})
  2066  
  2067  	if _, err := ctx.Plan(); err != nil {
  2068  		t.Fatalf("err: %s", err)
  2069  	}
  2070  
  2071  	state, err := ctx.Apply()
  2072  	if err != nil {
  2073  		t.Fatalf("err: %s", err)
  2074  	}
  2075  
  2076  	actual := strings.TrimSpace(state.String())
  2077  	expected := strings.TrimSpace(`
  2078  aws_instance.bar:
  2079    ID = foo
  2080    ami = overridden
  2081    type = aws_instance
  2082  aws_instance.foo:
  2083    ID = foo
  2084    ami = image-1234
  2085    type = aws_instance
  2086  	`)
  2087  	if actual != expected {
  2088  		t.Fatalf("got: \n%s\nexpected: \n%s", actual, expected)
  2089  	}
  2090  }
  2091  
  2092  func TestContext2Apply_moduleBasic(t *testing.T) {
  2093  	m := testModule(t, "apply-module")
  2094  	p := testProvider("aws")
  2095  	p.ApplyFn = testApplyFn
  2096  	p.DiffFn = testDiffFn
  2097  	ctx := testContext2(t, &ContextOpts{
  2098  		Module: m,
  2099  		Providers: map[string]ResourceProviderFactory{
  2100  			"aws": testProviderFuncFixed(p),
  2101  		},
  2102  	})
  2103  
  2104  	if _, err := ctx.Plan(); err != nil {
  2105  		t.Fatalf("err: %s", err)
  2106  	}
  2107  
  2108  	state, err := ctx.Apply()
  2109  	if err != nil {
  2110  		t.Fatalf("err: %s", err)
  2111  	}
  2112  
  2113  	actual := strings.TrimSpace(state.String())
  2114  	expected := strings.TrimSpace(testTerraformApplyModuleStr)
  2115  	if actual != expected {
  2116  		t.Fatalf("bad, expected:\n%s\n\nactual:\n%s", expected, actual)
  2117  	}
  2118  }
  2119  
  2120  func TestContext2Apply_moduleDestroyOrder(t *testing.T) {
  2121  	m := testModule(t, "apply-module-destroy-order")
  2122  	p := testProvider("aws")
  2123  	p.DiffFn = testDiffFn
  2124  
  2125  	// Create a custom apply function to track the order they were destroyed
  2126  	var order []string
  2127  	var orderLock sync.Mutex
  2128  	p.ApplyFn = func(
  2129  		info *InstanceInfo,
  2130  		is *InstanceState,
  2131  		id *InstanceDiff) (*InstanceState, error) {
  2132  		orderLock.Lock()
  2133  		defer orderLock.Unlock()
  2134  
  2135  		order = append(order, is.ID)
  2136  		return nil, nil
  2137  	}
  2138  
  2139  	state := &State{
  2140  		Modules: []*ModuleState{
  2141  			&ModuleState{
  2142  				Path: rootModulePath,
  2143  				Resources: map[string]*ResourceState{
  2144  					"aws_instance.b": &ResourceState{
  2145  						Type: "aws_instance",
  2146  						Primary: &InstanceState{
  2147  							ID: "b",
  2148  						},
  2149  					},
  2150  				},
  2151  			},
  2152  
  2153  			&ModuleState{
  2154  				Path: []string{"root", "child"},
  2155  				Resources: map[string]*ResourceState{
  2156  					"aws_instance.a": &ResourceState{
  2157  						Type: "aws_instance",
  2158  						Primary: &InstanceState{
  2159  							ID: "a",
  2160  						},
  2161  					},
  2162  				},
  2163  				Outputs: map[string]*OutputState{
  2164  					"a_output": &OutputState{
  2165  						Type:      "string",
  2166  						Sensitive: false,
  2167  						Value:     "a",
  2168  					},
  2169  				},
  2170  			},
  2171  		},
  2172  	}
  2173  
  2174  	ctx := testContext2(t, &ContextOpts{
  2175  		Module: m,
  2176  		Providers: map[string]ResourceProviderFactory{
  2177  			"aws": testProviderFuncFixed(p),
  2178  		},
  2179  		State:   state,
  2180  		Destroy: true,
  2181  	})
  2182  
  2183  	if _, err := ctx.Plan(); err != nil {
  2184  		t.Fatalf("err: %s", err)
  2185  	}
  2186  
  2187  	state, err := ctx.Apply()
  2188  	if err != nil {
  2189  		t.Fatalf("err: %s", err)
  2190  	}
  2191  
  2192  	expected := []string{"b", "a"}
  2193  	if !reflect.DeepEqual(order, expected) {
  2194  		t.Fatalf("bad: %#v", order)
  2195  	}
  2196  
  2197  	{
  2198  		actual := strings.TrimSpace(state.String())
  2199  		expected := strings.TrimSpace(testTerraformApplyModuleDestroyOrderStr)
  2200  		if actual != expected {
  2201  			t.Fatalf("bad: \n%s", actual)
  2202  		}
  2203  	}
  2204  }
  2205  
  2206  func TestContext2Apply_moduleInheritAlias(t *testing.T) {
  2207  	m := testModule(t, "apply-module-provider-inherit-alias")
  2208  	p := testProvider("aws")
  2209  	p.ApplyFn = testApplyFn
  2210  	p.DiffFn = testDiffFn
  2211  
  2212  	p.ConfigureFn = func(c *ResourceConfig) error {
  2213  		if _, ok := c.Get("child"); !ok {
  2214  			return nil
  2215  		}
  2216  
  2217  		if _, ok := c.Get("root"); ok {
  2218  			return fmt.Errorf("child should not get root")
  2219  		}
  2220  
  2221  		return nil
  2222  	}
  2223  
  2224  	ctx := testContext2(t, &ContextOpts{
  2225  		Module: m,
  2226  		Providers: map[string]ResourceProviderFactory{
  2227  			"aws": testProviderFuncFixed(p),
  2228  		},
  2229  	})
  2230  
  2231  	if _, err := ctx.Plan(); err != nil {
  2232  		t.Fatalf("err: %s", err)
  2233  	}
  2234  
  2235  	state, err := ctx.Apply()
  2236  	if err != nil {
  2237  		t.Fatalf("err: %s", err)
  2238  	}
  2239  
  2240  	checkStateString(t, state, `
  2241  <no state>
  2242  module.child:
  2243    aws_instance.foo:
  2244      ID = foo
  2245      provider = aws.eu
  2246  	`)
  2247  }
  2248  
  2249  func TestContext2Apply_moduleOrphanInheritAlias(t *testing.T) {
  2250  	m := testModule(t, "apply-module-provider-inherit-alias-orphan")
  2251  	p := testProvider("aws")
  2252  	p.ApplyFn = testApplyFn
  2253  	p.DiffFn = testDiffFn
  2254  
  2255  	called := false
  2256  	p.ConfigureFn = func(c *ResourceConfig) error {
  2257  		called = true
  2258  
  2259  		if _, ok := c.Get("child"); !ok {
  2260  			return nil
  2261  		}
  2262  
  2263  		if _, ok := c.Get("root"); ok {
  2264  			return fmt.Errorf("child should not get root")
  2265  		}
  2266  
  2267  		return nil
  2268  	}
  2269  
  2270  	// Create a state with an orphan module
  2271  	state := &State{
  2272  		Modules: []*ModuleState{
  2273  			&ModuleState{
  2274  				Path: []string{"root", "child"},
  2275  				Resources: map[string]*ResourceState{
  2276  					"aws_instance.bar": &ResourceState{
  2277  						Type: "aws_instance",
  2278  						Primary: &InstanceState{
  2279  							ID: "bar",
  2280  						},
  2281  						Provider: "aws.eu",
  2282  					},
  2283  				},
  2284  			},
  2285  		},
  2286  	}
  2287  
  2288  	ctx := testContext2(t, &ContextOpts{
  2289  		Module: m,
  2290  		State:  state,
  2291  		Providers: map[string]ResourceProviderFactory{
  2292  			"aws": testProviderFuncFixed(p),
  2293  		},
  2294  	})
  2295  
  2296  	if _, err := ctx.Plan(); err != nil {
  2297  		t.Fatalf("err: %s", err)
  2298  	}
  2299  
  2300  	state, err := ctx.Apply()
  2301  	if err != nil {
  2302  		t.Fatalf("err: %s", err)
  2303  	}
  2304  
  2305  	if !called {
  2306  		t.Fatal("must call configure")
  2307  	}
  2308  
  2309  	checkStateString(t, state, `
  2310  module.child:
  2311    <no state>
  2312    `)
  2313  }
  2314  
  2315  func TestContext2Apply_moduleOrphanProvider(t *testing.T) {
  2316  	m := testModule(t, "apply-module-orphan-provider-inherit")
  2317  	p := testProvider("aws")
  2318  	p.ApplyFn = testApplyFn
  2319  	p.DiffFn = testDiffFn
  2320  
  2321  	p.ConfigureFn = func(c *ResourceConfig) error {
  2322  		if _, ok := c.Get("value"); !ok {
  2323  			return fmt.Errorf("value is not found")
  2324  		}
  2325  
  2326  		return nil
  2327  	}
  2328  
  2329  	// Create a state with an orphan module
  2330  	state := &State{
  2331  		Modules: []*ModuleState{
  2332  			&ModuleState{
  2333  				Path: []string{"root", "child"},
  2334  				Resources: map[string]*ResourceState{
  2335  					"aws_instance.bar": &ResourceState{
  2336  						Type: "aws_instance",
  2337  						Primary: &InstanceState{
  2338  							ID: "bar",
  2339  						},
  2340  					},
  2341  				},
  2342  			},
  2343  		},
  2344  	}
  2345  
  2346  	ctx := testContext2(t, &ContextOpts{
  2347  		Module: m,
  2348  		State:  state,
  2349  		Providers: map[string]ResourceProviderFactory{
  2350  			"aws": testProviderFuncFixed(p),
  2351  		},
  2352  	})
  2353  
  2354  	if _, err := ctx.Plan(); err != nil {
  2355  		t.Fatalf("err: %s", err)
  2356  	}
  2357  
  2358  	if _, err := ctx.Apply(); err != nil {
  2359  		t.Fatalf("err: %s", err)
  2360  	}
  2361  }
  2362  
  2363  func TestContext2Apply_moduleOrphanGrandchildProvider(t *testing.T) {
  2364  	m := testModule(t, "apply-module-orphan-provider-inherit")
  2365  	p := testProvider("aws")
  2366  	p.ApplyFn = testApplyFn
  2367  	p.DiffFn = testDiffFn
  2368  
  2369  	p.ConfigureFn = func(c *ResourceConfig) error {
  2370  		if _, ok := c.Get("value"); !ok {
  2371  			return fmt.Errorf("value is not found")
  2372  		}
  2373  
  2374  		return nil
  2375  	}
  2376  
  2377  	// Create a state with an orphan module that is nested (grandchild)
  2378  	state := &State{
  2379  		Modules: []*ModuleState{
  2380  			&ModuleState{
  2381  				Path: []string{"root", "parent", "child"},
  2382  				Resources: map[string]*ResourceState{
  2383  					"aws_instance.bar": &ResourceState{
  2384  						Type: "aws_instance",
  2385  						Primary: &InstanceState{
  2386  							ID: "bar",
  2387  						},
  2388  					},
  2389  				},
  2390  			},
  2391  		},
  2392  	}
  2393  
  2394  	ctx := testContext2(t, &ContextOpts{
  2395  		Module: m,
  2396  		State:  state,
  2397  		Providers: map[string]ResourceProviderFactory{
  2398  			"aws": testProviderFuncFixed(p),
  2399  		},
  2400  	})
  2401  
  2402  	if _, err := ctx.Plan(); err != nil {
  2403  		t.Fatalf("err: %s", err)
  2404  	}
  2405  
  2406  	if _, err := ctx.Apply(); err != nil {
  2407  		t.Fatalf("err: %s", err)
  2408  	}
  2409  }
  2410  
  2411  func TestContext2Apply_moduleGrandchildProvider(t *testing.T) {
  2412  	m := testModule(t, "apply-module-grandchild-provider-inherit")
  2413  	p := testProvider("aws")
  2414  	p.ApplyFn = testApplyFn
  2415  	p.DiffFn = testDiffFn
  2416  
  2417  	var callLock sync.Mutex
  2418  	called := false
  2419  	p.ConfigureFn = func(c *ResourceConfig) error {
  2420  		if _, ok := c.Get("value"); !ok {
  2421  			return fmt.Errorf("value is not found")
  2422  		}
  2423  		callLock.Lock()
  2424  		called = true
  2425  		callLock.Unlock()
  2426  
  2427  		return nil
  2428  	}
  2429  
  2430  	ctx := testContext2(t, &ContextOpts{
  2431  		Module: m,
  2432  		Providers: map[string]ResourceProviderFactory{
  2433  			"aws": testProviderFuncFixed(p),
  2434  		},
  2435  	})
  2436  
  2437  	if _, err := ctx.Plan(); err != nil {
  2438  		t.Fatalf("err: %s", err)
  2439  	}
  2440  
  2441  	if _, err := ctx.Apply(); err != nil {
  2442  		t.Fatalf("err: %s", err)
  2443  	}
  2444  
  2445  	callLock.Lock()
  2446  	defer callLock.Unlock()
  2447  	if called != true {
  2448  		t.Fatalf("err: configure never called")
  2449  	}
  2450  }
  2451  
  2452  // This tests an issue where all the providers in a module but not
  2453  // in the root weren't being added to the root properly. In this test
  2454  // case: aws is explicitly added to root, but "test" should be added to.
  2455  // With the bug, it wasn't.
  2456  func TestContext2Apply_moduleOnlyProvider(t *testing.T) {
  2457  	m := testModule(t, "apply-module-only-provider")
  2458  	p := testProvider("aws")
  2459  	p.ApplyFn = testApplyFn
  2460  	p.DiffFn = testDiffFn
  2461  	pTest := testProvider("test")
  2462  	pTest.ApplyFn = testApplyFn
  2463  	pTest.DiffFn = testDiffFn
  2464  
  2465  	ctx := testContext2(t, &ContextOpts{
  2466  		Module: m,
  2467  		Providers: map[string]ResourceProviderFactory{
  2468  			"aws":  testProviderFuncFixed(p),
  2469  			"test": testProviderFuncFixed(pTest),
  2470  		},
  2471  	})
  2472  
  2473  	if _, err := ctx.Plan(); err != nil {
  2474  		t.Fatalf("err: %s", err)
  2475  	}
  2476  
  2477  	state, err := ctx.Apply()
  2478  	if err != nil {
  2479  		t.Fatalf("err: %s", err)
  2480  	}
  2481  
  2482  	actual := strings.TrimSpace(state.String())
  2483  	expected := strings.TrimSpace(testTerraformApplyModuleOnlyProviderStr)
  2484  	if actual != expected {
  2485  		t.Fatalf("bad: \n%s", actual)
  2486  	}
  2487  }
  2488  
  2489  func TestContext2Apply_moduleProviderAlias(t *testing.T) {
  2490  	m := testModule(t, "apply-module-provider-alias")
  2491  	p := testProvider("aws")
  2492  	p.ApplyFn = testApplyFn
  2493  	p.DiffFn = testDiffFn
  2494  	ctx := testContext2(t, &ContextOpts{
  2495  		Module: m,
  2496  		Providers: map[string]ResourceProviderFactory{
  2497  			"aws": testProviderFuncFixed(p),
  2498  		},
  2499  	})
  2500  
  2501  	if _, err := ctx.Plan(); err != nil {
  2502  		t.Fatalf("err: %s", err)
  2503  	}
  2504  
  2505  	state, err := ctx.Apply()
  2506  	if err != nil {
  2507  		t.Fatalf("err: %s", err)
  2508  	}
  2509  
  2510  	actual := strings.TrimSpace(state.String())
  2511  	expected := strings.TrimSpace(testTerraformApplyModuleProviderAliasStr)
  2512  	if actual != expected {
  2513  		t.Fatalf("bad: \n%s", actual)
  2514  	}
  2515  }
  2516  
  2517  func TestContext2Apply_moduleProviderAliasTargets(t *testing.T) {
  2518  	m := testModule(t, "apply-module-provider-alias")
  2519  	p := testProvider("aws")
  2520  	p.ApplyFn = testApplyFn
  2521  	p.DiffFn = testDiffFn
  2522  	ctx := testContext2(t, &ContextOpts{
  2523  		Module: m,
  2524  		Providers: map[string]ResourceProviderFactory{
  2525  			"aws": testProviderFuncFixed(p),
  2526  		},
  2527  		Targets: []string{"no.thing"},
  2528  	})
  2529  
  2530  	if _, err := ctx.Plan(); err != nil {
  2531  		t.Fatalf("err: %s", err)
  2532  	}
  2533  
  2534  	state, err := ctx.Apply()
  2535  	if err != nil {
  2536  		t.Fatalf("err: %s", err)
  2537  	}
  2538  
  2539  	actual := strings.TrimSpace(state.String())
  2540  	expected := strings.TrimSpace(`
  2541  <no state>
  2542  	`)
  2543  	if actual != expected {
  2544  		t.Fatalf("bad: \n%s", actual)
  2545  	}
  2546  }
  2547  
  2548  func TestContext2Apply_moduleProviderCloseNested(t *testing.T) {
  2549  	m := testModule(t, "apply-module-provider-close-nested")
  2550  	p := testProvider("aws")
  2551  	p.ApplyFn = testApplyFn
  2552  	p.DiffFn = testDiffFn
  2553  	ctx := testContext2(t, &ContextOpts{
  2554  		Module: m,
  2555  		Providers: map[string]ResourceProviderFactory{
  2556  			"aws": testProviderFuncFixed(p),
  2557  		},
  2558  		State: &State{
  2559  			Modules: []*ModuleState{
  2560  				&ModuleState{
  2561  					Path: []string{"root", "child", "subchild"},
  2562  					Resources: map[string]*ResourceState{
  2563  						"aws_instance.foo": &ResourceState{
  2564  							Type: "aws_instance",
  2565  							Primary: &InstanceState{
  2566  								ID: "bar",
  2567  							},
  2568  						},
  2569  					},
  2570  				},
  2571  			},
  2572  		},
  2573  		Destroy: true,
  2574  	})
  2575  
  2576  	if _, err := ctx.Plan(); err != nil {
  2577  		t.Fatalf("err: %s", err)
  2578  	}
  2579  
  2580  	if _, err := ctx.Apply(); err != nil {
  2581  		t.Fatalf("err: %s", err)
  2582  	}
  2583  }
  2584  
  2585  // Tests that variables used as module vars that reference data that
  2586  // already exists in the state and requires no diff works properly. This
  2587  // fixes an issue faced where module variables were pruned because they were
  2588  // accessing "non-existent" resources (they existed, just not in the graph
  2589  // cause they weren't in the diff).
  2590  func TestContext2Apply_moduleVarRefExisting(t *testing.T) {
  2591  	m := testModule(t, "apply-ref-existing")
  2592  	p := testProvider("aws")
  2593  	p.ApplyFn = testApplyFn
  2594  	p.DiffFn = testDiffFn
  2595  
  2596  	state := &State{
  2597  		Modules: []*ModuleState{
  2598  			&ModuleState{
  2599  				Path: rootModulePath,
  2600  				Resources: map[string]*ResourceState{
  2601  					"aws_instance.foo": &ResourceState{
  2602  						Type: "aws_instance",
  2603  						Primary: &InstanceState{
  2604  							ID: "foo",
  2605  							Attributes: map[string]string{
  2606  								"foo": "bar",
  2607  							},
  2608  						},
  2609  					},
  2610  				},
  2611  			},
  2612  		},
  2613  	}
  2614  
  2615  	ctx := testContext2(t, &ContextOpts{
  2616  		Module: m,
  2617  		Providers: map[string]ResourceProviderFactory{
  2618  			"aws": testProviderFuncFixed(p),
  2619  		},
  2620  		State: state,
  2621  	})
  2622  
  2623  	if _, err := ctx.Plan(); err != nil {
  2624  		t.Fatalf("err: %s", err)
  2625  	}
  2626  
  2627  	state, err := ctx.Apply()
  2628  	if err != nil {
  2629  		t.Fatalf("err: %s", err)
  2630  	}
  2631  
  2632  	actual := strings.TrimSpace(state.String())
  2633  	expected := strings.TrimSpace(testTerraformApplyModuleVarRefExistingStr)
  2634  	if actual != expected {
  2635  		t.Fatalf("bad: \n%s", actual)
  2636  	}
  2637  }
  2638  
  2639  func TestContext2Apply_moduleVarResourceCount(t *testing.T) {
  2640  	m := testModule(t, "apply-module-var-resource-count")
  2641  	p := testProvider("aws")
  2642  	p.ApplyFn = testApplyFn
  2643  	p.DiffFn = testDiffFn
  2644  	ctx := testContext2(t, &ContextOpts{
  2645  		Module: m,
  2646  		Providers: map[string]ResourceProviderFactory{
  2647  			"aws": testProviderFuncFixed(p),
  2648  		},
  2649  		Variables: map[string]interface{}{
  2650  			"count": "2",
  2651  		},
  2652  		Destroy: true,
  2653  	})
  2654  
  2655  	if _, err := ctx.Plan(); err != nil {
  2656  		t.Fatalf("err: %s", err)
  2657  	}
  2658  
  2659  	if _, err := ctx.Apply(); err != nil {
  2660  		t.Fatalf("err: %s", err)
  2661  	}
  2662  
  2663  	ctx = testContext2(t, &ContextOpts{
  2664  		Module: m,
  2665  		Providers: map[string]ResourceProviderFactory{
  2666  			"aws": testProviderFuncFixed(p),
  2667  		},
  2668  		Variables: map[string]interface{}{
  2669  			"count": "5",
  2670  		},
  2671  	})
  2672  
  2673  	if _, err := ctx.Plan(); err != nil {
  2674  		t.Fatalf("err: %s", err)
  2675  	}
  2676  
  2677  	if _, err := ctx.Apply(); err != nil {
  2678  		t.Fatalf("err: %s", err)
  2679  	}
  2680  }
  2681  
  2682  // GH-819
  2683  func TestContext2Apply_moduleBool(t *testing.T) {
  2684  	m := testModule(t, "apply-module-bool")
  2685  	p := testProvider("aws")
  2686  	p.ApplyFn = testApplyFn
  2687  	p.DiffFn = testDiffFn
  2688  	ctx := testContext2(t, &ContextOpts{
  2689  		Module: m,
  2690  		Providers: map[string]ResourceProviderFactory{
  2691  			"aws": testProviderFuncFixed(p),
  2692  		},
  2693  	})
  2694  
  2695  	if _, err := ctx.Plan(); err != nil {
  2696  		t.Fatalf("err: %s", err)
  2697  	}
  2698  
  2699  	state, err := ctx.Apply()
  2700  	if err != nil {
  2701  		t.Fatalf("err: %s", err)
  2702  	}
  2703  
  2704  	actual := strings.TrimSpace(state.String())
  2705  	expected := strings.TrimSpace(testTerraformApplyModuleBoolStr)
  2706  	if actual != expected {
  2707  		t.Fatalf("bad: \n%s", actual)
  2708  	}
  2709  }
  2710  
  2711  // Tests that a module can be targeted and everything is properly created.
  2712  // This adds to the plan test to also just verify that apply works.
  2713  func TestContext2Apply_moduleTarget(t *testing.T) {
  2714  	m := testModule(t, "plan-targeted-cross-module")
  2715  	p := testProvider("aws")
  2716  	p.ApplyFn = testApplyFn
  2717  	p.DiffFn = testDiffFn
  2718  	ctx := testContext2(t, &ContextOpts{
  2719  		Module: m,
  2720  		Providers: map[string]ResourceProviderFactory{
  2721  			"aws": testProviderFuncFixed(p),
  2722  		},
  2723  		Targets: []string{"module.B"},
  2724  	})
  2725  
  2726  	if _, err := ctx.Plan(); err != nil {
  2727  		t.Fatalf("err: %s", err)
  2728  	}
  2729  
  2730  	state, err := ctx.Apply()
  2731  	if err != nil {
  2732  		t.Fatalf("err: %s", err)
  2733  	}
  2734  
  2735  	checkStateString(t, state, `
  2736  <no state>
  2737  module.A:
  2738    aws_instance.foo:
  2739      ID = foo
  2740      foo = bar
  2741      type = aws_instance
  2742  
  2743    Outputs:
  2744  
  2745    value = foo
  2746  module.B:
  2747    aws_instance.bar:
  2748      ID = foo
  2749      foo = foo
  2750      type = aws_instance
  2751  	`)
  2752  }
  2753  
  2754  func TestContext2Apply_multiProvider(t *testing.T) {
  2755  	m := testModule(t, "apply-multi-provider")
  2756  	p := testProvider("aws")
  2757  	p.ApplyFn = testApplyFn
  2758  	p.DiffFn = testDiffFn
  2759  
  2760  	pDO := testProvider("do")
  2761  	pDO.ApplyFn = testApplyFn
  2762  	pDO.DiffFn = testDiffFn
  2763  
  2764  	ctx := testContext2(t, &ContextOpts{
  2765  		Module: m,
  2766  		Providers: map[string]ResourceProviderFactory{
  2767  			"aws": testProviderFuncFixed(p),
  2768  			"do":  testProviderFuncFixed(pDO),
  2769  		},
  2770  	})
  2771  
  2772  	if _, err := ctx.Plan(); err != nil {
  2773  		t.Fatalf("err: %s", err)
  2774  	}
  2775  
  2776  	state, err := ctx.Apply()
  2777  	if err != nil {
  2778  		t.Fatalf("err: %s", err)
  2779  	}
  2780  
  2781  	mod := state.RootModule()
  2782  	if len(mod.Resources) < 2 {
  2783  		t.Fatalf("bad: %#v", mod.Resources)
  2784  	}
  2785  
  2786  	actual := strings.TrimSpace(state.String())
  2787  	expected := strings.TrimSpace(testTerraformApplyMultiProviderStr)
  2788  	if actual != expected {
  2789  		t.Fatalf("bad: \n%s", actual)
  2790  	}
  2791  }
  2792  
  2793  func TestContext2Apply_multiProviderDestroy(t *testing.T) {
  2794  	m := testModule(t, "apply-multi-provider-destroy")
  2795  	p := testProvider("aws")
  2796  	p.ApplyFn = testApplyFn
  2797  	p.DiffFn = testDiffFn
  2798  
  2799  	p2 := testProvider("do")
  2800  	p2.ApplyFn = testApplyFn
  2801  	p2.DiffFn = testDiffFn
  2802  
  2803  	var state *State
  2804  
  2805  	// First, create the instances
  2806  	{
  2807  		ctx := testContext2(t, &ContextOpts{
  2808  			Module: m,
  2809  			Providers: map[string]ResourceProviderFactory{
  2810  				"aws":   testProviderFuncFixed(p),
  2811  				"vault": testProviderFuncFixed(p2),
  2812  			},
  2813  		})
  2814  
  2815  		if _, err := ctx.Plan(); err != nil {
  2816  			t.Fatalf("err: %s", err)
  2817  		}
  2818  
  2819  		s, err := ctx.Apply()
  2820  		if err != nil {
  2821  			t.Fatalf("err: %s", err)
  2822  		}
  2823  
  2824  		state = s
  2825  	}
  2826  
  2827  	// Destroy them
  2828  	{
  2829  		// Verify that aws_instance.bar is destroyed first
  2830  		var checked bool
  2831  		var called int32
  2832  		var lock sync.Mutex
  2833  		applyFn := func(
  2834  			info *InstanceInfo,
  2835  			is *InstanceState,
  2836  			id *InstanceDiff) (*InstanceState, error) {
  2837  			lock.Lock()
  2838  			defer lock.Unlock()
  2839  
  2840  			if info.HumanId() == "aws_instance.bar" {
  2841  				checked = true
  2842  
  2843  				// Sleep to allow parallel execution
  2844  				time.Sleep(50 * time.Millisecond)
  2845  
  2846  				// Verify that called is 0 (dep not called)
  2847  				if atomic.LoadInt32(&called) != 0 {
  2848  					return nil, fmt.Errorf("nothing else should be called")
  2849  				}
  2850  			}
  2851  
  2852  			atomic.AddInt32(&called, 1)
  2853  			return testApplyFn(info, is, id)
  2854  		}
  2855  
  2856  		// Set the apply functions
  2857  		p.ApplyFn = applyFn
  2858  		p2.ApplyFn = applyFn
  2859  
  2860  		ctx := testContext2(t, &ContextOpts{
  2861  			Destroy: true,
  2862  			State:   state,
  2863  			Module:  m,
  2864  			Providers: map[string]ResourceProviderFactory{
  2865  				"aws":   testProviderFuncFixed(p),
  2866  				"vault": testProviderFuncFixed(p2),
  2867  			},
  2868  		})
  2869  
  2870  		if _, err := ctx.Plan(); err != nil {
  2871  			t.Fatalf("err: %s", err)
  2872  		}
  2873  
  2874  		s, err := ctx.Apply()
  2875  		if err != nil {
  2876  			t.Fatalf("err: %s", err)
  2877  		}
  2878  
  2879  		if !checked {
  2880  			t.Fatal("should be checked")
  2881  		}
  2882  
  2883  		state = s
  2884  	}
  2885  
  2886  	checkStateString(t, state, `<no state>`)
  2887  }
  2888  
  2889  // This is like the multiProviderDestroy test except it tests that
  2890  // dependent resources within a child module that inherit provider
  2891  // configuration are still destroyed first.
  2892  func TestContext2Apply_multiProviderDestroyChild(t *testing.T) {
  2893  	m := testModule(t, "apply-multi-provider-destroy-child")
  2894  	p := testProvider("aws")
  2895  	p.ApplyFn = testApplyFn
  2896  	p.DiffFn = testDiffFn
  2897  
  2898  	p2 := testProvider("do")
  2899  	p2.ApplyFn = testApplyFn
  2900  	p2.DiffFn = testDiffFn
  2901  
  2902  	var state *State
  2903  
  2904  	// First, create the instances
  2905  	{
  2906  		ctx := testContext2(t, &ContextOpts{
  2907  			Module: m,
  2908  			Providers: map[string]ResourceProviderFactory{
  2909  				"aws":   testProviderFuncFixed(p),
  2910  				"vault": testProviderFuncFixed(p2),
  2911  			},
  2912  		})
  2913  
  2914  		if _, err := ctx.Plan(); err != nil {
  2915  			t.Fatalf("err: %s", err)
  2916  		}
  2917  
  2918  		s, err := ctx.Apply()
  2919  		if err != nil {
  2920  			t.Fatalf("err: %s", err)
  2921  		}
  2922  
  2923  		state = s
  2924  	}
  2925  
  2926  	// Destroy them
  2927  	{
  2928  		// Verify that aws_instance.bar is destroyed first
  2929  		var checked bool
  2930  		var called int32
  2931  		var lock sync.Mutex
  2932  		applyFn := func(
  2933  			info *InstanceInfo,
  2934  			is *InstanceState,
  2935  			id *InstanceDiff) (*InstanceState, error) {
  2936  			lock.Lock()
  2937  			defer lock.Unlock()
  2938  
  2939  			if info.HumanId() == "module.child.aws_instance.bar" {
  2940  				checked = true
  2941  
  2942  				// Sleep to allow parallel execution
  2943  				time.Sleep(50 * time.Millisecond)
  2944  
  2945  				// Verify that called is 0 (dep not called)
  2946  				if atomic.LoadInt32(&called) != 0 {
  2947  					return nil, fmt.Errorf("nothing else should be called")
  2948  				}
  2949  			}
  2950  
  2951  			atomic.AddInt32(&called, 1)
  2952  			return testApplyFn(info, is, id)
  2953  		}
  2954  
  2955  		// Set the apply functions
  2956  		p.ApplyFn = applyFn
  2957  		p2.ApplyFn = applyFn
  2958  
  2959  		ctx := testContext2(t, &ContextOpts{
  2960  			Destroy: true,
  2961  			State:   state,
  2962  			Module:  m,
  2963  			Providers: map[string]ResourceProviderFactory{
  2964  				"aws":   testProviderFuncFixed(p),
  2965  				"vault": testProviderFuncFixed(p2),
  2966  			},
  2967  		})
  2968  
  2969  		if _, err := ctx.Plan(); err != nil {
  2970  			t.Fatalf("err: %s", err)
  2971  		}
  2972  
  2973  		s, err := ctx.Apply()
  2974  		if err != nil {
  2975  			t.Fatalf("err: %s", err)
  2976  		}
  2977  
  2978  		if !checked {
  2979  			t.Fatal("should be checked")
  2980  		}
  2981  
  2982  		state = s
  2983  	}
  2984  
  2985  	checkStateString(t, state, `
  2986  <no state>
  2987  module.child:
  2988    <no state>
  2989  `)
  2990  }
  2991  
  2992  func TestContext2Apply_multiVar(t *testing.T) {
  2993  	m := testModule(t, "apply-multi-var")
  2994  	p := testProvider("aws")
  2995  	p.ApplyFn = testApplyFn
  2996  	p.DiffFn = testDiffFn
  2997  
  2998  	// First, apply with a count of 3
  2999  	ctx := testContext2(t, &ContextOpts{
  3000  		Module: m,
  3001  		Providers: map[string]ResourceProviderFactory{
  3002  			"aws": testProviderFuncFixed(p),
  3003  		},
  3004  		Variables: map[string]interface{}{
  3005  			"count": "3",
  3006  		},
  3007  	})
  3008  
  3009  	if _, err := ctx.Plan(); err != nil {
  3010  		t.Fatalf("err: %s", err)
  3011  	}
  3012  
  3013  	state, err := ctx.Apply()
  3014  	if err != nil {
  3015  		t.Fatalf("err: %s", err)
  3016  	}
  3017  
  3018  	actual := state.RootModule().Outputs["output"]
  3019  	expected := "bar0,bar1,bar2"
  3020  	if actual == nil || actual.Value != expected {
  3021  		t.Fatalf("bad: \n%s", actual)
  3022  	}
  3023  
  3024  	t.Logf("Initial state: %s", state.String())
  3025  
  3026  	// Apply again, reduce the count to 1
  3027  	{
  3028  		ctx := testContext2(t, &ContextOpts{
  3029  			Module: m,
  3030  			State:  state,
  3031  			Providers: map[string]ResourceProviderFactory{
  3032  				"aws": testProviderFuncFixed(p),
  3033  			},
  3034  			Variables: map[string]interface{}{
  3035  				"count": "1",
  3036  			},
  3037  		})
  3038  
  3039  		if _, err := ctx.Plan(); err != nil {
  3040  			t.Fatalf("err: %s", err)
  3041  		}
  3042  
  3043  		state, err := ctx.Apply()
  3044  		if err != nil {
  3045  			t.Fatalf("err: %s", err)
  3046  		}
  3047  
  3048  		t.Logf("End state: %s", state.String())
  3049  
  3050  		actual := state.RootModule().Outputs["output"]
  3051  		if actual == nil {
  3052  			t.Fatal("missing output")
  3053  		}
  3054  
  3055  		expected := "bar0"
  3056  		if actual.Value != expected {
  3057  			t.Fatalf("bad: \n%s", actual)
  3058  		}
  3059  	}
  3060  }
  3061  
  3062  // Test that multi-var (splat) access is ordered by count, not by
  3063  // value.
  3064  func TestContext2Apply_multiVarOrder(t *testing.T) {
  3065  	m := testModule(t, "apply-multi-var-order")
  3066  	p := testProvider("aws")
  3067  	p.ApplyFn = testApplyFn
  3068  	p.DiffFn = testDiffFn
  3069  
  3070  	// First, apply with a count of 3
  3071  	ctx := testContext2(t, &ContextOpts{
  3072  		Module: m,
  3073  		Providers: map[string]ResourceProviderFactory{
  3074  			"aws": testProviderFuncFixed(p),
  3075  		},
  3076  	})
  3077  
  3078  	if _, err := ctx.Plan(); err != nil {
  3079  		t.Fatalf("err: %s", err)
  3080  	}
  3081  
  3082  	state, err := ctx.Apply()
  3083  	if err != nil {
  3084  		t.Fatalf("err: %s", err)
  3085  	}
  3086  
  3087  	t.Logf("State: %s", state.String())
  3088  
  3089  	actual := state.RootModule().Outputs["should-be-11"]
  3090  	expected := "index-11"
  3091  	if actual == nil || actual.Value != expected {
  3092  		t.Fatalf("bad: \n%s", actual)
  3093  	}
  3094  }
  3095  
  3096  // Test that multi-var (splat) access is ordered by count, not by
  3097  // value, through interpolations.
  3098  func TestContext2Apply_multiVarOrderInterp(t *testing.T) {
  3099  	m := testModule(t, "apply-multi-var-order-interp")
  3100  	p := testProvider("aws")
  3101  	p.ApplyFn = testApplyFn
  3102  	p.DiffFn = testDiffFn
  3103  
  3104  	// First, apply with a count of 3
  3105  	ctx := testContext2(t, &ContextOpts{
  3106  		Module: m,
  3107  		Providers: map[string]ResourceProviderFactory{
  3108  			"aws": testProviderFuncFixed(p),
  3109  		},
  3110  	})
  3111  
  3112  	if _, err := ctx.Plan(); err != nil {
  3113  		t.Fatalf("err: %s", err)
  3114  	}
  3115  
  3116  	state, err := ctx.Apply()
  3117  	if err != nil {
  3118  		t.Fatalf("err: %s", err)
  3119  	}
  3120  
  3121  	t.Logf("State: %s", state.String())
  3122  
  3123  	actual := state.RootModule().Outputs["should-be-11"]
  3124  	expected := "baz-index-11"
  3125  	if actual == nil || actual.Value != expected {
  3126  		t.Fatalf("bad: \n%s", actual)
  3127  	}
  3128  }
  3129  
  3130  // Based on GH-10440 where a graph edge wasn't properly being created
  3131  // between a modified resource and a count instance being destroyed.
  3132  func TestContext2Apply_multiVarCountDec(t *testing.T) {
  3133  	var s *State
  3134  
  3135  	// First create resources. Nothing sneaky here.
  3136  	{
  3137  		m := testModule(t, "apply-multi-var-count-dec")
  3138  		p := testProvider("aws")
  3139  		p.ApplyFn = testApplyFn
  3140  		p.DiffFn = testDiffFn
  3141  		ctx := testContext2(t, &ContextOpts{
  3142  			Module: m,
  3143  			Providers: map[string]ResourceProviderFactory{
  3144  				"aws": testProviderFuncFixed(p),
  3145  			},
  3146  			Variables: map[string]interface{}{
  3147  				"count": "2",
  3148  			},
  3149  		})
  3150  
  3151  		if _, err := ctx.Plan(); err != nil {
  3152  			t.Fatalf("err: %s", err)
  3153  		}
  3154  
  3155  		state, err := ctx.Apply()
  3156  		if err != nil {
  3157  			t.Fatalf("err: %s", err)
  3158  		}
  3159  
  3160  		t.Logf("Step 1 state: %s", state)
  3161  
  3162  		s = state
  3163  	}
  3164  
  3165  	// Decrease the count by 1 and verify that everything happens in the
  3166  	// right order.
  3167  	{
  3168  		m := testModule(t, "apply-multi-var-count-dec")
  3169  		p := testProvider("aws")
  3170  		p.ApplyFn = testApplyFn
  3171  		p.DiffFn = testDiffFn
  3172  
  3173  		// Verify that aws_instance.bar is modified first and nothing
  3174  		// else happens at the same time.
  3175  		var checked bool
  3176  		var called int32
  3177  		var lock sync.Mutex
  3178  		p.ApplyFn = func(
  3179  			info *InstanceInfo,
  3180  			is *InstanceState,
  3181  			id *InstanceDiff) (*InstanceState, error) {
  3182  			lock.Lock()
  3183  			defer lock.Unlock()
  3184  
  3185  			if info.HumanId() == "aws_instance.bar" {
  3186  				checked = true
  3187  
  3188  				// Sleep to allow parallel execution
  3189  				time.Sleep(50 * time.Millisecond)
  3190  
  3191  				// Verify that called is 0 (dep not called)
  3192  				if atomic.LoadInt32(&called) != 1 {
  3193  					return nil, fmt.Errorf("nothing else should be called")
  3194  				}
  3195  			}
  3196  
  3197  			atomic.AddInt32(&called, 1)
  3198  			return testApplyFn(info, is, id)
  3199  		}
  3200  
  3201  		ctx := testContext2(t, &ContextOpts{
  3202  			State:  s,
  3203  			Module: m,
  3204  			Providers: map[string]ResourceProviderFactory{
  3205  				"aws": testProviderFuncFixed(p),
  3206  			},
  3207  			Variables: map[string]interface{}{
  3208  				"count": "1",
  3209  			},
  3210  		})
  3211  
  3212  		if _, err := ctx.Plan(); err != nil {
  3213  			t.Fatalf("err: %s", err)
  3214  		}
  3215  
  3216  		state, err := ctx.Apply()
  3217  		if err != nil {
  3218  			t.Fatalf("err: %s", err)
  3219  		}
  3220  
  3221  		if !checked {
  3222  			t.Fatal("apply never called")
  3223  		}
  3224  
  3225  		t.Logf("Step 2 state: %s", state)
  3226  
  3227  		s = state
  3228  	}
  3229  }
  3230  
  3231  func TestContext2Apply_nilDiff(t *testing.T) {
  3232  	m := testModule(t, "apply-good")
  3233  	p := testProvider("aws")
  3234  	p.ApplyFn = testApplyFn
  3235  	p.DiffFn = testDiffFn
  3236  	ctx := testContext2(t, &ContextOpts{
  3237  		Module: m,
  3238  		Providers: map[string]ResourceProviderFactory{
  3239  			"aws": testProviderFuncFixed(p),
  3240  		},
  3241  	})
  3242  
  3243  	if _, err := ctx.Plan(); err != nil {
  3244  		t.Fatalf("err: %s", err)
  3245  	}
  3246  
  3247  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  3248  		return nil, nil
  3249  	}
  3250  
  3251  	if _, err := ctx.Apply(); err == nil {
  3252  		t.Fatal("should error")
  3253  	}
  3254  }
  3255  
  3256  func TestContext2Apply_outputDependsOn(t *testing.T) {
  3257  	m := testModule(t, "apply-output-depends-on")
  3258  	p := testProvider("aws")
  3259  	p.DiffFn = testDiffFn
  3260  
  3261  	{
  3262  		// Create a custom apply function that sleeps a bit (to allow parallel
  3263  		// graph execution) and then returns an error to force a partial state
  3264  		// return. We then verify the output is NOT there.
  3265  		p.ApplyFn = func(
  3266  			info *InstanceInfo,
  3267  			is *InstanceState,
  3268  			id *InstanceDiff) (*InstanceState, error) {
  3269  
  3270  			// Sleep to allow parallel execution
  3271  			time.Sleep(50 * time.Millisecond)
  3272  
  3273  			// Return error to force partial state
  3274  			return nil, fmt.Errorf("abcd")
  3275  		}
  3276  
  3277  		ctx := testContext2(t, &ContextOpts{
  3278  			Module: m,
  3279  			Providers: map[string]ResourceProviderFactory{
  3280  				"aws": testProviderFuncFixed(p),
  3281  			},
  3282  		})
  3283  
  3284  		if _, err := ctx.Plan(); err != nil {
  3285  			t.Fatalf("err: %s", err)
  3286  		}
  3287  
  3288  		state, err := ctx.Apply()
  3289  		if err == nil || !strings.Contains(err.Error(), "abcd") {
  3290  			t.Fatalf("err: %s", err)
  3291  		}
  3292  
  3293  		checkStateString(t, state, `<no state>`)
  3294  	}
  3295  
  3296  	{
  3297  		// Create the standard apply function and verify we get the output
  3298  		p.ApplyFn = testApplyFn
  3299  
  3300  		ctx := testContext2(t, &ContextOpts{
  3301  			Module: m,
  3302  			Providers: map[string]ResourceProviderFactory{
  3303  				"aws": testProviderFuncFixed(p),
  3304  			},
  3305  		})
  3306  
  3307  		if _, err := ctx.Plan(); err != nil {
  3308  			t.Fatalf("err: %s", err)
  3309  		}
  3310  
  3311  		state, err := ctx.Apply()
  3312  		if err != nil {
  3313  			t.Fatalf("err: %s", err)
  3314  		}
  3315  
  3316  		checkStateString(t, state, `
  3317  aws_instance.foo:
  3318    ID = foo
  3319  
  3320  Outputs:
  3321  
  3322  value = result
  3323  		`)
  3324  	}
  3325  }
  3326  
  3327  func TestContext2Apply_outputOrphan(t *testing.T) {
  3328  	m := testModule(t, "apply-output-orphan")
  3329  	p := testProvider("aws")
  3330  	p.ApplyFn = testApplyFn
  3331  	p.DiffFn = testDiffFn
  3332  
  3333  	state := &State{
  3334  		Modules: []*ModuleState{
  3335  			&ModuleState{
  3336  				Path: rootModulePath,
  3337  				Outputs: map[string]*OutputState{
  3338  					"foo": &OutputState{
  3339  						Type:      "string",
  3340  						Sensitive: false,
  3341  						Value:     "bar",
  3342  					},
  3343  					"bar": &OutputState{
  3344  						Type:      "string",
  3345  						Sensitive: false,
  3346  						Value:     "baz",
  3347  					},
  3348  				},
  3349  			},
  3350  		},
  3351  	}
  3352  
  3353  	ctx := testContext2(t, &ContextOpts{
  3354  		Module: m,
  3355  		Providers: map[string]ResourceProviderFactory{
  3356  			"aws": testProviderFuncFixed(p),
  3357  		},
  3358  		State: state,
  3359  	})
  3360  
  3361  	if _, err := ctx.Plan(); err != nil {
  3362  		t.Fatalf("err: %s", err)
  3363  	}
  3364  
  3365  	state, err := ctx.Apply()
  3366  	if err != nil {
  3367  		t.Fatalf("err: %s", err)
  3368  	}
  3369  
  3370  	actual := strings.TrimSpace(state.String())
  3371  	expected := strings.TrimSpace(testTerraformApplyOutputOrphanStr)
  3372  	if actual != expected {
  3373  		t.Fatalf("bad: \n%s", actual)
  3374  	}
  3375  }
  3376  
  3377  func TestContext2Apply_outputOrphanModule(t *testing.T) {
  3378  	m := testModule(t, "apply-output-orphan-module")
  3379  	p := testProvider("aws")
  3380  	p.ApplyFn = testApplyFn
  3381  	p.DiffFn = testDiffFn
  3382  
  3383  	state := &State{
  3384  		Modules: []*ModuleState{
  3385  			&ModuleState{
  3386  				Path: []string{"root", "child"},
  3387  				Outputs: map[string]*OutputState{
  3388  					"foo": &OutputState{
  3389  						Type:  "string",
  3390  						Value: "bar",
  3391  					},
  3392  					"bar": &OutputState{
  3393  						Type:  "string",
  3394  						Value: "baz",
  3395  					},
  3396  				},
  3397  			},
  3398  		},
  3399  	}
  3400  
  3401  	ctx := testContext2(t, &ContextOpts{
  3402  		Module: m,
  3403  		Providers: map[string]ResourceProviderFactory{
  3404  			"aws": testProviderFuncFixed(p),
  3405  		},
  3406  		State: state,
  3407  	})
  3408  
  3409  	if _, err := ctx.Plan(); err != nil {
  3410  		t.Fatalf("err: %s", err)
  3411  	}
  3412  
  3413  	state, err := ctx.Apply()
  3414  	if err != nil {
  3415  		t.Fatalf("err: %s", err)
  3416  	}
  3417  
  3418  	actual := strings.TrimSpace(state.String())
  3419  	expected := strings.TrimSpace(testTerraformApplyOutputOrphanModuleStr)
  3420  	if actual != expected {
  3421  		t.Fatalf("bad: \n%s", actual)
  3422  	}
  3423  }
  3424  
  3425  func TestContext2Apply_providerComputedVar(t *testing.T) {
  3426  	m := testModule(t, "apply-provider-computed")
  3427  	p := testProvider("aws")
  3428  	p.ApplyFn = testApplyFn
  3429  	p.DiffFn = testDiffFn
  3430  
  3431  	pTest := testProvider("test")
  3432  	pTest.ApplyFn = testApplyFn
  3433  	pTest.DiffFn = testDiffFn
  3434  
  3435  	ctx := testContext2(t, &ContextOpts{
  3436  		Module: m,
  3437  		Providers: map[string]ResourceProviderFactory{
  3438  			"aws":  testProviderFuncFixed(p),
  3439  			"test": testProviderFuncFixed(pTest),
  3440  		},
  3441  	})
  3442  
  3443  	p.ConfigureFn = func(c *ResourceConfig) error {
  3444  		if c.IsComputed("value") {
  3445  			return fmt.Errorf("value is computed")
  3446  		}
  3447  
  3448  		v, ok := c.Get("value")
  3449  		if !ok {
  3450  			return fmt.Errorf("value is not found")
  3451  		}
  3452  		if v != "yes" {
  3453  			return fmt.Errorf("value is not 'yes': %v", v)
  3454  		}
  3455  
  3456  		return nil
  3457  	}
  3458  
  3459  	if _, err := ctx.Plan(); err != nil {
  3460  		t.Fatalf("err: %s", err)
  3461  	}
  3462  
  3463  	if _, err := ctx.Apply(); err != nil {
  3464  		t.Fatalf("err: %s", err)
  3465  	}
  3466  }
  3467  
  3468  func TestContext2Apply_providerConfigureDisabled(t *testing.T) {
  3469  	m := testModule(t, "apply-provider-configure-disabled")
  3470  	p := testProvider("aws")
  3471  	p.ApplyFn = testApplyFn
  3472  	p.DiffFn = testDiffFn
  3473  
  3474  	called := false
  3475  	p.ConfigureFn = func(c *ResourceConfig) error {
  3476  		called = true
  3477  
  3478  		if _, ok := c.Get("value"); !ok {
  3479  			return fmt.Errorf("value is not found")
  3480  		}
  3481  
  3482  		return nil
  3483  	}
  3484  
  3485  	ctx := testContext2(t, &ContextOpts{
  3486  		Module: m,
  3487  		Providers: map[string]ResourceProviderFactory{
  3488  			"aws": testProviderFuncFixed(p),
  3489  		},
  3490  	})
  3491  
  3492  	if _, err := ctx.Plan(); err != nil {
  3493  		t.Fatalf("err: %s", err)
  3494  	}
  3495  
  3496  	if _, err := ctx.Apply(); err != nil {
  3497  		t.Fatalf("err: %s", err)
  3498  	}
  3499  
  3500  	if !called {
  3501  		t.Fatal("configure never called")
  3502  	}
  3503  }
  3504  
  3505  func TestContext2Apply_provisionerModule(t *testing.T) {
  3506  	m := testModule(t, "apply-provisioner-module")
  3507  	p := testProvider("aws")
  3508  	pr := testProvisioner()
  3509  	p.ApplyFn = testApplyFn
  3510  	p.DiffFn = testDiffFn
  3511  	ctx := testContext2(t, &ContextOpts{
  3512  		Module: m,
  3513  		Providers: map[string]ResourceProviderFactory{
  3514  			"aws": testProviderFuncFixed(p),
  3515  		},
  3516  		Provisioners: map[string]ResourceProvisionerFactory{
  3517  			"shell": testProvisionerFuncFixed(pr),
  3518  		},
  3519  	})
  3520  
  3521  	if _, err := ctx.Plan(); err != nil {
  3522  		t.Fatalf("err: %s", err)
  3523  	}
  3524  
  3525  	state, err := ctx.Apply()
  3526  	if err != nil {
  3527  		t.Fatalf("err: %s", err)
  3528  	}
  3529  
  3530  	actual := strings.TrimSpace(state.String())
  3531  	expected := strings.TrimSpace(testTerraformApplyProvisionerModuleStr)
  3532  	if actual != expected {
  3533  		t.Fatalf("bad: \n%s", actual)
  3534  	}
  3535  
  3536  	// Verify apply was invoked
  3537  	if !pr.ApplyCalled {
  3538  		t.Fatalf("provisioner not invoked")
  3539  	}
  3540  }
  3541  
  3542  func TestContext2Apply_Provisioner_compute(t *testing.T) {
  3543  	m := testModule(t, "apply-provisioner-compute")
  3544  	p := testProvider("aws")
  3545  	pr := testProvisioner()
  3546  	p.ApplyFn = testApplyFn
  3547  	p.DiffFn = testDiffFn
  3548  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  3549  		val, ok := c.Config["foo"]
  3550  		if !ok || val != "computed_dynamical" {
  3551  			t.Fatalf("bad value for foo: %v %#v", val, c)
  3552  		}
  3553  
  3554  		return nil
  3555  	}
  3556  	ctx := testContext2(t, &ContextOpts{
  3557  		Module: m,
  3558  		Providers: map[string]ResourceProviderFactory{
  3559  			"aws": testProviderFuncFixed(p),
  3560  		},
  3561  		Provisioners: map[string]ResourceProvisionerFactory{
  3562  			"shell": testProvisionerFuncFixed(pr),
  3563  		},
  3564  		Variables: map[string]interface{}{
  3565  			"value": "1",
  3566  		},
  3567  	})
  3568  
  3569  	if _, err := ctx.Plan(); err != nil {
  3570  		t.Fatalf("err: %s", err)
  3571  	}
  3572  
  3573  	state, err := ctx.Apply()
  3574  	if err != nil {
  3575  		t.Fatalf("err: %s", err)
  3576  	}
  3577  
  3578  	actual := strings.TrimSpace(state.String())
  3579  	expected := strings.TrimSpace(testTerraformApplyProvisionerStr)
  3580  	if actual != expected {
  3581  		t.Fatalf("bad: \n%s", actual)
  3582  	}
  3583  
  3584  	// Verify apply was invoked
  3585  	if !pr.ApplyCalled {
  3586  		t.Fatalf("provisioner not invoked")
  3587  	}
  3588  }
  3589  
  3590  func TestContext2Apply_provisionerCreateFail(t *testing.T) {
  3591  	m := testModule(t, "apply-provisioner-fail-create")
  3592  	p := testProvider("aws")
  3593  	pr := testProvisioner()
  3594  	p.DiffFn = testDiffFn
  3595  
  3596  	p.ApplyFn = func(
  3597  		info *InstanceInfo,
  3598  		is *InstanceState,
  3599  		id *InstanceDiff) (*InstanceState, error) {
  3600  		is.ID = "foo"
  3601  		return is, fmt.Errorf("error")
  3602  	}
  3603  
  3604  	ctx := testContext2(t, &ContextOpts{
  3605  		Module: m,
  3606  		Providers: map[string]ResourceProviderFactory{
  3607  			"aws": testProviderFuncFixed(p),
  3608  		},
  3609  		Provisioners: map[string]ResourceProvisionerFactory{
  3610  			"shell": testProvisionerFuncFixed(pr),
  3611  		},
  3612  	})
  3613  
  3614  	if _, err := ctx.Plan(); err != nil {
  3615  		t.Fatalf("err: %s", err)
  3616  	}
  3617  
  3618  	state, err := ctx.Apply()
  3619  	if err == nil {
  3620  		t.Fatal("should error")
  3621  	}
  3622  
  3623  	actual := strings.TrimSpace(state.String())
  3624  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailCreateStr)
  3625  	if actual != expected {
  3626  		t.Fatalf("bad: \n%s", actual)
  3627  	}
  3628  }
  3629  
  3630  func TestContext2Apply_provisionerCreateFailNoId(t *testing.T) {
  3631  	m := testModule(t, "apply-provisioner-fail-create")
  3632  	p := testProvider("aws")
  3633  	pr := testProvisioner()
  3634  	p.DiffFn = testDiffFn
  3635  
  3636  	p.ApplyFn = func(
  3637  		info *InstanceInfo,
  3638  		is *InstanceState,
  3639  		id *InstanceDiff) (*InstanceState, error) {
  3640  		return nil, fmt.Errorf("error")
  3641  	}
  3642  
  3643  	ctx := testContext2(t, &ContextOpts{
  3644  		Module: m,
  3645  		Providers: map[string]ResourceProviderFactory{
  3646  			"aws": testProviderFuncFixed(p),
  3647  		},
  3648  		Provisioners: map[string]ResourceProvisionerFactory{
  3649  			"shell": testProvisionerFuncFixed(pr),
  3650  		},
  3651  	})
  3652  
  3653  	if _, err := ctx.Plan(); err != nil {
  3654  		t.Fatalf("err: %s", err)
  3655  	}
  3656  
  3657  	state, err := ctx.Apply()
  3658  	if err == nil {
  3659  		t.Fatal("should error")
  3660  	}
  3661  
  3662  	actual := strings.TrimSpace(state.String())
  3663  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailCreateNoIdStr)
  3664  	if actual != expected {
  3665  		t.Fatalf("bad: \n%s", actual)
  3666  	}
  3667  }
  3668  
  3669  func TestContext2Apply_provisionerFail(t *testing.T) {
  3670  	m := testModule(t, "apply-provisioner-fail")
  3671  	p := testProvider("aws")
  3672  	pr := testProvisioner()
  3673  	p.ApplyFn = testApplyFn
  3674  	p.DiffFn = testDiffFn
  3675  
  3676  	pr.ApplyFn = func(*InstanceState, *ResourceConfig) error {
  3677  		return fmt.Errorf("EXPLOSION")
  3678  	}
  3679  
  3680  	ctx := testContext2(t, &ContextOpts{
  3681  		Module: m,
  3682  		Providers: map[string]ResourceProviderFactory{
  3683  			"aws": testProviderFuncFixed(p),
  3684  		},
  3685  		Provisioners: map[string]ResourceProvisionerFactory{
  3686  			"shell": testProvisionerFuncFixed(pr),
  3687  		},
  3688  		Variables: map[string]interface{}{
  3689  			"value": "1",
  3690  		},
  3691  	})
  3692  
  3693  	if _, err := ctx.Plan(); err != nil {
  3694  		t.Fatalf("err: %s", err)
  3695  	}
  3696  
  3697  	state, err := ctx.Apply()
  3698  	if err == nil {
  3699  		t.Fatal("should error")
  3700  	}
  3701  
  3702  	actual := strings.TrimSpace(state.String())
  3703  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailStr)
  3704  	if actual != expected {
  3705  		t.Fatalf("bad: \n%s", actual)
  3706  	}
  3707  }
  3708  
  3709  func TestContext2Apply_provisionerFail_createBeforeDestroy(t *testing.T) {
  3710  	m := testModule(t, "apply-provisioner-fail-create-before")
  3711  	p := testProvider("aws")
  3712  	pr := testProvisioner()
  3713  	p.ApplyFn = testApplyFn
  3714  	p.DiffFn = testDiffFn
  3715  	pr.ApplyFn = func(*InstanceState, *ResourceConfig) error {
  3716  		return fmt.Errorf("EXPLOSION")
  3717  	}
  3718  
  3719  	state := &State{
  3720  		Modules: []*ModuleState{
  3721  			&ModuleState{
  3722  				Path: rootModulePath,
  3723  				Resources: map[string]*ResourceState{
  3724  					"aws_instance.bar": &ResourceState{
  3725  						Type: "aws_instance",
  3726  						Primary: &InstanceState{
  3727  							ID: "bar",
  3728  							Attributes: map[string]string{
  3729  								"require_new": "abc",
  3730  							},
  3731  						},
  3732  					},
  3733  				},
  3734  			},
  3735  		},
  3736  	}
  3737  	ctx := testContext2(t, &ContextOpts{
  3738  		Module: m,
  3739  		Providers: map[string]ResourceProviderFactory{
  3740  			"aws": testProviderFuncFixed(p),
  3741  		},
  3742  		Provisioners: map[string]ResourceProvisionerFactory{
  3743  			"shell": testProvisionerFuncFixed(pr),
  3744  		},
  3745  		State: state,
  3746  	})
  3747  
  3748  	if _, err := ctx.Plan(); err != nil {
  3749  		t.Fatalf("err: %s", err)
  3750  	}
  3751  
  3752  	state, err := ctx.Apply()
  3753  	if err == nil {
  3754  		t.Fatal("should error")
  3755  	}
  3756  
  3757  	actual := strings.TrimSpace(state.String())
  3758  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailCreateBeforeDestroyStr)
  3759  	if actual != expected {
  3760  		t.Fatalf("bad: \n%s", actual)
  3761  	}
  3762  }
  3763  
  3764  func TestContext2Apply_error_createBeforeDestroy(t *testing.T) {
  3765  	m := testModule(t, "apply-error-create-before")
  3766  	p := testProvider("aws")
  3767  	state := &State{
  3768  		Modules: []*ModuleState{
  3769  			&ModuleState{
  3770  				Path: rootModulePath,
  3771  				Resources: map[string]*ResourceState{
  3772  					"aws_instance.bar": &ResourceState{
  3773  						Type: "aws_instance",
  3774  						Primary: &InstanceState{
  3775  							ID: "bar",
  3776  							Attributes: map[string]string{
  3777  								"require_new": "abc",
  3778  							},
  3779  						},
  3780  					},
  3781  				},
  3782  			},
  3783  		},
  3784  	}
  3785  	ctx := testContext2(t, &ContextOpts{
  3786  		Module: m,
  3787  		Providers: map[string]ResourceProviderFactory{
  3788  			"aws": testProviderFuncFixed(p),
  3789  		},
  3790  		State: state,
  3791  	})
  3792  	p.ApplyFn = func(info *InstanceInfo, is *InstanceState, id *InstanceDiff) (*InstanceState, error) {
  3793  		return nil, fmt.Errorf("error")
  3794  	}
  3795  	p.DiffFn = testDiffFn
  3796  
  3797  	if _, err := ctx.Plan(); err != nil {
  3798  		t.Fatalf("err: %s", err)
  3799  	}
  3800  
  3801  	state, err := ctx.Apply()
  3802  	if err == nil {
  3803  		t.Fatal("should have error")
  3804  	}
  3805  
  3806  	actual := strings.TrimSpace(state.String())
  3807  	expected := strings.TrimSpace(testTerraformApplyErrorCreateBeforeDestroyStr)
  3808  	if actual != expected {
  3809  		t.Fatalf("bad: \n%s\n\nExpected:\n\n%s", actual, expected)
  3810  	}
  3811  }
  3812  
  3813  func TestContext2Apply_errorDestroy_createBeforeDestroy(t *testing.T) {
  3814  	m := testModule(t, "apply-error-create-before")
  3815  	p := testProvider("aws")
  3816  	state := &State{
  3817  		Modules: []*ModuleState{
  3818  			&ModuleState{
  3819  				Path: rootModulePath,
  3820  				Resources: map[string]*ResourceState{
  3821  					"aws_instance.bar": &ResourceState{
  3822  						Type: "aws_instance",
  3823  						Primary: &InstanceState{
  3824  							ID: "bar",
  3825  							Attributes: map[string]string{
  3826  								"require_new": "abc",
  3827  							},
  3828  						},
  3829  					},
  3830  				},
  3831  			},
  3832  		},
  3833  	}
  3834  	ctx := testContext2(t, &ContextOpts{
  3835  		Module: m,
  3836  		Providers: map[string]ResourceProviderFactory{
  3837  			"aws": testProviderFuncFixed(p),
  3838  		},
  3839  		State: state,
  3840  	})
  3841  	p.ApplyFn = func(info *InstanceInfo, is *InstanceState, id *InstanceDiff) (*InstanceState, error) {
  3842  		// Fail the destroy!
  3843  		if id.Destroy {
  3844  			return is, fmt.Errorf("error")
  3845  		}
  3846  
  3847  		// Create should work
  3848  		is = &InstanceState{
  3849  			ID: "foo",
  3850  		}
  3851  		return is, nil
  3852  	}
  3853  	p.DiffFn = testDiffFn
  3854  
  3855  	if _, err := ctx.Plan(); err != nil {
  3856  		t.Fatalf("err: %s", err)
  3857  	}
  3858  
  3859  	state, err := ctx.Apply()
  3860  	if err == nil {
  3861  		t.Fatal("should have error")
  3862  	}
  3863  
  3864  	actual := strings.TrimSpace(state.String())
  3865  	expected := strings.TrimSpace(testTerraformApplyErrorDestroyCreateBeforeDestroyStr)
  3866  	if actual != expected {
  3867  		t.Fatalf("bad: actual:\n%s\n\nexpected:\n%s", actual, expected)
  3868  	}
  3869  }
  3870  
  3871  func TestContext2Apply_multiDepose_createBeforeDestroy(t *testing.T) {
  3872  	m := testModule(t, "apply-multi-depose-create-before-destroy")
  3873  	p := testProvider("aws")
  3874  	p.DiffFn = testDiffFn
  3875  	ps := map[string]ResourceProviderFactory{"aws": testProviderFuncFixed(p)}
  3876  	state := &State{
  3877  		Modules: []*ModuleState{
  3878  			&ModuleState{
  3879  				Path: rootModulePath,
  3880  				Resources: map[string]*ResourceState{
  3881  					"aws_instance.web": &ResourceState{
  3882  						Type:    "aws_instance",
  3883  						Primary: &InstanceState{ID: "foo"},
  3884  					},
  3885  				},
  3886  			},
  3887  		},
  3888  	}
  3889  
  3890  	ctx := testContext2(t, &ContextOpts{
  3891  		Module:    m,
  3892  		Providers: ps,
  3893  		State:     state,
  3894  	})
  3895  	createdInstanceId := "bar"
  3896  	// Create works
  3897  	createFunc := func(is *InstanceState) (*InstanceState, error) {
  3898  		return &InstanceState{ID: createdInstanceId}, nil
  3899  	}
  3900  	// Destroy starts broken
  3901  	destroyFunc := func(is *InstanceState) (*InstanceState, error) {
  3902  		return is, fmt.Errorf("destroy failed")
  3903  	}
  3904  	p.ApplyFn = func(info *InstanceInfo, is *InstanceState, id *InstanceDiff) (*InstanceState, error) {
  3905  		if id.Destroy {
  3906  			return destroyFunc(is)
  3907  		} else {
  3908  			return createFunc(is)
  3909  		}
  3910  	}
  3911  
  3912  	if _, err := ctx.Plan(); err != nil {
  3913  		t.Fatalf("err: %s", err)
  3914  	}
  3915  
  3916  	// Destroy is broken, so even though CBD successfully replaces the instance,
  3917  	// we'll have to save the Deposed instance to destroy later
  3918  	state, err := ctx.Apply()
  3919  	if err == nil {
  3920  		t.Fatal("should have error")
  3921  	}
  3922  
  3923  	checkStateString(t, state, `
  3924  aws_instance.web: (1 deposed)
  3925    ID = bar
  3926    Deposed ID 1 = foo
  3927  	`)
  3928  
  3929  	createdInstanceId = "baz"
  3930  	ctx = testContext2(t, &ContextOpts{
  3931  		Module:    m,
  3932  		Providers: ps,
  3933  		State:     state,
  3934  	})
  3935  
  3936  	if _, err := ctx.Plan(); err != nil {
  3937  		t.Fatalf("err: %s", err)
  3938  	}
  3939  
  3940  	// We're replacing the primary instance once again. Destroy is _still_
  3941  	// broken, so the Deposed list gets longer
  3942  	state, err = ctx.Apply()
  3943  	if err == nil {
  3944  		t.Fatal("should have error")
  3945  	}
  3946  
  3947  	checkStateString(t, state, `
  3948  aws_instance.web: (2 deposed)
  3949    ID = baz
  3950    Deposed ID 1 = foo
  3951    Deposed ID 2 = bar
  3952  	`)
  3953  
  3954  	// Destroy partially fixed!
  3955  	destroyFunc = func(is *InstanceState) (*InstanceState, error) {
  3956  		if is.ID == "foo" || is.ID == "baz" {
  3957  			return nil, nil
  3958  		} else {
  3959  			return is, fmt.Errorf("destroy partially failed")
  3960  		}
  3961  	}
  3962  
  3963  	createdInstanceId = "qux"
  3964  	if _, err := ctx.Plan(); err != nil {
  3965  		t.Fatalf("err: %s", err)
  3966  	}
  3967  	state, err = ctx.Apply()
  3968  	// Expect error because 1/2 of Deposed destroys failed
  3969  	if err == nil {
  3970  		t.Fatal("should have error")
  3971  	}
  3972  
  3973  	// foo and baz are now gone, bar sticks around
  3974  	checkStateString(t, state, `
  3975  aws_instance.web: (1 deposed)
  3976    ID = qux
  3977    Deposed ID 1 = bar
  3978  	`)
  3979  
  3980  	// Destroy working fully!
  3981  	destroyFunc = func(is *InstanceState) (*InstanceState, error) {
  3982  		return nil, nil
  3983  	}
  3984  
  3985  	createdInstanceId = "quux"
  3986  	if _, err := ctx.Plan(); err != nil {
  3987  		t.Fatalf("err: %s", err)
  3988  	}
  3989  	state, err = ctx.Apply()
  3990  	if err != nil {
  3991  		t.Fatal("should not have error:", err)
  3992  	}
  3993  
  3994  	// And finally the state is clean
  3995  	checkStateString(t, state, `
  3996  aws_instance.web:
  3997    ID = quux
  3998  	`)
  3999  }
  4000  
  4001  func TestContext2Apply_provisionerResourceRef(t *testing.T) {
  4002  	m := testModule(t, "apply-provisioner-resource-ref")
  4003  	p := testProvider("aws")
  4004  	pr := testProvisioner()
  4005  	p.ApplyFn = testApplyFn
  4006  	p.DiffFn = testDiffFn
  4007  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  4008  		val, ok := c.Config["foo"]
  4009  		if !ok || val != "2" {
  4010  			t.Fatalf("bad value for foo: %v %#v", val, c)
  4011  		}
  4012  
  4013  		return nil
  4014  	}
  4015  
  4016  	ctx := testContext2(t, &ContextOpts{
  4017  		Module: m,
  4018  		Providers: map[string]ResourceProviderFactory{
  4019  			"aws": testProviderFuncFixed(p),
  4020  		},
  4021  		Provisioners: map[string]ResourceProvisionerFactory{
  4022  			"shell": testProvisionerFuncFixed(pr),
  4023  		},
  4024  	})
  4025  
  4026  	if _, err := ctx.Plan(); err != nil {
  4027  		t.Fatalf("err: %s", err)
  4028  	}
  4029  
  4030  	state, err := ctx.Apply()
  4031  	if err != nil {
  4032  		t.Fatalf("err: %s", err)
  4033  	}
  4034  
  4035  	actual := strings.TrimSpace(state.String())
  4036  	expected := strings.TrimSpace(testTerraformApplyProvisionerResourceRefStr)
  4037  	if actual != expected {
  4038  		t.Fatalf("bad: \n%s", actual)
  4039  	}
  4040  
  4041  	// Verify apply was invoked
  4042  	if !pr.ApplyCalled {
  4043  		t.Fatalf("provisioner not invoked")
  4044  	}
  4045  }
  4046  
  4047  func TestContext2Apply_provisionerSelfRef(t *testing.T) {
  4048  	m := testModule(t, "apply-provisioner-self-ref")
  4049  	p := testProvider("aws")
  4050  	pr := testProvisioner()
  4051  	p.ApplyFn = testApplyFn
  4052  	p.DiffFn = testDiffFn
  4053  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  4054  		val, ok := c.Config["command"]
  4055  		if !ok || val != "bar" {
  4056  			t.Fatalf("bad value for command: %v %#v", val, c)
  4057  		}
  4058  
  4059  		return nil
  4060  	}
  4061  
  4062  	ctx := testContext2(t, &ContextOpts{
  4063  		Module: m,
  4064  		Providers: map[string]ResourceProviderFactory{
  4065  			"aws": testProviderFuncFixed(p),
  4066  		},
  4067  		Provisioners: map[string]ResourceProvisionerFactory{
  4068  			"shell": testProvisionerFuncFixed(pr),
  4069  		},
  4070  	})
  4071  
  4072  	if _, err := ctx.Plan(); err != nil {
  4073  		t.Fatalf("err: %s", err)
  4074  	}
  4075  
  4076  	state, err := ctx.Apply()
  4077  	if err != nil {
  4078  		t.Fatalf("err: %s", err)
  4079  	}
  4080  
  4081  	actual := strings.TrimSpace(state.String())
  4082  	expected := strings.TrimSpace(testTerraformApplyProvisionerSelfRefStr)
  4083  	if actual != expected {
  4084  		t.Fatalf("bad: \n%s", actual)
  4085  	}
  4086  
  4087  	// Verify apply was invoked
  4088  	if !pr.ApplyCalled {
  4089  		t.Fatalf("provisioner not invoked")
  4090  	}
  4091  }
  4092  
  4093  func TestContext2Apply_provisionerMultiSelfRef(t *testing.T) {
  4094  	var lock sync.Mutex
  4095  	commands := make([]string, 0, 5)
  4096  
  4097  	m := testModule(t, "apply-provisioner-multi-self-ref")
  4098  	p := testProvider("aws")
  4099  	pr := testProvisioner()
  4100  	p.ApplyFn = testApplyFn
  4101  	p.DiffFn = testDiffFn
  4102  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  4103  		lock.Lock()
  4104  		defer lock.Unlock()
  4105  
  4106  		val, ok := c.Config["command"]
  4107  		if !ok {
  4108  			t.Fatalf("bad value for command: %v %#v", val, c)
  4109  		}
  4110  
  4111  		commands = append(commands, val.(string))
  4112  		return nil
  4113  	}
  4114  
  4115  	ctx := testContext2(t, &ContextOpts{
  4116  		Module: m,
  4117  		Providers: map[string]ResourceProviderFactory{
  4118  			"aws": testProviderFuncFixed(p),
  4119  		},
  4120  		Provisioners: map[string]ResourceProvisionerFactory{
  4121  			"shell": testProvisionerFuncFixed(pr),
  4122  		},
  4123  	})
  4124  
  4125  	if _, err := ctx.Plan(); err != nil {
  4126  		t.Fatalf("err: %s", err)
  4127  	}
  4128  
  4129  	state, err := ctx.Apply()
  4130  	if err != nil {
  4131  		t.Fatalf("err: %s", err)
  4132  	}
  4133  
  4134  	actual := strings.TrimSpace(state.String())
  4135  	expected := strings.TrimSpace(testTerraformApplyProvisionerMultiSelfRefStr)
  4136  	if actual != expected {
  4137  		t.Fatalf("bad: \n%s", actual)
  4138  	}
  4139  
  4140  	// Verify apply was invoked
  4141  	if !pr.ApplyCalled {
  4142  		t.Fatalf("provisioner not invoked")
  4143  	}
  4144  
  4145  	// Verify our result
  4146  	sort.Strings(commands)
  4147  	expectedCommands := []string{"number 0", "number 1", "number 2"}
  4148  	if !reflect.DeepEqual(commands, expectedCommands) {
  4149  		t.Fatalf("bad: %#v", commands)
  4150  	}
  4151  }
  4152  
  4153  func TestContext2Apply_provisionerMultiSelfRefSingle(t *testing.T) {
  4154  	var lock sync.Mutex
  4155  	order := make([]string, 0, 5)
  4156  
  4157  	m := testModule(t, "apply-provisioner-multi-self-ref-single")
  4158  	p := testProvider("aws")
  4159  	pr := testProvisioner()
  4160  	p.ApplyFn = testApplyFn
  4161  	p.DiffFn = testDiffFn
  4162  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  4163  		lock.Lock()
  4164  		defer lock.Unlock()
  4165  
  4166  		val, ok := c.Config["order"]
  4167  		if !ok {
  4168  			t.Fatalf("bad value for order: %v %#v", val, c)
  4169  		}
  4170  
  4171  		order = append(order, val.(string))
  4172  		return nil
  4173  	}
  4174  
  4175  	ctx := testContext2(t, &ContextOpts{
  4176  		Module: m,
  4177  		Providers: map[string]ResourceProviderFactory{
  4178  			"aws": testProviderFuncFixed(p),
  4179  		},
  4180  		Provisioners: map[string]ResourceProvisionerFactory{
  4181  			"shell": testProvisionerFuncFixed(pr),
  4182  		},
  4183  	})
  4184  
  4185  	if _, err := ctx.Plan(); err != nil {
  4186  		t.Fatalf("err: %s", err)
  4187  	}
  4188  
  4189  	state, err := ctx.Apply()
  4190  	if err != nil {
  4191  		t.Fatalf("err: %s", err)
  4192  	}
  4193  
  4194  	actual := strings.TrimSpace(state.String())
  4195  	expected := strings.TrimSpace(testTerraformApplyProvisionerMultiSelfRefSingleStr)
  4196  	if actual != expected {
  4197  		t.Fatalf("bad: \n%s", actual)
  4198  	}
  4199  
  4200  	// Verify apply was invoked
  4201  	if !pr.ApplyCalled {
  4202  		t.Fatalf("provisioner not invoked")
  4203  	}
  4204  
  4205  	// Verify our result
  4206  	sort.Strings(order)
  4207  	expectedOrder := []string{"0", "1", "2"}
  4208  	if !reflect.DeepEqual(order, expectedOrder) {
  4209  		t.Fatalf("bad: %#v", order)
  4210  	}
  4211  }
  4212  
  4213  func TestContext2Apply_provisionerMultiSelfRefCount(t *testing.T) {
  4214  	var lock sync.Mutex
  4215  	commands := make([]string, 0, 5)
  4216  
  4217  	m := testModule(t, "apply-provisioner-multi-self-ref-count")
  4218  	p := testProvider("aws")
  4219  	pr := testProvisioner()
  4220  	p.ApplyFn = testApplyFn
  4221  	p.DiffFn = testDiffFn
  4222  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  4223  		lock.Lock()
  4224  		defer lock.Unlock()
  4225  
  4226  		val, ok := c.Config["command"]
  4227  		if !ok {
  4228  			t.Fatalf("bad value for command: %v %#v", val, c)
  4229  		}
  4230  
  4231  		commands = append(commands, val.(string))
  4232  		return nil
  4233  	}
  4234  
  4235  	ctx := testContext2(t, &ContextOpts{
  4236  		Module: m,
  4237  		Providers: map[string]ResourceProviderFactory{
  4238  			"aws": testProviderFuncFixed(p),
  4239  		},
  4240  		Provisioners: map[string]ResourceProvisionerFactory{
  4241  			"shell": testProvisionerFuncFixed(pr),
  4242  		},
  4243  	})
  4244  
  4245  	if _, err := ctx.Plan(); err != nil {
  4246  		t.Fatalf("err: %s", err)
  4247  	}
  4248  
  4249  	if _, err := ctx.Apply(); err != nil {
  4250  		t.Fatalf("err: %s", err)
  4251  	}
  4252  
  4253  	// Verify apply was invoked
  4254  	if !pr.ApplyCalled {
  4255  		t.Fatalf("provisioner not invoked")
  4256  	}
  4257  
  4258  	// Verify our result
  4259  	sort.Strings(commands)
  4260  	expectedCommands := []string{"3", "3", "3"}
  4261  	if !reflect.DeepEqual(commands, expectedCommands) {
  4262  		t.Fatalf("bad: %#v", commands)
  4263  	}
  4264  }
  4265  
  4266  func TestContext2Apply_provisionerExplicitSelfRef(t *testing.T) {
  4267  	m := testModule(t, "apply-provisioner-explicit-self-ref")
  4268  	p := testProvider("aws")
  4269  	pr := testProvisioner()
  4270  	p.ApplyFn = testApplyFn
  4271  	p.DiffFn = testDiffFn
  4272  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  4273  		val, ok := c.Config["command"]
  4274  		if !ok || val != "bar" {
  4275  			t.Fatalf("bad value for command: %v %#v", val, c)
  4276  		}
  4277  
  4278  		return nil
  4279  	}
  4280  
  4281  	var state *State
  4282  	{
  4283  		ctx := testContext2(t, &ContextOpts{
  4284  			Module: m,
  4285  			Providers: map[string]ResourceProviderFactory{
  4286  				"aws": testProviderFuncFixed(p),
  4287  			},
  4288  			Provisioners: map[string]ResourceProvisionerFactory{
  4289  				"shell": testProvisionerFuncFixed(pr),
  4290  			},
  4291  		})
  4292  
  4293  		_, err := ctx.Plan()
  4294  		if err != nil {
  4295  			t.Fatalf("err: %s", err)
  4296  		}
  4297  
  4298  		state, err = ctx.Apply()
  4299  		if err != nil {
  4300  			t.Fatalf("err: %s", err)
  4301  		}
  4302  
  4303  		// Verify apply was invoked
  4304  		if !pr.ApplyCalled {
  4305  			t.Fatalf("provisioner not invoked")
  4306  		}
  4307  	}
  4308  
  4309  	{
  4310  		ctx := testContext2(t, &ContextOpts{
  4311  			Module:  m,
  4312  			Destroy: true,
  4313  			State:   state,
  4314  			Providers: map[string]ResourceProviderFactory{
  4315  				"aws": testProviderFuncFixed(p),
  4316  			},
  4317  			Provisioners: map[string]ResourceProvisionerFactory{
  4318  				"shell": testProvisionerFuncFixed(pr),
  4319  			},
  4320  		})
  4321  
  4322  		_, err := ctx.Plan()
  4323  		if err != nil {
  4324  			t.Fatalf("err: %s", err)
  4325  		}
  4326  
  4327  		state, err = ctx.Apply()
  4328  		if err != nil {
  4329  			t.Fatalf("err: %s", err)
  4330  		}
  4331  
  4332  		checkStateString(t, state, `<no state>`)
  4333  	}
  4334  }
  4335  
  4336  // Provisioner should NOT run on a diff, only create
  4337  func TestContext2Apply_Provisioner_Diff(t *testing.T) {
  4338  	m := testModule(t, "apply-provisioner-diff")
  4339  	p := testProvider("aws")
  4340  	pr := testProvisioner()
  4341  	p.ApplyFn = testApplyFn
  4342  	p.DiffFn = testDiffFn
  4343  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  4344  		return nil
  4345  	}
  4346  	ctx := testContext2(t, &ContextOpts{
  4347  		Module: m,
  4348  		Providers: map[string]ResourceProviderFactory{
  4349  			"aws": testProviderFuncFixed(p),
  4350  		},
  4351  		Provisioners: map[string]ResourceProvisionerFactory{
  4352  			"shell": testProvisionerFuncFixed(pr),
  4353  		},
  4354  	})
  4355  
  4356  	if _, err := ctx.Plan(); err != nil {
  4357  		t.Fatalf("err: %s", err)
  4358  	}
  4359  
  4360  	state, err := ctx.Apply()
  4361  	if err != nil {
  4362  		t.Fatalf("err: %s", err)
  4363  	}
  4364  
  4365  	actual := strings.TrimSpace(state.String())
  4366  	expected := strings.TrimSpace(testTerraformApplyProvisionerDiffStr)
  4367  	if actual != expected {
  4368  		t.Fatalf("bad: \n%s", actual)
  4369  	}
  4370  
  4371  	// Verify apply was invoked
  4372  	if !pr.ApplyCalled {
  4373  		t.Fatalf("provisioner not invoked")
  4374  	}
  4375  	pr.ApplyCalled = false
  4376  
  4377  	// Change the state to force a diff
  4378  	mod := state.RootModule()
  4379  	mod.Resources["aws_instance.bar"].Primary.Attributes["foo"] = "baz"
  4380  
  4381  	// Re-create context with state
  4382  	ctx = testContext2(t, &ContextOpts{
  4383  		Module: m,
  4384  		Providers: map[string]ResourceProviderFactory{
  4385  			"aws": testProviderFuncFixed(p),
  4386  		},
  4387  		Provisioners: map[string]ResourceProvisionerFactory{
  4388  			"shell": testProvisionerFuncFixed(pr),
  4389  		},
  4390  		State: state,
  4391  	})
  4392  
  4393  	if _, err := ctx.Plan(); err != nil {
  4394  		t.Fatalf("err: %s", err)
  4395  	}
  4396  
  4397  	state2, err := ctx.Apply()
  4398  	if err != nil {
  4399  		t.Fatalf("err: %s", err)
  4400  	}
  4401  
  4402  	actual = strings.TrimSpace(state2.String())
  4403  	if actual != expected {
  4404  		t.Fatalf("bad: \n%s", actual)
  4405  	}
  4406  
  4407  	// Verify apply was NOT invoked
  4408  	if pr.ApplyCalled {
  4409  		t.Fatalf("provisioner invoked")
  4410  	}
  4411  }
  4412  
  4413  func TestContext2Apply_outputDiffVars(t *testing.T) {
  4414  	m := testModule(t, "apply-good")
  4415  	p := testProvider("aws")
  4416  	s := &State{
  4417  		Modules: []*ModuleState{
  4418  			&ModuleState{
  4419  				Path: rootModulePath,
  4420  				Resources: map[string]*ResourceState{
  4421  					"aws_instance.baz": &ResourceState{
  4422  						Type: "aws_instance",
  4423  						Primary: &InstanceState{
  4424  							ID: "bar",
  4425  						},
  4426  					},
  4427  				},
  4428  			},
  4429  		},
  4430  	}
  4431  	ctx := testContext2(t, &ContextOpts{
  4432  		Module: m,
  4433  		Providers: map[string]ResourceProviderFactory{
  4434  			"aws": testProviderFuncFixed(p),
  4435  		},
  4436  		State: s,
  4437  	})
  4438  
  4439  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  4440  		for k, ad := range d.Attributes {
  4441  			if ad.NewComputed {
  4442  				return nil, fmt.Errorf("%s: computed", k)
  4443  			}
  4444  		}
  4445  
  4446  		result := s.MergeDiff(d)
  4447  		result.ID = "foo"
  4448  		return result, nil
  4449  	}
  4450  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  4451  		return &InstanceDiff{
  4452  			Attributes: map[string]*ResourceAttrDiff{
  4453  				"foo": &ResourceAttrDiff{
  4454  					NewComputed: true,
  4455  					Type:        DiffAttrOutput,
  4456  				},
  4457  				"bar": &ResourceAttrDiff{
  4458  					New: "baz",
  4459  				},
  4460  			},
  4461  		}, nil
  4462  	}
  4463  
  4464  	if _, err := ctx.Plan(); err != nil {
  4465  		t.Fatalf("err: %s", err)
  4466  	}
  4467  	if _, err := ctx.Apply(); err != nil {
  4468  		t.Fatalf("err: %s", err)
  4469  	}
  4470  }
  4471  
  4472  func TestContext2Apply_Provisioner_ConnInfo(t *testing.T) {
  4473  	m := testModule(t, "apply-provisioner-conninfo")
  4474  	p := testProvider("aws")
  4475  	pr := testProvisioner()
  4476  
  4477  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  4478  		if s.Ephemeral.ConnInfo == nil {
  4479  			t.Fatalf("ConnInfo not initialized")
  4480  		}
  4481  
  4482  		result, _ := testApplyFn(info, s, d)
  4483  		result.Ephemeral.ConnInfo = map[string]string{
  4484  			"type": "ssh",
  4485  			"host": "127.0.0.1",
  4486  			"port": "22",
  4487  		}
  4488  		return result, nil
  4489  	}
  4490  	p.DiffFn = testDiffFn
  4491  
  4492  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  4493  		conn := rs.Ephemeral.ConnInfo
  4494  		if conn["type"] != "telnet" {
  4495  			t.Fatalf("Bad: %#v", conn)
  4496  		}
  4497  		if conn["host"] != "127.0.0.1" {
  4498  			t.Fatalf("Bad: %#v", conn)
  4499  		}
  4500  		if conn["port"] != "2222" {
  4501  			t.Fatalf("Bad: %#v", conn)
  4502  		}
  4503  		if conn["user"] != "superuser" {
  4504  			t.Fatalf("Bad: %#v", conn)
  4505  		}
  4506  		if conn["pass"] != "test" {
  4507  			t.Fatalf("Bad: %#v", conn)
  4508  		}
  4509  
  4510  		return nil
  4511  	}
  4512  
  4513  	ctx := testContext2(t, &ContextOpts{
  4514  		Module: m,
  4515  		Providers: map[string]ResourceProviderFactory{
  4516  			"aws": testProviderFuncFixed(p),
  4517  		},
  4518  		Provisioners: map[string]ResourceProvisionerFactory{
  4519  			"shell": testProvisionerFuncFixed(pr),
  4520  		},
  4521  		Variables: map[string]interface{}{
  4522  			"value": "1",
  4523  			"pass":  "test",
  4524  		},
  4525  	})
  4526  
  4527  	if _, err := ctx.Plan(); err != nil {
  4528  		t.Fatalf("err: %s", err)
  4529  	}
  4530  
  4531  	state, err := ctx.Apply()
  4532  	if err != nil {
  4533  		t.Fatalf("err: %s", err)
  4534  	}
  4535  
  4536  	actual := strings.TrimSpace(state.String())
  4537  	expected := strings.TrimSpace(testTerraformApplyProvisionerStr)
  4538  	if actual != expected {
  4539  		t.Fatalf("bad: \n%s", actual)
  4540  	}
  4541  
  4542  	// Verify apply was invoked
  4543  	if !pr.ApplyCalled {
  4544  		t.Fatalf("provisioner not invoked")
  4545  	}
  4546  }
  4547  
  4548  func TestContext2Apply_destroyX(t *testing.T) {
  4549  	m := testModule(t, "apply-destroy")
  4550  	h := new(HookRecordApplyOrder)
  4551  	p := testProvider("aws")
  4552  	p.ApplyFn = testApplyFn
  4553  	p.DiffFn = testDiffFn
  4554  	ctx := testContext2(t, &ContextOpts{
  4555  		Module: m,
  4556  		Hooks:  []Hook{h},
  4557  		Providers: map[string]ResourceProviderFactory{
  4558  			"aws": testProviderFuncFixed(p),
  4559  		},
  4560  	})
  4561  
  4562  	// First plan and apply a create operation
  4563  	if _, err := ctx.Plan(); err != nil {
  4564  		t.Fatalf("err: %s", err)
  4565  	}
  4566  
  4567  	state, err := ctx.Apply()
  4568  	if err != nil {
  4569  		t.Fatalf("err: %s", err)
  4570  	}
  4571  
  4572  	// Next, plan and apply a destroy operation
  4573  	h.Active = true
  4574  	ctx = testContext2(t, &ContextOpts{
  4575  		Destroy: true,
  4576  		State:   state,
  4577  		Module:  m,
  4578  		Hooks:   []Hook{h},
  4579  		Providers: map[string]ResourceProviderFactory{
  4580  			"aws": testProviderFuncFixed(p),
  4581  		},
  4582  	})
  4583  
  4584  	if _, err := ctx.Plan(); err != nil {
  4585  		t.Fatalf("err: %s", err)
  4586  	}
  4587  
  4588  	state, err = ctx.Apply()
  4589  	if err != nil {
  4590  		t.Fatalf("err: %s", err)
  4591  	}
  4592  
  4593  	// Test that things were destroyed
  4594  	actual := strings.TrimSpace(state.String())
  4595  	expected := strings.TrimSpace(testTerraformApplyDestroyStr)
  4596  	if actual != expected {
  4597  		t.Fatalf("bad: \n%s", actual)
  4598  	}
  4599  
  4600  	// Test that things were destroyed _in the right order_
  4601  	expected2 := []string{"aws_instance.bar", "aws_instance.foo"}
  4602  	actual2 := h.IDs
  4603  	if !reflect.DeepEqual(actual2, expected2) {
  4604  		t.Fatalf("expected: %#v\n\ngot:%#v", expected2, actual2)
  4605  	}
  4606  }
  4607  
  4608  func TestContext2Apply_destroyOrder(t *testing.T) {
  4609  	m := testModule(t, "apply-destroy")
  4610  	h := new(HookRecordApplyOrder)
  4611  	p := testProvider("aws")
  4612  	p.ApplyFn = testApplyFn
  4613  	p.DiffFn = testDiffFn
  4614  	ctx := testContext2(t, &ContextOpts{
  4615  		Module: m,
  4616  		Hooks:  []Hook{h},
  4617  		Providers: map[string]ResourceProviderFactory{
  4618  			"aws": testProviderFuncFixed(p),
  4619  		},
  4620  	})
  4621  
  4622  	// First plan and apply a create operation
  4623  	if _, err := ctx.Plan(); err != nil {
  4624  		t.Fatalf("err: %s", err)
  4625  	}
  4626  
  4627  	state, err := ctx.Apply()
  4628  	if err != nil {
  4629  		t.Fatalf("err: %s", err)
  4630  	}
  4631  
  4632  	t.Logf("State 1: %s", state)
  4633  
  4634  	// Next, plan and apply config-less to force a destroy with "apply"
  4635  	h.Active = true
  4636  	ctx = testContext2(t, &ContextOpts{
  4637  		State:  state,
  4638  		Module: module.NewEmptyTree(),
  4639  		Hooks:  []Hook{h},
  4640  		Providers: map[string]ResourceProviderFactory{
  4641  			"aws": testProviderFuncFixed(p),
  4642  		},
  4643  	})
  4644  
  4645  	if _, err := ctx.Plan(); err != nil {
  4646  		t.Fatalf("err: %s", err)
  4647  	}
  4648  
  4649  	state, err = ctx.Apply()
  4650  	if err != nil {
  4651  		t.Fatalf("err: %s", err)
  4652  	}
  4653  
  4654  	// Test that things were destroyed
  4655  	actual := strings.TrimSpace(state.String())
  4656  	expected := strings.TrimSpace(testTerraformApplyDestroyStr)
  4657  	if actual != expected {
  4658  		t.Fatalf("bad: \n%s", actual)
  4659  	}
  4660  
  4661  	// Test that things were destroyed _in the right order_
  4662  	expected2 := []string{"aws_instance.bar", "aws_instance.foo"}
  4663  	actual2 := h.IDs
  4664  	if !reflect.DeepEqual(actual2, expected2) {
  4665  		t.Fatalf("expected: %#v\n\ngot:%#v", expected2, actual2)
  4666  	}
  4667  }
  4668  
  4669  // https://github.com/hashicorp/terraform/issues/2767
  4670  func TestContext2Apply_destroyModulePrefix(t *testing.T) {
  4671  	m := testModule(t, "apply-destroy-module-resource-prefix")
  4672  	h := new(MockHook)
  4673  	p := testProvider("aws")
  4674  	p.ApplyFn = testApplyFn
  4675  	p.DiffFn = testDiffFn
  4676  	ctx := testContext2(t, &ContextOpts{
  4677  		Module: m,
  4678  		Hooks:  []Hook{h},
  4679  		Providers: map[string]ResourceProviderFactory{
  4680  			"aws": testProviderFuncFixed(p),
  4681  		},
  4682  	})
  4683  
  4684  	// First plan and apply a create operation
  4685  	if _, err := ctx.Plan(); err != nil {
  4686  		t.Fatalf("err: %s", err)
  4687  	}
  4688  
  4689  	state, err := ctx.Apply()
  4690  	if err != nil {
  4691  		t.Fatalf("err: %s", err)
  4692  	}
  4693  
  4694  	// Verify that we got the apply info correct
  4695  	if v := h.PreApplyInfo.HumanId(); v != "module.child.aws_instance.foo" {
  4696  		t.Fatalf("bad: %s", v)
  4697  	}
  4698  
  4699  	// Next, plan and apply a destroy operation and reset the hook
  4700  	h = new(MockHook)
  4701  	ctx = testContext2(t, &ContextOpts{
  4702  		Destroy: true,
  4703  		State:   state,
  4704  		Module:  m,
  4705  		Hooks:   []Hook{h},
  4706  		Providers: map[string]ResourceProviderFactory{
  4707  			"aws": testProviderFuncFixed(p),
  4708  		},
  4709  	})
  4710  
  4711  	if _, err := ctx.Plan(); err != nil {
  4712  		t.Fatalf("err: %s", err)
  4713  	}
  4714  
  4715  	state, err = ctx.Apply()
  4716  	if err != nil {
  4717  		t.Fatalf("err: %s", err)
  4718  	}
  4719  
  4720  	// Test that things were destroyed
  4721  	if v := h.PreApplyInfo.HumanId(); v != "module.child.aws_instance.foo" {
  4722  		t.Fatalf("bad: %s", v)
  4723  	}
  4724  }
  4725  
  4726  func TestContext2Apply_destroyNestedModule(t *testing.T) {
  4727  	m := testModule(t, "apply-destroy-nested-module")
  4728  	p := testProvider("aws")
  4729  	p.ApplyFn = testApplyFn
  4730  	p.DiffFn = testDiffFn
  4731  
  4732  	s := &State{
  4733  		Modules: []*ModuleState{
  4734  			&ModuleState{
  4735  				Path: []string{"root", "child", "subchild"},
  4736  				Resources: map[string]*ResourceState{
  4737  					"aws_instance.bar": &ResourceState{
  4738  						Type: "aws_instance",
  4739  						Primary: &InstanceState{
  4740  							ID: "bar",
  4741  						},
  4742  					},
  4743  				},
  4744  			},
  4745  		},
  4746  	}
  4747  
  4748  	ctx := testContext2(t, &ContextOpts{
  4749  		Module: m,
  4750  		Providers: map[string]ResourceProviderFactory{
  4751  			"aws": testProviderFuncFixed(p),
  4752  		},
  4753  		State: s,
  4754  	})
  4755  
  4756  	// First plan and apply a create operation
  4757  	if _, err := ctx.Plan(); err != nil {
  4758  		t.Fatalf("err: %s", err)
  4759  	}
  4760  
  4761  	state, err := ctx.Apply()
  4762  	if err != nil {
  4763  		t.Fatalf("err: %s", err)
  4764  	}
  4765  
  4766  	// Test that things were destroyed
  4767  	actual := strings.TrimSpace(state.String())
  4768  	expected := strings.TrimSpace(testTerraformApplyDestroyNestedModuleStr)
  4769  	if actual != expected {
  4770  		t.Fatalf("bad: \n%s", actual)
  4771  	}
  4772  }
  4773  
  4774  func TestContext2Apply_destroyDeeplyNestedModule(t *testing.T) {
  4775  	m := testModule(t, "apply-destroy-deeply-nested-module")
  4776  	p := testProvider("aws")
  4777  	p.ApplyFn = testApplyFn
  4778  	p.DiffFn = testDiffFn
  4779  
  4780  	s := &State{
  4781  		Modules: []*ModuleState{
  4782  			&ModuleState{
  4783  				Path: []string{"root", "child", "subchild", "subsubchild"},
  4784  				Resources: map[string]*ResourceState{
  4785  					"aws_instance.bar": &ResourceState{
  4786  						Type: "aws_instance",
  4787  						Primary: &InstanceState{
  4788  							ID: "bar",
  4789  						},
  4790  					},
  4791  				},
  4792  			},
  4793  		},
  4794  	}
  4795  
  4796  	ctx := testContext2(t, &ContextOpts{
  4797  		Module: m,
  4798  		Providers: map[string]ResourceProviderFactory{
  4799  			"aws": testProviderFuncFixed(p),
  4800  		},
  4801  		State: s,
  4802  	})
  4803  
  4804  	// First plan and apply a create operation
  4805  	if _, err := ctx.Plan(); err != nil {
  4806  		t.Fatalf("err: %s", err)
  4807  	}
  4808  
  4809  	state, err := ctx.Apply()
  4810  	if err != nil {
  4811  		t.Fatalf("err: %s", err)
  4812  	}
  4813  
  4814  	// Test that things were destroyed
  4815  	actual := strings.TrimSpace(state.String())
  4816  	expected := strings.TrimSpace(`
  4817  module.child.subchild.subsubchild:
  4818    <no state>
  4819  	`)
  4820  	if actual != expected {
  4821  		t.Fatalf("bad: \n%s", actual)
  4822  	}
  4823  }
  4824  
  4825  // https://github.com/hashicorp/terraform/issues/5440
  4826  func TestContext2Apply_destroyModuleWithAttrsReferencingResource(t *testing.T) {
  4827  	m := testModule(t, "apply-destroy-module-with-attrs")
  4828  	p := testProvider("aws")
  4829  	p.ApplyFn = testApplyFn
  4830  	p.DiffFn = testDiffFn
  4831  
  4832  	var state *State
  4833  	var err error
  4834  	{
  4835  		ctx := testContext2(t, &ContextOpts{
  4836  			Module: m,
  4837  			Providers: map[string]ResourceProviderFactory{
  4838  				"aws": testProviderFuncFixed(p),
  4839  			},
  4840  		})
  4841  
  4842  		// First plan and apply a create operation
  4843  		if p, err := ctx.Plan(); err != nil {
  4844  			t.Fatalf("plan err: %s", err)
  4845  		} else {
  4846  			t.Logf("Step 1 plan: %s", p)
  4847  		}
  4848  
  4849  		state, err = ctx.Apply()
  4850  		if err != nil {
  4851  			t.Fatalf("apply err: %s", err)
  4852  		}
  4853  
  4854  		t.Logf("Step 1 state: %s", state)
  4855  	}
  4856  
  4857  	h := new(HookRecordApplyOrder)
  4858  	h.Active = true
  4859  
  4860  	{
  4861  		ctx := testContext2(t, &ContextOpts{
  4862  			Destroy: true,
  4863  			Module:  m,
  4864  			State:   state,
  4865  			Hooks:   []Hook{h},
  4866  			Providers: map[string]ResourceProviderFactory{
  4867  				"aws": testProviderFuncFixed(p),
  4868  			},
  4869  			Variables: map[string]interface{}{
  4870  				"key_name": "foobarkey",
  4871  			},
  4872  		})
  4873  
  4874  		// First plan and apply a create operation
  4875  		plan, err := ctx.Plan()
  4876  		if err != nil {
  4877  			t.Fatalf("destroy plan err: %s", err)
  4878  		}
  4879  
  4880  		t.Logf("Step 2 plan: %s", plan)
  4881  
  4882  		var buf bytes.Buffer
  4883  		if err := WritePlan(plan, &buf); err != nil {
  4884  			t.Fatalf("plan write err: %s", err)
  4885  		}
  4886  
  4887  		planFromFile, err := ReadPlan(&buf)
  4888  		if err != nil {
  4889  			t.Fatalf("plan read err: %s", err)
  4890  		}
  4891  
  4892  		ctx, err = planFromFile.Context(&ContextOpts{
  4893  			Providers: map[string]ResourceProviderFactory{
  4894  				"aws": testProviderFuncFixed(p),
  4895  			},
  4896  		})
  4897  		if err != nil {
  4898  			t.Fatalf("err: %s", err)
  4899  		}
  4900  
  4901  		state, err = ctx.Apply()
  4902  		if err != nil {
  4903  			t.Fatalf("destroy apply err: %s", err)
  4904  		}
  4905  
  4906  		t.Logf("Step 2 state: %s", state)
  4907  	}
  4908  
  4909  	//Test that things were destroyed
  4910  	actual := strings.TrimSpace(state.String())
  4911  	expected := strings.TrimSpace(`
  4912  <no state>
  4913  module.child:
  4914    <no state>
  4915  		`)
  4916  	if actual != expected {
  4917  		t.Fatalf("expected:\n\n%s\n\nactual:\n\n%s", expected, actual)
  4918  	}
  4919  }
  4920  
  4921  func TestContext2Apply_destroyWithModuleVariableAndCount(t *testing.T) {
  4922  	m := testModule(t, "apply-destroy-mod-var-and-count")
  4923  	p := testProvider("aws")
  4924  	p.ApplyFn = testApplyFn
  4925  	p.DiffFn = testDiffFn
  4926  
  4927  	var state *State
  4928  	var err error
  4929  	{
  4930  		ctx := testContext2(t, &ContextOpts{
  4931  			Module: m,
  4932  			Providers: map[string]ResourceProviderFactory{
  4933  				"aws": testProviderFuncFixed(p),
  4934  			},
  4935  		})
  4936  
  4937  		// First plan and apply a create operation
  4938  		if _, err := ctx.Plan(); err != nil {
  4939  			t.Fatalf("plan err: %s", err)
  4940  		}
  4941  
  4942  		state, err = ctx.Apply()
  4943  		if err != nil {
  4944  			t.Fatalf("apply err: %s", err)
  4945  		}
  4946  	}
  4947  
  4948  	h := new(HookRecordApplyOrder)
  4949  	h.Active = true
  4950  
  4951  	{
  4952  		ctx := testContext2(t, &ContextOpts{
  4953  			Destroy: true,
  4954  			Module:  m,
  4955  			State:   state,
  4956  			Hooks:   []Hook{h},
  4957  			Providers: map[string]ResourceProviderFactory{
  4958  				"aws": testProviderFuncFixed(p),
  4959  			},
  4960  		})
  4961  
  4962  		// First plan and apply a create operation
  4963  		plan, err := ctx.Plan()
  4964  		if err != nil {
  4965  			t.Fatalf("destroy plan err: %s", err)
  4966  		}
  4967  
  4968  		var buf bytes.Buffer
  4969  		if err := WritePlan(plan, &buf); err != nil {
  4970  			t.Fatalf("plan write err: %s", err)
  4971  		}
  4972  
  4973  		planFromFile, err := ReadPlan(&buf)
  4974  		if err != nil {
  4975  			t.Fatalf("plan read err: %s", err)
  4976  		}
  4977  
  4978  		ctx, err = planFromFile.Context(&ContextOpts{
  4979  			Providers: map[string]ResourceProviderFactory{
  4980  				"aws": testProviderFuncFixed(p),
  4981  			},
  4982  		})
  4983  		if err != nil {
  4984  			t.Fatalf("err: %s", err)
  4985  		}
  4986  
  4987  		state, err = ctx.Apply()
  4988  		if err != nil {
  4989  			t.Fatalf("destroy apply err: %s", err)
  4990  		}
  4991  	}
  4992  
  4993  	//Test that things were destroyed
  4994  	actual := strings.TrimSpace(state.String())
  4995  	expected := strings.TrimSpace(`
  4996  <no state>
  4997  module.child:
  4998    <no state>
  4999  		`)
  5000  	if actual != expected {
  5001  		t.Fatalf("expected: \n%s\n\nbad: \n%s", expected, actual)
  5002  	}
  5003  }
  5004  
  5005  func TestContext2Apply_destroyTargetWithModuleVariableAndCount(t *testing.T) {
  5006  	m := testModule(t, "apply-destroy-mod-var-and-count")
  5007  	p := testProvider("aws")
  5008  	p.ApplyFn = testApplyFn
  5009  	p.DiffFn = testDiffFn
  5010  
  5011  	var state *State
  5012  	var err error
  5013  	{
  5014  		ctx := testContext2(t, &ContextOpts{
  5015  			Module: m,
  5016  			Providers: map[string]ResourceProviderFactory{
  5017  				"aws": testProviderFuncFixed(p),
  5018  			},
  5019  		})
  5020  
  5021  		// First plan and apply a create operation
  5022  		if _, err := ctx.Plan(); err != nil {
  5023  			t.Fatalf("plan err: %s", err)
  5024  		}
  5025  
  5026  		state, err = ctx.Apply()
  5027  		if err != nil {
  5028  			t.Fatalf("apply err: %s", err)
  5029  		}
  5030  	}
  5031  
  5032  	{
  5033  		ctx := testContext2(t, &ContextOpts{
  5034  			Destroy: true,
  5035  			Module:  m,
  5036  			State:   state,
  5037  			Providers: map[string]ResourceProviderFactory{
  5038  				"aws": testProviderFuncFixed(p),
  5039  			},
  5040  			Targets: []string{"module.child"},
  5041  		})
  5042  
  5043  		_, err := ctx.Plan()
  5044  		if err != nil {
  5045  			t.Fatalf("plan err: %s", err)
  5046  		}
  5047  
  5048  		// Destroy, targeting the module explicitly
  5049  		state, err = ctx.Apply()
  5050  		if err != nil {
  5051  			t.Fatalf("destroy apply err: %s", err)
  5052  		}
  5053  	}
  5054  
  5055  	//Test that things were destroyed
  5056  	actual := strings.TrimSpace(state.String())
  5057  	expected := strings.TrimSpace(`
  5058  <no state>
  5059  module.child:
  5060    <no state>
  5061  		`)
  5062  	if actual != expected {
  5063  		t.Fatalf("expected: \n%s\n\nbad: \n%s", expected, actual)
  5064  	}
  5065  }
  5066  
  5067  func TestContext2Apply_destroyWithModuleVariableAndCountNested(t *testing.T) {
  5068  	m := testModule(t, "apply-destroy-mod-var-and-count-nested")
  5069  	p := testProvider("aws")
  5070  	p.ApplyFn = testApplyFn
  5071  	p.DiffFn = testDiffFn
  5072  
  5073  	var state *State
  5074  	var err error
  5075  	{
  5076  		ctx := testContext2(t, &ContextOpts{
  5077  			Module: m,
  5078  			Providers: map[string]ResourceProviderFactory{
  5079  				"aws": testProviderFuncFixed(p),
  5080  			},
  5081  		})
  5082  
  5083  		// First plan and apply a create operation
  5084  		if _, err := ctx.Plan(); err != nil {
  5085  			t.Fatalf("plan err: %s", err)
  5086  		}
  5087  
  5088  		state, err = ctx.Apply()
  5089  		if err != nil {
  5090  			t.Fatalf("apply err: %s", err)
  5091  		}
  5092  	}
  5093  
  5094  	h := new(HookRecordApplyOrder)
  5095  	h.Active = true
  5096  
  5097  	{
  5098  		ctx := testContext2(t, &ContextOpts{
  5099  			Destroy: true,
  5100  			Module:  m,
  5101  			State:   state,
  5102  			Hooks:   []Hook{h},
  5103  			Providers: map[string]ResourceProviderFactory{
  5104  				"aws": testProviderFuncFixed(p),
  5105  			},
  5106  		})
  5107  
  5108  		// First plan and apply a create operation
  5109  		plan, err := ctx.Plan()
  5110  		if err != nil {
  5111  			t.Fatalf("destroy plan err: %s", err)
  5112  		}
  5113  
  5114  		var buf bytes.Buffer
  5115  		if err := WritePlan(plan, &buf); err != nil {
  5116  			t.Fatalf("plan write err: %s", err)
  5117  		}
  5118  
  5119  		planFromFile, err := ReadPlan(&buf)
  5120  		if err != nil {
  5121  			t.Fatalf("plan read err: %s", err)
  5122  		}
  5123  
  5124  		ctx, err = planFromFile.Context(&ContextOpts{
  5125  			Providers: map[string]ResourceProviderFactory{
  5126  				"aws": testProviderFuncFixed(p),
  5127  			},
  5128  		})
  5129  		if err != nil {
  5130  			t.Fatalf("err: %s", err)
  5131  		}
  5132  
  5133  		state, err = ctx.Apply()
  5134  		if err != nil {
  5135  			t.Fatalf("destroy apply err: %s", err)
  5136  		}
  5137  	}
  5138  
  5139  	//Test that things were destroyed
  5140  	actual := strings.TrimSpace(state.String())
  5141  	expected := strings.TrimSpace(`
  5142  <no state>
  5143  module.child:
  5144    <no state>
  5145  module.child.child2:
  5146    <no state>
  5147  		`)
  5148  	if actual != expected {
  5149  		t.Fatalf("expected: \n%s\n\nbad: \n%s", expected, actual)
  5150  	}
  5151  }
  5152  
  5153  func TestContext2Apply_destroyOutputs(t *testing.T) {
  5154  	m := testModule(t, "apply-destroy-outputs")
  5155  	h := new(HookRecordApplyOrder)
  5156  	p := testProvider("aws")
  5157  	p.ApplyFn = testApplyFn
  5158  	p.DiffFn = testDiffFn
  5159  	ctx := testContext2(t, &ContextOpts{
  5160  		Module: m,
  5161  		Hooks:  []Hook{h},
  5162  		Providers: map[string]ResourceProviderFactory{
  5163  			"aws": testProviderFuncFixed(p),
  5164  		},
  5165  	})
  5166  
  5167  	// First plan and apply a create operation
  5168  	if _, err := ctx.Plan(); err != nil {
  5169  		t.Fatalf("err: %s", err)
  5170  	}
  5171  
  5172  	state, err := ctx.Apply()
  5173  
  5174  	if err != nil {
  5175  		t.Fatalf("err: %s", err)
  5176  	}
  5177  
  5178  	// Next, plan and apply a destroy operation
  5179  	h.Active = true
  5180  	ctx = testContext2(t, &ContextOpts{
  5181  		Destroy: true,
  5182  		State:   state,
  5183  		Module:  m,
  5184  		Hooks:   []Hook{h},
  5185  		Providers: map[string]ResourceProviderFactory{
  5186  			"aws": testProviderFuncFixed(p),
  5187  		},
  5188  	})
  5189  
  5190  	if _, err := ctx.Plan(); err != nil {
  5191  		t.Fatalf("err: %s", err)
  5192  	}
  5193  
  5194  	state, err = ctx.Apply()
  5195  	if err != nil {
  5196  		t.Fatalf("err: %s", err)
  5197  	}
  5198  
  5199  	mod := state.RootModule()
  5200  	if len(mod.Resources) > 0 {
  5201  		t.Fatalf("bad: %#v", mod)
  5202  	}
  5203  }
  5204  
  5205  func TestContext2Apply_destroyOrphan(t *testing.T) {
  5206  	m := testModule(t, "apply-error")
  5207  	p := testProvider("aws")
  5208  	s := &State{
  5209  		Modules: []*ModuleState{
  5210  			&ModuleState{
  5211  				Path: rootModulePath,
  5212  				Resources: map[string]*ResourceState{
  5213  					"aws_instance.baz": &ResourceState{
  5214  						Type: "aws_instance",
  5215  						Primary: &InstanceState{
  5216  							ID: "bar",
  5217  						},
  5218  					},
  5219  				},
  5220  			},
  5221  		},
  5222  	}
  5223  	ctx := testContext2(t, &ContextOpts{
  5224  		Module: m,
  5225  		Providers: map[string]ResourceProviderFactory{
  5226  			"aws": testProviderFuncFixed(p),
  5227  		},
  5228  		State: s,
  5229  	})
  5230  
  5231  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  5232  		if d.Destroy {
  5233  			return nil, nil
  5234  		}
  5235  
  5236  		result := s.MergeDiff(d)
  5237  		result.ID = "foo"
  5238  		return result, nil
  5239  	}
  5240  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  5241  		return &InstanceDiff{
  5242  			Attributes: map[string]*ResourceAttrDiff{
  5243  				"num": &ResourceAttrDiff{
  5244  					New: "bar",
  5245  				},
  5246  			},
  5247  		}, nil
  5248  	}
  5249  
  5250  	if _, err := ctx.Plan(); err != nil {
  5251  		t.Fatalf("err: %s", err)
  5252  	}
  5253  
  5254  	state, err := ctx.Apply()
  5255  	if err != nil {
  5256  		t.Fatalf("err: %s", err)
  5257  	}
  5258  
  5259  	mod := state.RootModule()
  5260  	if _, ok := mod.Resources["aws_instance.baz"]; ok {
  5261  		t.Fatalf("bad: %#v", mod.Resources)
  5262  	}
  5263  }
  5264  
  5265  func TestContext2Apply_destroyTaintedProvisioner(t *testing.T) {
  5266  	m := testModule(t, "apply-destroy-provisioner")
  5267  	p := testProvider("aws")
  5268  	pr := testProvisioner()
  5269  	p.ApplyFn = testApplyFn
  5270  	p.DiffFn = testDiffFn
  5271  
  5272  	called := false
  5273  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  5274  		called = true
  5275  		return nil
  5276  	}
  5277  
  5278  	s := &State{
  5279  		Modules: []*ModuleState{
  5280  			&ModuleState{
  5281  				Path: rootModulePath,
  5282  				Resources: map[string]*ResourceState{
  5283  					"aws_instance.foo": &ResourceState{
  5284  						Type: "aws_instance",
  5285  						Primary: &InstanceState{
  5286  							ID: "bar",
  5287  							Attributes: map[string]string{
  5288  								"id": "bar",
  5289  							},
  5290  							Tainted: true,
  5291  						},
  5292  					},
  5293  				},
  5294  			},
  5295  		},
  5296  	}
  5297  
  5298  	ctx := testContext2(t, &ContextOpts{
  5299  		Module: m,
  5300  		Providers: map[string]ResourceProviderFactory{
  5301  			"aws": testProviderFuncFixed(p),
  5302  		},
  5303  		Provisioners: map[string]ResourceProvisionerFactory{
  5304  			"shell": testProvisionerFuncFixed(pr),
  5305  		},
  5306  		State:   s,
  5307  		Destroy: true,
  5308  	})
  5309  
  5310  	if _, err := ctx.Plan(); err != nil {
  5311  		t.Fatalf("err: %s", err)
  5312  	}
  5313  
  5314  	state, err := ctx.Apply()
  5315  	if err != nil {
  5316  		t.Fatalf("err: %s", err)
  5317  	}
  5318  
  5319  	if called {
  5320  		t.Fatal("provisioner should not be called")
  5321  	}
  5322  
  5323  	actual := strings.TrimSpace(state.String())
  5324  	expected := strings.TrimSpace("<no state>")
  5325  	if actual != expected {
  5326  		t.Fatalf("bad: \n%s", actual)
  5327  	}
  5328  }
  5329  
  5330  func TestContext2Apply_error(t *testing.T) {
  5331  	errored := false
  5332  
  5333  	m := testModule(t, "apply-error")
  5334  	p := testProvider("aws")
  5335  	ctx := testContext2(t, &ContextOpts{
  5336  		Module: m,
  5337  		Providers: map[string]ResourceProviderFactory{
  5338  			"aws": testProviderFuncFixed(p),
  5339  		},
  5340  	})
  5341  
  5342  	p.ApplyFn = func(*InstanceInfo, *InstanceState, *InstanceDiff) (*InstanceState, error) {
  5343  		if errored {
  5344  			state := &InstanceState{
  5345  				ID: "bar",
  5346  			}
  5347  			return state, fmt.Errorf("error")
  5348  		}
  5349  		errored = true
  5350  
  5351  		return &InstanceState{
  5352  			ID: "foo",
  5353  			Attributes: map[string]string{
  5354  				"num": "2",
  5355  			},
  5356  		}, nil
  5357  	}
  5358  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  5359  		return &InstanceDiff{
  5360  			Attributes: map[string]*ResourceAttrDiff{
  5361  				"num": &ResourceAttrDiff{
  5362  					New: "bar",
  5363  				},
  5364  			},
  5365  		}, nil
  5366  	}
  5367  
  5368  	if _, err := ctx.Plan(); err != nil {
  5369  		t.Fatalf("err: %s", err)
  5370  	}
  5371  
  5372  	state, err := ctx.Apply()
  5373  	if err == nil {
  5374  		t.Fatal("should have error")
  5375  	}
  5376  
  5377  	actual := strings.TrimSpace(state.String())
  5378  	expected := strings.TrimSpace(testTerraformApplyErrorStr)
  5379  	if actual != expected {
  5380  		t.Fatalf("bad: \n%s", actual)
  5381  	}
  5382  }
  5383  
  5384  func TestContext2Apply_errorPartial(t *testing.T) {
  5385  	errored := false
  5386  
  5387  	m := testModule(t, "apply-error")
  5388  	p := testProvider("aws")
  5389  	s := &State{
  5390  		Modules: []*ModuleState{
  5391  			&ModuleState{
  5392  				Path: rootModulePath,
  5393  				Resources: map[string]*ResourceState{
  5394  					"aws_instance.bar": &ResourceState{
  5395  						Type: "aws_instance",
  5396  						Primary: &InstanceState{
  5397  							ID: "bar",
  5398  						},
  5399  					},
  5400  				},
  5401  			},
  5402  		},
  5403  	}
  5404  	ctx := testContext2(t, &ContextOpts{
  5405  		Module: m,
  5406  		Providers: map[string]ResourceProviderFactory{
  5407  			"aws": testProviderFuncFixed(p),
  5408  		},
  5409  		State: s,
  5410  	})
  5411  
  5412  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  5413  		if errored {
  5414  			return s, fmt.Errorf("error")
  5415  		}
  5416  		errored = true
  5417  
  5418  		return &InstanceState{
  5419  			ID: "foo",
  5420  			Attributes: map[string]string{
  5421  				"num": "2",
  5422  			},
  5423  		}, nil
  5424  	}
  5425  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  5426  		return &InstanceDiff{
  5427  			Attributes: map[string]*ResourceAttrDiff{
  5428  				"num": &ResourceAttrDiff{
  5429  					New: "bar",
  5430  				},
  5431  			},
  5432  		}, nil
  5433  	}
  5434  
  5435  	if _, err := ctx.Plan(); err != nil {
  5436  		t.Fatalf("err: %s", err)
  5437  	}
  5438  
  5439  	state, err := ctx.Apply()
  5440  	if err == nil {
  5441  		t.Fatal("should have error")
  5442  	}
  5443  
  5444  	mod := state.RootModule()
  5445  	if len(mod.Resources) != 2 {
  5446  		t.Fatalf("bad: %#v", mod.Resources)
  5447  	}
  5448  
  5449  	actual := strings.TrimSpace(state.String())
  5450  	expected := strings.TrimSpace(testTerraformApplyErrorPartialStr)
  5451  	if actual != expected {
  5452  		t.Fatalf("bad: \n%s", actual)
  5453  	}
  5454  }
  5455  
  5456  func TestContext2Apply_hook(t *testing.T) {
  5457  	m := testModule(t, "apply-good")
  5458  	h := new(MockHook)
  5459  	p := testProvider("aws")
  5460  	p.ApplyFn = testApplyFn
  5461  	p.DiffFn = testDiffFn
  5462  	ctx := testContext2(t, &ContextOpts{
  5463  		Module: m,
  5464  		Hooks:  []Hook{h},
  5465  		Providers: map[string]ResourceProviderFactory{
  5466  			"aws": testProviderFuncFixed(p),
  5467  		},
  5468  	})
  5469  
  5470  	if _, err := ctx.Plan(); err != nil {
  5471  		t.Fatalf("err: %s", err)
  5472  	}
  5473  
  5474  	if _, err := ctx.Apply(); err != nil {
  5475  		t.Fatalf("err: %s", err)
  5476  	}
  5477  
  5478  	if !h.PreApplyCalled {
  5479  		t.Fatal("should be called")
  5480  	}
  5481  	if !h.PostApplyCalled {
  5482  		t.Fatal("should be called")
  5483  	}
  5484  	if !h.PostStateUpdateCalled {
  5485  		t.Fatalf("should call post state update")
  5486  	}
  5487  }
  5488  
  5489  func TestContext2Apply_hookOrphan(t *testing.T) {
  5490  	m := testModule(t, "apply-blank")
  5491  	h := new(MockHook)
  5492  	p := testProvider("aws")
  5493  	p.ApplyFn = testApplyFn
  5494  	p.DiffFn = testDiffFn
  5495  
  5496  	state := &State{
  5497  		Modules: []*ModuleState{
  5498  			&ModuleState{
  5499  				Path: rootModulePath,
  5500  				Resources: map[string]*ResourceState{
  5501  					"aws_instance.bar": &ResourceState{
  5502  						Type: "aws_instance",
  5503  						Primary: &InstanceState{
  5504  							ID: "bar",
  5505  						},
  5506  					},
  5507  				},
  5508  			},
  5509  		},
  5510  	}
  5511  
  5512  	ctx := testContext2(t, &ContextOpts{
  5513  		Module: m,
  5514  		State:  state,
  5515  		Hooks:  []Hook{h},
  5516  		Providers: map[string]ResourceProviderFactory{
  5517  			"aws": testProviderFuncFixed(p),
  5518  		},
  5519  	})
  5520  
  5521  	if _, err := ctx.Plan(); err != nil {
  5522  		t.Fatalf("err: %s", err)
  5523  	}
  5524  
  5525  	if _, err := ctx.Apply(); err != nil {
  5526  		t.Fatalf("err: %s", err)
  5527  	}
  5528  
  5529  	if !h.PreApplyCalled {
  5530  		t.Fatal("should be called")
  5531  	}
  5532  	if !h.PostApplyCalled {
  5533  		t.Fatal("should be called")
  5534  	}
  5535  	if !h.PostStateUpdateCalled {
  5536  		t.Fatalf("should call post state update")
  5537  	}
  5538  }
  5539  
  5540  func TestContext2Apply_idAttr(t *testing.T) {
  5541  	m := testModule(t, "apply-idattr")
  5542  	p := testProvider("aws")
  5543  	ctx := testContext2(t, &ContextOpts{
  5544  		Module: m,
  5545  		Providers: map[string]ResourceProviderFactory{
  5546  			"aws": testProviderFuncFixed(p),
  5547  		},
  5548  	})
  5549  
  5550  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  5551  		result := s.MergeDiff(d)
  5552  		result.ID = "foo"
  5553  		result.Attributes = map[string]string{
  5554  			"id": "bar",
  5555  		}
  5556  
  5557  		return result, nil
  5558  	}
  5559  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  5560  		return &InstanceDiff{
  5561  			Attributes: map[string]*ResourceAttrDiff{
  5562  				"num": &ResourceAttrDiff{
  5563  					New: "bar",
  5564  				},
  5565  			},
  5566  		}, nil
  5567  	}
  5568  
  5569  	if _, err := ctx.Plan(); err != nil {
  5570  		t.Fatalf("err: %s", err)
  5571  	}
  5572  
  5573  	state, err := ctx.Apply()
  5574  	if err != nil {
  5575  		t.Fatalf("err: %s", err)
  5576  	}
  5577  
  5578  	mod := state.RootModule()
  5579  	rs, ok := mod.Resources["aws_instance.foo"]
  5580  	if !ok {
  5581  		t.Fatal("not in state")
  5582  	}
  5583  	if rs.Primary.ID != "foo" {
  5584  		t.Fatalf("bad: %#v", rs.Primary.ID)
  5585  	}
  5586  	if rs.Primary.Attributes["id"] != "foo" {
  5587  		t.Fatalf("bad: %#v", rs.Primary.Attributes)
  5588  	}
  5589  }
  5590  
  5591  func TestContext2Apply_outputBasic(t *testing.T) {
  5592  	m := testModule(t, "apply-output")
  5593  	p := testProvider("aws")
  5594  	p.ApplyFn = testApplyFn
  5595  	p.DiffFn = testDiffFn
  5596  	ctx := testContext2(t, &ContextOpts{
  5597  		Module: m,
  5598  		Providers: map[string]ResourceProviderFactory{
  5599  			"aws": testProviderFuncFixed(p),
  5600  		},
  5601  	})
  5602  
  5603  	if _, err := ctx.Plan(); err != nil {
  5604  		t.Fatalf("err: %s", err)
  5605  	}
  5606  
  5607  	state, err := ctx.Apply()
  5608  	if err != nil {
  5609  		t.Fatalf("err: %s", err)
  5610  	}
  5611  
  5612  	actual := strings.TrimSpace(state.String())
  5613  	expected := strings.TrimSpace(testTerraformApplyOutputStr)
  5614  	if actual != expected {
  5615  		t.Fatalf("bad: \n%s", actual)
  5616  	}
  5617  }
  5618  
  5619  func TestContext2Apply_outputInvalid(t *testing.T) {
  5620  	m := testModule(t, "apply-output-invalid")
  5621  	p := testProvider("aws")
  5622  	p.ApplyFn = testApplyFn
  5623  	p.DiffFn = testDiffFn
  5624  	ctx := testContext2(t, &ContextOpts{
  5625  		Module: m,
  5626  		Providers: map[string]ResourceProviderFactory{
  5627  			"aws": testProviderFuncFixed(p),
  5628  		},
  5629  	})
  5630  
  5631  	_, err := ctx.Plan()
  5632  	if err == nil {
  5633  		t.Fatalf("err: %s", err)
  5634  	}
  5635  	if !strings.Contains(err.Error(), "is not a valid type") {
  5636  		t.Fatalf("err: %s", err)
  5637  	}
  5638  }
  5639  
  5640  func TestContext2Apply_outputAdd(t *testing.T) {
  5641  	m1 := testModule(t, "apply-output-add-before")
  5642  	p1 := testProvider("aws")
  5643  	p1.ApplyFn = testApplyFn
  5644  	p1.DiffFn = testDiffFn
  5645  	ctx1 := testContext2(t, &ContextOpts{
  5646  		Module: m1,
  5647  		Providers: map[string]ResourceProviderFactory{
  5648  			"aws": testProviderFuncFixed(p1),
  5649  		},
  5650  	})
  5651  
  5652  	if _, err := ctx1.Plan(); err != nil {
  5653  		t.Fatalf("err: %s", err)
  5654  	}
  5655  
  5656  	state1, err := ctx1.Apply()
  5657  	if err != nil {
  5658  		t.Fatalf("err: %s", err)
  5659  	}
  5660  
  5661  	m2 := testModule(t, "apply-output-add-after")
  5662  	p2 := testProvider("aws")
  5663  	p2.ApplyFn = testApplyFn
  5664  	p2.DiffFn = testDiffFn
  5665  	ctx2 := testContext2(t, &ContextOpts{
  5666  		Module: m2,
  5667  		Providers: map[string]ResourceProviderFactory{
  5668  			"aws": testProviderFuncFixed(p2),
  5669  		},
  5670  		State: state1,
  5671  	})
  5672  
  5673  	if _, err := ctx2.Plan(); err != nil {
  5674  		t.Fatalf("err: %s", err)
  5675  	}
  5676  
  5677  	state2, err := ctx2.Apply()
  5678  	if err != nil {
  5679  		t.Fatalf("err: %s", err)
  5680  	}
  5681  
  5682  	actual := strings.TrimSpace(state2.String())
  5683  	expected := strings.TrimSpace(testTerraformApplyOutputAddStr)
  5684  	if actual != expected {
  5685  		t.Fatalf("bad: \n%s", actual)
  5686  	}
  5687  }
  5688  
  5689  func TestContext2Apply_outputList(t *testing.T) {
  5690  	m := testModule(t, "apply-output-list")
  5691  	p := testProvider("aws")
  5692  	p.ApplyFn = testApplyFn
  5693  	p.DiffFn = testDiffFn
  5694  	ctx := testContext2(t, &ContextOpts{
  5695  		Module: m,
  5696  		Providers: map[string]ResourceProviderFactory{
  5697  			"aws": testProviderFuncFixed(p),
  5698  		},
  5699  	})
  5700  
  5701  	if _, err := ctx.Plan(); err != nil {
  5702  		t.Fatalf("err: %s", err)
  5703  	}
  5704  
  5705  	state, err := ctx.Apply()
  5706  	if err != nil {
  5707  		t.Fatalf("err: %s", err)
  5708  	}
  5709  
  5710  	actual := strings.TrimSpace(state.String())
  5711  	expected := strings.TrimSpace(testTerraformApplyOutputListStr)
  5712  	if actual != expected {
  5713  		t.Fatalf("expected: \n%s\n\nbad: \n%s", expected, actual)
  5714  	}
  5715  }
  5716  
  5717  func TestContext2Apply_outputMulti(t *testing.T) {
  5718  	m := testModule(t, "apply-output-multi")
  5719  	p := testProvider("aws")
  5720  	p.ApplyFn = testApplyFn
  5721  	p.DiffFn = testDiffFn
  5722  	ctx := testContext2(t, &ContextOpts{
  5723  		Module: m,
  5724  		Providers: map[string]ResourceProviderFactory{
  5725  			"aws": testProviderFuncFixed(p),
  5726  		},
  5727  	})
  5728  
  5729  	if _, err := ctx.Plan(); err != nil {
  5730  		t.Fatalf("err: %s", err)
  5731  	}
  5732  
  5733  	state, err := ctx.Apply()
  5734  	if err != nil {
  5735  		t.Fatalf("err: %s", err)
  5736  	}
  5737  
  5738  	actual := strings.TrimSpace(state.String())
  5739  	expected := strings.TrimSpace(testTerraformApplyOutputMultiStr)
  5740  	if actual != expected {
  5741  		t.Fatalf("bad: \n%s", actual)
  5742  	}
  5743  }
  5744  
  5745  func TestContext2Apply_outputMultiIndex(t *testing.T) {
  5746  	m := testModule(t, "apply-output-multi-index")
  5747  	p := testProvider("aws")
  5748  	p.ApplyFn = testApplyFn
  5749  	p.DiffFn = testDiffFn
  5750  	ctx := testContext2(t, &ContextOpts{
  5751  		Module: m,
  5752  		Providers: map[string]ResourceProviderFactory{
  5753  			"aws": testProviderFuncFixed(p),
  5754  		},
  5755  	})
  5756  
  5757  	if _, err := ctx.Plan(); err != nil {
  5758  		t.Fatalf("err: %s", err)
  5759  	}
  5760  
  5761  	state, err := ctx.Apply()
  5762  	if err != nil {
  5763  		t.Fatalf("err: %s", err)
  5764  	}
  5765  
  5766  	actual := strings.TrimSpace(state.String())
  5767  	expected := strings.TrimSpace(testTerraformApplyOutputMultiIndexStr)
  5768  	if actual != expected {
  5769  		t.Fatalf("bad: \n%s", actual)
  5770  	}
  5771  }
  5772  
  5773  func TestContext2Apply_taintX(t *testing.T) {
  5774  	m := testModule(t, "apply-taint")
  5775  	p := testProvider("aws")
  5776  
  5777  	// destroyCount tests against regression of
  5778  	// https://github.com/hashicorp/terraform/issues/1056
  5779  	var destroyCount = int32(0)
  5780  	var once sync.Once
  5781  	simulateProviderDelay := func() {
  5782  		time.Sleep(10 * time.Millisecond)
  5783  	}
  5784  
  5785  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  5786  		once.Do(simulateProviderDelay)
  5787  		if d.Destroy {
  5788  			atomic.AddInt32(&destroyCount, 1)
  5789  		}
  5790  		return testApplyFn(info, s, d)
  5791  	}
  5792  	p.DiffFn = testDiffFn
  5793  	s := &State{
  5794  		Modules: []*ModuleState{
  5795  			&ModuleState{
  5796  				Path: rootModulePath,
  5797  				Resources: map[string]*ResourceState{
  5798  					"aws_instance.bar": &ResourceState{
  5799  						Type: "aws_instance",
  5800  						Primary: &InstanceState{
  5801  							ID: "baz",
  5802  							Attributes: map[string]string{
  5803  								"num":  "2",
  5804  								"type": "aws_instance",
  5805  							},
  5806  							Tainted: true,
  5807  						},
  5808  					},
  5809  				},
  5810  			},
  5811  		},
  5812  	}
  5813  	ctx := testContext2(t, &ContextOpts{
  5814  		Module: m,
  5815  		Providers: map[string]ResourceProviderFactory{
  5816  			"aws": testProviderFuncFixed(p),
  5817  		},
  5818  		State: s,
  5819  	})
  5820  
  5821  	if p, err := ctx.Plan(); err != nil {
  5822  		t.Fatalf("err: %s", err)
  5823  	} else {
  5824  		t.Logf("plan: %s", p)
  5825  	}
  5826  
  5827  	state, err := ctx.Apply()
  5828  	if err != nil {
  5829  		t.Fatalf("err: %s", err)
  5830  	}
  5831  
  5832  	actual := strings.TrimSpace(state.String())
  5833  	expected := strings.TrimSpace(testTerraformApplyTaintStr)
  5834  	if actual != expected {
  5835  		t.Fatalf("bad:\n%s", actual)
  5836  	}
  5837  
  5838  	if destroyCount != 1 {
  5839  		t.Fatalf("Expected 1 destroy, got %d", destroyCount)
  5840  	}
  5841  }
  5842  
  5843  func TestContext2Apply_taintDep(t *testing.T) {
  5844  	m := testModule(t, "apply-taint-dep")
  5845  	p := testProvider("aws")
  5846  	p.ApplyFn = testApplyFn
  5847  	p.DiffFn = testDiffFn
  5848  	s := &State{
  5849  		Modules: []*ModuleState{
  5850  			&ModuleState{
  5851  				Path: rootModulePath,
  5852  				Resources: map[string]*ResourceState{
  5853  					"aws_instance.foo": &ResourceState{
  5854  						Type: "aws_instance",
  5855  						Primary: &InstanceState{
  5856  							ID: "baz",
  5857  							Attributes: map[string]string{
  5858  								"num":  "2",
  5859  								"type": "aws_instance",
  5860  							},
  5861  							Tainted: true,
  5862  						},
  5863  					},
  5864  					"aws_instance.bar": &ResourceState{
  5865  						Type: "aws_instance",
  5866  						Primary: &InstanceState{
  5867  							ID: "bar",
  5868  							Attributes: map[string]string{
  5869  								"foo":  "baz",
  5870  								"num":  "2",
  5871  								"type": "aws_instance",
  5872  							},
  5873  						},
  5874  					},
  5875  				},
  5876  			},
  5877  		},
  5878  	}
  5879  	ctx := testContext2(t, &ContextOpts{
  5880  		Module: m,
  5881  		Providers: map[string]ResourceProviderFactory{
  5882  			"aws": testProviderFuncFixed(p),
  5883  		},
  5884  		State: s,
  5885  	})
  5886  
  5887  	if p, err := ctx.Plan(); err != nil {
  5888  		t.Fatalf("err: %s", err)
  5889  	} else {
  5890  		t.Logf("plan: %s", p)
  5891  	}
  5892  
  5893  	state, err := ctx.Apply()
  5894  	if err != nil {
  5895  		t.Fatalf("err: %s", err)
  5896  	}
  5897  
  5898  	actual := strings.TrimSpace(state.String())
  5899  	expected := strings.TrimSpace(testTerraformApplyTaintDepStr)
  5900  	if actual != expected {
  5901  		t.Fatalf("bad:\n%s", actual)
  5902  	}
  5903  }
  5904  
  5905  func TestContext2Apply_taintDepRequiresNew(t *testing.T) {
  5906  	m := testModule(t, "apply-taint-dep-requires-new")
  5907  	p := testProvider("aws")
  5908  	p.ApplyFn = testApplyFn
  5909  	p.DiffFn = testDiffFn
  5910  	s := &State{
  5911  		Modules: []*ModuleState{
  5912  			&ModuleState{
  5913  				Path: rootModulePath,
  5914  				Resources: map[string]*ResourceState{
  5915  					"aws_instance.foo": &ResourceState{
  5916  						Type: "aws_instance",
  5917  						Primary: &InstanceState{
  5918  							ID: "baz",
  5919  							Attributes: map[string]string{
  5920  								"num":  "2",
  5921  								"type": "aws_instance",
  5922  							},
  5923  							Tainted: true,
  5924  						},
  5925  					},
  5926  					"aws_instance.bar": &ResourceState{
  5927  						Type: "aws_instance",
  5928  						Primary: &InstanceState{
  5929  							ID: "bar",
  5930  							Attributes: map[string]string{
  5931  								"foo":  "baz",
  5932  								"num":  "2",
  5933  								"type": "aws_instance",
  5934  							},
  5935  						},
  5936  					},
  5937  				},
  5938  			},
  5939  		},
  5940  	}
  5941  	ctx := testContext2(t, &ContextOpts{
  5942  		Module: m,
  5943  		Providers: map[string]ResourceProviderFactory{
  5944  			"aws": testProviderFuncFixed(p),
  5945  		},
  5946  		State: s,
  5947  	})
  5948  
  5949  	if p, err := ctx.Plan(); err != nil {
  5950  		t.Fatalf("err: %s", err)
  5951  	} else {
  5952  		t.Logf("plan: %s", p)
  5953  	}
  5954  
  5955  	state, err := ctx.Apply()
  5956  	if err != nil {
  5957  		t.Fatalf("err: %s", err)
  5958  	}
  5959  
  5960  	actual := strings.TrimSpace(state.String())
  5961  	expected := strings.TrimSpace(testTerraformApplyTaintDepRequireNewStr)
  5962  	if actual != expected {
  5963  		t.Fatalf("bad:\n%s", actual)
  5964  	}
  5965  }
  5966  
  5967  func TestContext2Apply_targeted(t *testing.T) {
  5968  	m := testModule(t, "apply-targeted")
  5969  	p := testProvider("aws")
  5970  	p.ApplyFn = testApplyFn
  5971  	p.DiffFn = testDiffFn
  5972  	ctx := testContext2(t, &ContextOpts{
  5973  		Module: m,
  5974  		Providers: map[string]ResourceProviderFactory{
  5975  			"aws": testProviderFuncFixed(p),
  5976  		},
  5977  		Targets: []string{"aws_instance.foo"},
  5978  	})
  5979  
  5980  	if _, err := ctx.Plan(); err != nil {
  5981  		t.Fatalf("err: %s", err)
  5982  	}
  5983  
  5984  	state, err := ctx.Apply()
  5985  	if err != nil {
  5986  		t.Fatalf("err: %s", err)
  5987  	}
  5988  
  5989  	mod := state.RootModule()
  5990  	if len(mod.Resources) != 1 {
  5991  		t.Fatalf("expected 1 resource, got: %#v", mod.Resources)
  5992  	}
  5993  
  5994  	checkStateString(t, state, `
  5995  aws_instance.foo:
  5996    ID = foo
  5997    num = 2
  5998    type = aws_instance
  5999  	`)
  6000  }
  6001  
  6002  func TestContext2Apply_targetedCount(t *testing.T) {
  6003  	m := testModule(t, "apply-targeted-count")
  6004  	p := testProvider("aws")
  6005  	p.ApplyFn = testApplyFn
  6006  	p.DiffFn = testDiffFn
  6007  	ctx := testContext2(t, &ContextOpts{
  6008  		Module: m,
  6009  		Providers: map[string]ResourceProviderFactory{
  6010  			"aws": testProviderFuncFixed(p),
  6011  		},
  6012  		Targets: []string{"aws_instance.foo"},
  6013  	})
  6014  
  6015  	if _, err := ctx.Plan(); err != nil {
  6016  		t.Fatalf("err: %s", err)
  6017  	}
  6018  
  6019  	state, err := ctx.Apply()
  6020  	if err != nil {
  6021  		t.Fatalf("err: %s", err)
  6022  	}
  6023  
  6024  	checkStateString(t, state, `
  6025  aws_instance.foo.0:
  6026    ID = foo
  6027  aws_instance.foo.1:
  6028    ID = foo
  6029  aws_instance.foo.2:
  6030    ID = foo
  6031  	`)
  6032  }
  6033  
  6034  func TestContext2Apply_targetedCountIndex(t *testing.T) {
  6035  	m := testModule(t, "apply-targeted-count")
  6036  	p := testProvider("aws")
  6037  	p.ApplyFn = testApplyFn
  6038  	p.DiffFn = testDiffFn
  6039  	ctx := testContext2(t, &ContextOpts{
  6040  		Module: m,
  6041  		Providers: map[string]ResourceProviderFactory{
  6042  			"aws": testProviderFuncFixed(p),
  6043  		},
  6044  		Targets: []string{"aws_instance.foo[1]"},
  6045  	})
  6046  
  6047  	if _, err := ctx.Plan(); err != nil {
  6048  		t.Fatalf("err: %s", err)
  6049  	}
  6050  
  6051  	state, err := ctx.Apply()
  6052  	if err != nil {
  6053  		t.Fatalf("err: %s", err)
  6054  	}
  6055  
  6056  	checkStateString(t, state, `
  6057  aws_instance.foo.1:
  6058    ID = foo
  6059  	`)
  6060  }
  6061  
  6062  func TestContext2Apply_targetedDestroy(t *testing.T) {
  6063  	m := testModule(t, "apply-targeted")
  6064  	p := testProvider("aws")
  6065  	p.ApplyFn = testApplyFn
  6066  	p.DiffFn = testDiffFn
  6067  	ctx := testContext2(t, &ContextOpts{
  6068  		Module: m,
  6069  		Providers: map[string]ResourceProviderFactory{
  6070  			"aws": testProviderFuncFixed(p),
  6071  		},
  6072  		State: &State{
  6073  			Modules: []*ModuleState{
  6074  				&ModuleState{
  6075  					Path: rootModulePath,
  6076  					Resources: map[string]*ResourceState{
  6077  						"aws_instance.foo": resourceState("aws_instance", "i-bcd345"),
  6078  						"aws_instance.bar": resourceState("aws_instance", "i-abc123"),
  6079  					},
  6080  				},
  6081  			},
  6082  		},
  6083  		Targets: []string{"aws_instance.foo"},
  6084  		Destroy: true,
  6085  	})
  6086  
  6087  	if _, err := ctx.Plan(); err != nil {
  6088  		t.Fatalf("err: %s", err)
  6089  	}
  6090  
  6091  	state, err := ctx.Apply()
  6092  	if err != nil {
  6093  		t.Fatalf("err: %s", err)
  6094  	}
  6095  
  6096  	mod := state.RootModule()
  6097  	if len(mod.Resources) != 1 {
  6098  		t.Fatalf("expected 1 resource, got: %#v", mod.Resources)
  6099  	}
  6100  
  6101  	checkStateString(t, state, `
  6102  aws_instance.bar:
  6103    ID = i-abc123
  6104  	`)
  6105  }
  6106  
  6107  func TestContext2Apply_targetedDestroyCountDeps(t *testing.T) {
  6108  	m := testModule(t, "apply-destroy-targeted-count")
  6109  	p := testProvider("aws")
  6110  	p.ApplyFn = testApplyFn
  6111  	p.DiffFn = testDiffFn
  6112  	ctx := testContext2(t, &ContextOpts{
  6113  		Module: m,
  6114  		Providers: map[string]ResourceProviderFactory{
  6115  			"aws": testProviderFuncFixed(p),
  6116  		},
  6117  		State: &State{
  6118  			Modules: []*ModuleState{
  6119  				&ModuleState{
  6120  					Path: rootModulePath,
  6121  					Resources: map[string]*ResourceState{
  6122  						"aws_instance.foo": resourceState("aws_instance", "i-bcd345"),
  6123  						"aws_instance.bar": resourceState("aws_instance", "i-abc123"),
  6124  					},
  6125  				},
  6126  			},
  6127  		},
  6128  		Targets: []string{"aws_instance.foo"},
  6129  		Destroy: true,
  6130  	})
  6131  
  6132  	if _, err := ctx.Plan(); err != nil {
  6133  		t.Fatalf("err: %s", err)
  6134  	}
  6135  
  6136  	state, err := ctx.Apply()
  6137  	if err != nil {
  6138  		t.Fatalf("err: %s", err)
  6139  	}
  6140  
  6141  	checkStateString(t, state, `<no state>`)
  6142  }
  6143  
  6144  // https://github.com/hashicorp/terraform/issues/4462
  6145  func TestContext2Apply_targetedDestroyModule(t *testing.T) {
  6146  	m := testModule(t, "apply-targeted-module")
  6147  	p := testProvider("aws")
  6148  	p.ApplyFn = testApplyFn
  6149  	p.DiffFn = testDiffFn
  6150  	ctx := testContext2(t, &ContextOpts{
  6151  		Module: m,
  6152  		Providers: map[string]ResourceProviderFactory{
  6153  			"aws": testProviderFuncFixed(p),
  6154  		},
  6155  		State: &State{
  6156  			Modules: []*ModuleState{
  6157  				&ModuleState{
  6158  					Path: rootModulePath,
  6159  					Resources: map[string]*ResourceState{
  6160  						"aws_instance.foo": resourceState("aws_instance", "i-bcd345"),
  6161  						"aws_instance.bar": resourceState("aws_instance", "i-abc123"),
  6162  					},
  6163  				},
  6164  				&ModuleState{
  6165  					Path: []string{"root", "child"},
  6166  					Resources: map[string]*ResourceState{
  6167  						"aws_instance.foo": resourceState("aws_instance", "i-bcd345"),
  6168  						"aws_instance.bar": resourceState("aws_instance", "i-abc123"),
  6169  					},
  6170  				},
  6171  			},
  6172  		},
  6173  		Targets: []string{"module.child.aws_instance.foo"},
  6174  		Destroy: true,
  6175  	})
  6176  
  6177  	if _, err := ctx.Plan(); err != nil {
  6178  		t.Fatalf("err: %s", err)
  6179  	}
  6180  
  6181  	state, err := ctx.Apply()
  6182  	if err != nil {
  6183  		t.Fatalf("err: %s", err)
  6184  	}
  6185  
  6186  	checkStateString(t, state, `
  6187  aws_instance.bar:
  6188    ID = i-abc123
  6189  aws_instance.foo:
  6190    ID = i-bcd345
  6191  
  6192  module.child:
  6193    aws_instance.bar:
  6194      ID = i-abc123
  6195  	`)
  6196  }
  6197  
  6198  func TestContext2Apply_targetedDestroyCountIndex(t *testing.T) {
  6199  	m := testModule(t, "apply-targeted-count")
  6200  	p := testProvider("aws")
  6201  	p.ApplyFn = testApplyFn
  6202  	p.DiffFn = testDiffFn
  6203  	ctx := testContext2(t, &ContextOpts{
  6204  		Module: m,
  6205  		Providers: map[string]ResourceProviderFactory{
  6206  			"aws": testProviderFuncFixed(p),
  6207  		},
  6208  		State: &State{
  6209  			Modules: []*ModuleState{
  6210  				&ModuleState{
  6211  					Path: rootModulePath,
  6212  					Resources: map[string]*ResourceState{
  6213  						"aws_instance.foo.0": resourceState("aws_instance", "i-bcd345"),
  6214  						"aws_instance.foo.1": resourceState("aws_instance", "i-bcd345"),
  6215  						"aws_instance.foo.2": resourceState("aws_instance", "i-bcd345"),
  6216  						"aws_instance.bar.0": resourceState("aws_instance", "i-abc123"),
  6217  						"aws_instance.bar.1": resourceState("aws_instance", "i-abc123"),
  6218  						"aws_instance.bar.2": resourceState("aws_instance", "i-abc123"),
  6219  					},
  6220  				},
  6221  			},
  6222  		},
  6223  		Targets: []string{
  6224  			"aws_instance.foo[2]",
  6225  			"aws_instance.bar[1]",
  6226  		},
  6227  		Destroy: true,
  6228  	})
  6229  
  6230  	if _, err := ctx.Plan(); err != nil {
  6231  		t.Fatalf("err: %s", err)
  6232  	}
  6233  
  6234  	state, err := ctx.Apply()
  6235  	if err != nil {
  6236  		t.Fatalf("err: %s", err)
  6237  	}
  6238  
  6239  	checkStateString(t, state, `
  6240  aws_instance.bar.0:
  6241    ID = i-abc123
  6242  aws_instance.bar.2:
  6243    ID = i-abc123
  6244  aws_instance.foo.0:
  6245    ID = i-bcd345
  6246  aws_instance.foo.1:
  6247    ID = i-bcd345
  6248  	`)
  6249  }
  6250  
  6251  func TestContext2Apply_targetedModule(t *testing.T) {
  6252  	m := testModule(t, "apply-targeted-module")
  6253  	p := testProvider("aws")
  6254  	p.ApplyFn = testApplyFn
  6255  	p.DiffFn = testDiffFn
  6256  	ctx := testContext2(t, &ContextOpts{
  6257  		Module: m,
  6258  		Providers: map[string]ResourceProviderFactory{
  6259  			"aws": testProviderFuncFixed(p),
  6260  		},
  6261  		Targets: []string{"module.child"},
  6262  	})
  6263  
  6264  	if _, err := ctx.Plan(); err != nil {
  6265  		t.Fatalf("err: %s", err)
  6266  	}
  6267  
  6268  	state, err := ctx.Apply()
  6269  	if err != nil {
  6270  		t.Fatalf("err: %s", err)
  6271  	}
  6272  
  6273  	mod := state.ModuleByPath([]string{"root", "child"})
  6274  	if mod == nil {
  6275  		t.Fatalf("no child module found in the state!\n\n%#v", state)
  6276  	}
  6277  	if len(mod.Resources) != 2 {
  6278  		t.Fatalf("expected 2 resources, got: %#v", mod.Resources)
  6279  	}
  6280  
  6281  	checkStateString(t, state, `
  6282  <no state>
  6283  module.child:
  6284    aws_instance.bar:
  6285      ID = foo
  6286      num = 2
  6287      type = aws_instance
  6288    aws_instance.foo:
  6289      ID = foo
  6290      num = 2
  6291      type = aws_instance
  6292  	`)
  6293  }
  6294  
  6295  // GH-1858
  6296  func TestContext2Apply_targetedModuleDep(t *testing.T) {
  6297  	m := testModule(t, "apply-targeted-module-dep")
  6298  	p := testProvider("aws")
  6299  	p.ApplyFn = testApplyFn
  6300  	p.DiffFn = testDiffFn
  6301  	ctx := testContext2(t, &ContextOpts{
  6302  		Module: m,
  6303  		Providers: map[string]ResourceProviderFactory{
  6304  			"aws": testProviderFuncFixed(p),
  6305  		},
  6306  		Targets: []string{"aws_instance.foo"},
  6307  	})
  6308  
  6309  	if p, err := ctx.Plan(); err != nil {
  6310  		t.Fatalf("err: %s", err)
  6311  	} else {
  6312  		t.Logf("Diff: %s", p)
  6313  	}
  6314  
  6315  	state, err := ctx.Apply()
  6316  	if err != nil {
  6317  		t.Fatalf("err: %s", err)
  6318  	}
  6319  
  6320  	checkStateString(t, state, `
  6321  aws_instance.foo:
  6322    ID = foo
  6323    foo = foo
  6324    type = aws_instance
  6325  
  6326    Dependencies:
  6327      module.child
  6328  
  6329  module.child:
  6330    aws_instance.mod:
  6331      ID = foo
  6332  
  6333    Outputs:
  6334  
  6335    output = foo
  6336  	`)
  6337  }
  6338  
  6339  func TestContext2Apply_targetedModuleResource(t *testing.T) {
  6340  	m := testModule(t, "apply-targeted-module-resource")
  6341  	p := testProvider("aws")
  6342  	p.ApplyFn = testApplyFn
  6343  	p.DiffFn = testDiffFn
  6344  	ctx := testContext2(t, &ContextOpts{
  6345  		Module: m,
  6346  		Providers: map[string]ResourceProviderFactory{
  6347  			"aws": testProviderFuncFixed(p),
  6348  		},
  6349  		Targets: []string{"module.child.aws_instance.foo"},
  6350  	})
  6351  
  6352  	if _, err := ctx.Plan(); err != nil {
  6353  		t.Fatalf("err: %s", err)
  6354  	}
  6355  
  6356  	state, err := ctx.Apply()
  6357  	if err != nil {
  6358  		t.Fatalf("err: %s", err)
  6359  	}
  6360  
  6361  	mod := state.ModuleByPath([]string{"root", "child"})
  6362  	if mod == nil || len(mod.Resources) != 1 {
  6363  		t.Fatalf("expected 1 resource, got: %#v", mod)
  6364  	}
  6365  
  6366  	checkStateString(t, state, `
  6367  <no state>
  6368  module.child:
  6369    aws_instance.foo:
  6370      ID = foo
  6371      num = 2
  6372      type = aws_instance
  6373  	`)
  6374  }
  6375  
  6376  func TestContext2Apply_unknownAttribute(t *testing.T) {
  6377  	m := testModule(t, "apply-unknown")
  6378  	p := testProvider("aws")
  6379  	p.ApplyFn = testApplyFn
  6380  	p.DiffFn = testDiffFn
  6381  	ctx := testContext2(t, &ContextOpts{
  6382  		Module: m,
  6383  		Providers: map[string]ResourceProviderFactory{
  6384  			"aws": testProviderFuncFixed(p),
  6385  		},
  6386  	})
  6387  
  6388  	if _, err := ctx.Plan(); err != nil {
  6389  		t.Fatalf("err: %s", err)
  6390  	}
  6391  
  6392  	state, err := ctx.Apply()
  6393  	if err == nil {
  6394  		t.Fatal("should error")
  6395  	}
  6396  
  6397  	actual := strings.TrimSpace(state.String())
  6398  	expected := strings.TrimSpace(testTerraformApplyUnknownAttrStr)
  6399  	if actual != expected {
  6400  		t.Fatalf("bad: \n%s", actual)
  6401  	}
  6402  }
  6403  
  6404  func TestContext2Apply_unknownAttributeInterpolate(t *testing.T) {
  6405  	m := testModule(t, "apply-unknown-interpolate")
  6406  	p := testProvider("aws")
  6407  	p.ApplyFn = testApplyFn
  6408  	p.DiffFn = testDiffFn
  6409  	ctx := testContext2(t, &ContextOpts{
  6410  		Module: m,
  6411  		Providers: map[string]ResourceProviderFactory{
  6412  			"aws": testProviderFuncFixed(p),
  6413  		},
  6414  	})
  6415  
  6416  	if _, err := ctx.Plan(); err == nil {
  6417  		t.Fatal("should error")
  6418  	}
  6419  }
  6420  
  6421  func TestContext2Apply_vars(t *testing.T) {
  6422  	m := testModule(t, "apply-vars")
  6423  	p := testProvider("aws")
  6424  	p.ApplyFn = testApplyFn
  6425  	p.DiffFn = testDiffFn
  6426  	ctx := testContext2(t, &ContextOpts{
  6427  		Module: m,
  6428  		Providers: map[string]ResourceProviderFactory{
  6429  			"aws": testProviderFuncFixed(p),
  6430  		},
  6431  		Variables: map[string]interface{}{
  6432  			"foo":       "us-west-2",
  6433  			"test_list": []interface{}{"Hello", "World"},
  6434  			"test_map": map[string]interface{}{
  6435  				"Hello": "World",
  6436  				"Foo":   "Bar",
  6437  				"Baz":   "Foo",
  6438  			},
  6439  			"amis": []map[string]interface{}{
  6440  				map[string]interface{}{
  6441  					"us-east-1": "override",
  6442  				},
  6443  			},
  6444  		},
  6445  	})
  6446  
  6447  	w, e := ctx.Validate()
  6448  	if len(w) > 0 {
  6449  		t.Fatalf("bad: %#v", w)
  6450  	}
  6451  	if len(e) > 0 {
  6452  		t.Fatalf("bad: %s", e)
  6453  	}
  6454  
  6455  	if _, err := ctx.Plan(); err != nil {
  6456  		t.Fatalf("err: %s", err)
  6457  	}
  6458  
  6459  	state, err := ctx.Apply()
  6460  	if err != nil {
  6461  		t.Fatalf("err: %s", err)
  6462  	}
  6463  
  6464  	actual := strings.TrimSpace(state.String())
  6465  	expected := strings.TrimSpace(testTerraformApplyVarsStr)
  6466  	if actual != expected {
  6467  		t.Fatalf("expected: %s\n got:\n%s", expected, actual)
  6468  	}
  6469  }
  6470  
  6471  func TestContext2Apply_varsEnv(t *testing.T) {
  6472  	// Set the env var
  6473  	defer tempEnv(t, "TF_VAR_ami", "baz")()
  6474  	defer tempEnv(t, "TF_VAR_list", `["Hello", "World"]`)()
  6475  	defer tempEnv(t, "TF_VAR_map", `{"Hello" = "World", "Foo" = "Bar", "Baz" = "Foo"}`)()
  6476  
  6477  	m := testModule(t, "apply-vars-env")
  6478  	p := testProvider("aws")
  6479  	p.ApplyFn = testApplyFn
  6480  	p.DiffFn = testDiffFn
  6481  	ctx := testContext2(t, &ContextOpts{
  6482  		Module: m,
  6483  		Providers: map[string]ResourceProviderFactory{
  6484  			"aws": testProviderFuncFixed(p),
  6485  		},
  6486  	})
  6487  
  6488  	w, e := ctx.Validate()
  6489  	if len(w) > 0 {
  6490  		t.Fatalf("bad: %#v", w)
  6491  	}
  6492  	if len(e) > 0 {
  6493  		t.Fatalf("bad: %s", e)
  6494  	}
  6495  
  6496  	if _, err := ctx.Plan(); err != nil {
  6497  		t.Fatalf("err: %s", err)
  6498  	}
  6499  
  6500  	state, err := ctx.Apply()
  6501  	if err != nil {
  6502  		t.Fatalf("err: %s", err)
  6503  	}
  6504  
  6505  	actual := strings.TrimSpace(state.String())
  6506  	expected := strings.TrimSpace(testTerraformApplyVarsEnvStr)
  6507  	if actual != expected {
  6508  		t.Fatalf("bad: \n%s", actual)
  6509  	}
  6510  }
  6511  
  6512  func TestContext2Apply_createBefore_depends(t *testing.T) {
  6513  	m := testModule(t, "apply-depends-create-before")
  6514  	h := new(HookRecordApplyOrder)
  6515  	p := testProvider("aws")
  6516  	p.ApplyFn = testApplyFn
  6517  	p.DiffFn = testDiffFn
  6518  	state := &State{
  6519  		Modules: []*ModuleState{
  6520  			&ModuleState{
  6521  				Path: rootModulePath,
  6522  				Resources: map[string]*ResourceState{
  6523  					"aws_instance.web": &ResourceState{
  6524  						Type: "aws_instance",
  6525  						Primary: &InstanceState{
  6526  							ID: "bar",
  6527  							Attributes: map[string]string{
  6528  								"require_new": "ami-old",
  6529  							},
  6530  						},
  6531  					},
  6532  					"aws_instance.lb": &ResourceState{
  6533  						Type: "aws_instance",
  6534  						Primary: &InstanceState{
  6535  							ID: "baz",
  6536  							Attributes: map[string]string{
  6537  								"instance": "bar",
  6538  							},
  6539  						},
  6540  					},
  6541  				},
  6542  			},
  6543  		},
  6544  	}
  6545  	ctx := testContext2(t, &ContextOpts{
  6546  		Module: m,
  6547  		Hooks:  []Hook{h},
  6548  		Providers: map[string]ResourceProviderFactory{
  6549  			"aws": testProviderFuncFixed(p),
  6550  		},
  6551  		State: state,
  6552  	})
  6553  
  6554  	if p, err := ctx.Plan(); err != nil {
  6555  		t.Fatalf("err: %s", err)
  6556  	} else {
  6557  		t.Logf("plan: %s", p)
  6558  	}
  6559  
  6560  	h.Active = true
  6561  	state, err := ctx.Apply()
  6562  	if err != nil {
  6563  		t.Fatalf("err: %s", err)
  6564  	}
  6565  
  6566  	mod := state.RootModule()
  6567  	if len(mod.Resources) < 2 {
  6568  		t.Fatalf("bad: %#v", mod.Resources)
  6569  	}
  6570  
  6571  	actual := strings.TrimSpace(state.String())
  6572  	expected := strings.TrimSpace(testTerraformApplyDependsCreateBeforeStr)
  6573  	if actual != expected {
  6574  		t.Fatalf("bad: \n%s\n\n%s", actual, expected)
  6575  	}
  6576  
  6577  	// Test that things were managed _in the right order_
  6578  	order := h.States
  6579  	diffs := h.Diffs
  6580  	if order[0].ID != "" || diffs[0].Destroy {
  6581  		t.Fatalf("should create new instance first: %#v", order)
  6582  	}
  6583  
  6584  	if order[1].ID != "baz" {
  6585  		t.Fatalf("update must happen after create: %#v", order)
  6586  	}
  6587  
  6588  	if order[2].ID != "bar" || !diffs[2].Destroy {
  6589  		t.Fatalf("destroy must happen after update: %#v", order)
  6590  	}
  6591  }
  6592  
  6593  func TestContext2Apply_singleDestroy(t *testing.T) {
  6594  	m := testModule(t, "apply-depends-create-before")
  6595  	h := new(HookRecordApplyOrder)
  6596  	p := testProvider("aws")
  6597  
  6598  	invokeCount := 0
  6599  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  6600  		invokeCount++
  6601  		switch invokeCount {
  6602  		case 1:
  6603  			if d.Destroy {
  6604  				t.Fatalf("should not destroy")
  6605  			}
  6606  			if s.ID != "" {
  6607  				t.Fatalf("should not have ID")
  6608  			}
  6609  		case 2:
  6610  			if d.Destroy {
  6611  				t.Fatalf("should not destroy")
  6612  			}
  6613  			if s.ID != "baz" {
  6614  				t.Fatalf("should have id")
  6615  			}
  6616  		case 3:
  6617  			if !d.Destroy {
  6618  				t.Fatalf("should destroy")
  6619  			}
  6620  			if s.ID == "" {
  6621  				t.Fatalf("should have ID")
  6622  			}
  6623  		default:
  6624  			t.Fatalf("bad invoke count %d", invokeCount)
  6625  		}
  6626  		return testApplyFn(info, s, d)
  6627  	}
  6628  	p.DiffFn = testDiffFn
  6629  	state := &State{
  6630  		Modules: []*ModuleState{
  6631  			&ModuleState{
  6632  				Path: rootModulePath,
  6633  				Resources: map[string]*ResourceState{
  6634  					"aws_instance.web": &ResourceState{
  6635  						Type: "aws_instance",
  6636  						Primary: &InstanceState{
  6637  							ID: "bar",
  6638  							Attributes: map[string]string{
  6639  								"require_new": "ami-old",
  6640  							},
  6641  						},
  6642  					},
  6643  					"aws_instance.lb": &ResourceState{
  6644  						Type: "aws_instance",
  6645  						Primary: &InstanceState{
  6646  							ID: "baz",
  6647  							Attributes: map[string]string{
  6648  								"instance": "bar",
  6649  							},
  6650  						},
  6651  					},
  6652  				},
  6653  			},
  6654  		},
  6655  	}
  6656  	ctx := testContext2(t, &ContextOpts{
  6657  		Module: m,
  6658  		Hooks:  []Hook{h},
  6659  		Providers: map[string]ResourceProviderFactory{
  6660  			"aws": testProviderFuncFixed(p),
  6661  		},
  6662  		State: state,
  6663  	})
  6664  
  6665  	if _, err := ctx.Plan(); err != nil {
  6666  		t.Fatalf("err: %s", err)
  6667  	}
  6668  
  6669  	h.Active = true
  6670  	state, err := ctx.Apply()
  6671  	if err != nil {
  6672  		t.Fatalf("err: %s", err)
  6673  	}
  6674  
  6675  	if invokeCount != 3 {
  6676  		t.Fatalf("bad: %d", invokeCount)
  6677  	}
  6678  }
  6679  
  6680  // GH-7824
  6681  func TestContext2Apply_issue7824(t *testing.T) {
  6682  	p := testProvider("template")
  6683  	p.ResourcesReturn = append(p.ResourcesReturn, ResourceType{
  6684  		Name: "template_file",
  6685  	})
  6686  
  6687  	p.ApplyFn = testApplyFn
  6688  	p.DiffFn = testDiffFn
  6689  
  6690  	// Apply cleanly step 0
  6691  	ctx := testContext2(t, &ContextOpts{
  6692  		Module: testModule(t, "issue-7824"),
  6693  		Providers: map[string]ResourceProviderFactory{
  6694  			"template": testProviderFuncFixed(p),
  6695  		},
  6696  	})
  6697  
  6698  	plan, err := ctx.Plan()
  6699  	if err != nil {
  6700  		t.Fatalf("err: %s", err)
  6701  	}
  6702  
  6703  	// Write / Read plan to simulate running it through a Plan file
  6704  	var buf bytes.Buffer
  6705  	if err := WritePlan(plan, &buf); err != nil {
  6706  		t.Fatalf("err: %s", err)
  6707  	}
  6708  
  6709  	planFromFile, err := ReadPlan(&buf)
  6710  	if err != nil {
  6711  		t.Fatalf("err: %s", err)
  6712  	}
  6713  
  6714  	ctx, err = planFromFile.Context(&ContextOpts{
  6715  		Providers: map[string]ResourceProviderFactory{
  6716  			"template": testProviderFuncFixed(p),
  6717  		},
  6718  	})
  6719  	if err != nil {
  6720  		t.Fatalf("err: %s", err)
  6721  	}
  6722  
  6723  	_, err = ctx.Apply()
  6724  	if err != nil {
  6725  		t.Fatalf("err: %s", err)
  6726  	}
  6727  }
  6728  
  6729  // GH-5254
  6730  func TestContext2Apply_issue5254(t *testing.T) {
  6731  	// Create a provider. We use "template" here just to match the repro
  6732  	// we got from the issue itself.
  6733  	p := testProvider("template")
  6734  	p.ResourcesReturn = append(p.ResourcesReturn, ResourceType{
  6735  		Name: "template_file",
  6736  	})
  6737  
  6738  	p.ApplyFn = testApplyFn
  6739  	p.DiffFn = testDiffFn
  6740  
  6741  	// Apply cleanly step 0
  6742  	ctx := testContext2(t, &ContextOpts{
  6743  		Module: testModule(t, "issue-5254/step-0"),
  6744  		Providers: map[string]ResourceProviderFactory{
  6745  			"template": testProviderFuncFixed(p),
  6746  		},
  6747  	})
  6748  
  6749  	plan, err := ctx.Plan()
  6750  	if err != nil {
  6751  		t.Fatalf("err: %s", err)
  6752  	}
  6753  
  6754  	state, err := ctx.Apply()
  6755  	if err != nil {
  6756  		t.Fatalf("err: %s", err)
  6757  	}
  6758  
  6759  	// Application success. Now make the modification and store a plan
  6760  	ctx = testContext2(t, &ContextOpts{
  6761  		Module: testModule(t, "issue-5254/step-1"),
  6762  		State:  state,
  6763  		Providers: map[string]ResourceProviderFactory{
  6764  			"template": testProviderFuncFixed(p),
  6765  		},
  6766  	})
  6767  
  6768  	plan, err = ctx.Plan()
  6769  	if err != nil {
  6770  		t.Fatalf("err: %s", err)
  6771  	}
  6772  
  6773  	// Write / Read plan to simulate running it through a Plan file
  6774  	var buf bytes.Buffer
  6775  	if err := WritePlan(plan, &buf); err != nil {
  6776  		t.Fatalf("err: %s", err)
  6777  	}
  6778  
  6779  	planFromFile, err := ReadPlan(&buf)
  6780  	if err != nil {
  6781  		t.Fatalf("err: %s", err)
  6782  	}
  6783  
  6784  	ctx, err = planFromFile.Context(&ContextOpts{
  6785  		Providers: map[string]ResourceProviderFactory{
  6786  			"template": testProviderFuncFixed(p),
  6787  		},
  6788  	})
  6789  	if err != nil {
  6790  		t.Fatalf("err: %s", err)
  6791  	}
  6792  
  6793  	state, err = ctx.Apply()
  6794  	if err != nil {
  6795  		t.Fatalf("err: %s", err)
  6796  	}
  6797  
  6798  	actual := strings.TrimSpace(state.String())
  6799  	expected := strings.TrimSpace(`
  6800  template_file.child:
  6801    ID = foo
  6802    template = Hi
  6803    type = template_file
  6804  
  6805    Dependencies:
  6806      template_file.parent
  6807  template_file.parent:
  6808    ID = foo
  6809    template = Hi
  6810    type = template_file
  6811  		`)
  6812  	if actual != expected {
  6813  		t.Fatalf("expected state: \n%s\ngot: \n%s", expected, actual)
  6814  	}
  6815  }
  6816  
  6817  func TestContext2Apply_targetedWithTaintedInState(t *testing.T) {
  6818  	p := testProvider("aws")
  6819  	p.DiffFn = testDiffFn
  6820  	p.ApplyFn = testApplyFn
  6821  	ctx := testContext2(t, &ContextOpts{
  6822  		Module: testModule(t, "apply-tainted-targets"),
  6823  		Providers: map[string]ResourceProviderFactory{
  6824  			"aws": testProviderFuncFixed(p),
  6825  		},
  6826  		Targets: []string{"aws_instance.iambeingadded"},
  6827  		State: &State{
  6828  			Modules: []*ModuleState{
  6829  				&ModuleState{
  6830  					Path: rootModulePath,
  6831  					Resources: map[string]*ResourceState{
  6832  						"aws_instance.ifailedprovisioners": &ResourceState{
  6833  							Primary: &InstanceState{
  6834  								ID:      "ifailedprovisioners",
  6835  								Tainted: true,
  6836  							},
  6837  						},
  6838  					},
  6839  				},
  6840  			},
  6841  		},
  6842  	})
  6843  
  6844  	plan, err := ctx.Plan()
  6845  	if err != nil {
  6846  		t.Fatalf("err: %s", err)
  6847  	}
  6848  
  6849  	// Write / Read plan to simulate running it through a Plan file
  6850  	var buf bytes.Buffer
  6851  	if err := WritePlan(plan, &buf); err != nil {
  6852  		t.Fatalf("err: %s", err)
  6853  	}
  6854  
  6855  	planFromFile, err := ReadPlan(&buf)
  6856  	if err != nil {
  6857  		t.Fatalf("err: %s", err)
  6858  	}
  6859  
  6860  	ctx, err = planFromFile.Context(&ContextOpts{
  6861  		Module: testModule(t, "apply-tainted-targets"),
  6862  		Providers: map[string]ResourceProviderFactory{
  6863  			"aws": testProviderFuncFixed(p),
  6864  		},
  6865  	})
  6866  	if err != nil {
  6867  		t.Fatalf("err: %s", err)
  6868  	}
  6869  
  6870  	state, err := ctx.Apply()
  6871  	if err != nil {
  6872  		t.Fatalf("err: %s", err)
  6873  	}
  6874  
  6875  	actual := strings.TrimSpace(state.String())
  6876  	expected := strings.TrimSpace(`
  6877  aws_instance.iambeingadded:
  6878    ID = foo
  6879  aws_instance.ifailedprovisioners: (tainted)
  6880    ID = ifailedprovisioners
  6881  		`)
  6882  	if actual != expected {
  6883  		t.Fatalf("expected state: \n%s\ngot: \n%s", expected, actual)
  6884  	}
  6885  }
  6886  
  6887  // Higher level test exposing the bug this covers in
  6888  // TestResource_ignoreChangesRequired
  6889  func TestContext2Apply_ignoreChangesCreate(t *testing.T) {
  6890  	m := testModule(t, "apply-ignore-changes-create")
  6891  	p := testProvider("aws")
  6892  	p.ApplyFn = testApplyFn
  6893  	p.DiffFn = testDiffFn
  6894  	ctx := testContext2(t, &ContextOpts{
  6895  		Module: m,
  6896  		Providers: map[string]ResourceProviderFactory{
  6897  			"aws": testProviderFuncFixed(p),
  6898  		},
  6899  	})
  6900  
  6901  	if p, err := ctx.Plan(); err != nil {
  6902  		t.Fatalf("err: %s", err)
  6903  	} else {
  6904  		t.Logf(p.String())
  6905  	}
  6906  
  6907  	state, err := ctx.Apply()
  6908  	if err != nil {
  6909  		t.Fatalf("err: %s", err)
  6910  	}
  6911  
  6912  	mod := state.RootModule()
  6913  	if len(mod.Resources) != 1 {
  6914  		t.Fatalf("bad: %s", state)
  6915  	}
  6916  
  6917  	actual := strings.TrimSpace(state.String())
  6918  	// Expect no changes from original state
  6919  	expected := strings.TrimSpace(`
  6920  aws_instance.foo:
  6921    ID = foo
  6922    required_field = set
  6923    type = aws_instance
  6924  `)
  6925  	if actual != expected {
  6926  		t.Fatalf("expected:\n%s\ngot:\n%s", expected, actual)
  6927  	}
  6928  }
  6929  
  6930  func TestContext2Apply_ignoreChangesWithDep(t *testing.T) {
  6931  	m := testModule(t, "apply-ignore-changes-dep")
  6932  	p := testProvider("aws")
  6933  	p.ApplyFn = testApplyFn
  6934  	p.DiffFn = func(i *InstanceInfo, s *InstanceState, c *ResourceConfig) (*InstanceDiff, error) {
  6935  		switch i.Type {
  6936  		case "aws_instance":
  6937  			newAmi, _ := c.Get("ami")
  6938  			return &InstanceDiff{
  6939  				Attributes: map[string]*ResourceAttrDiff{
  6940  					"ami": &ResourceAttrDiff{
  6941  						Old:         s.Attributes["ami"],
  6942  						New:         newAmi.(string),
  6943  						RequiresNew: true,
  6944  					},
  6945  				},
  6946  			}, nil
  6947  		case "aws_eip":
  6948  			return testDiffFn(i, s, c)
  6949  		default:
  6950  			t.Fatalf("Unexpected type: %s", i.Type)
  6951  			return nil, nil
  6952  		}
  6953  	}
  6954  	s := &State{
  6955  		Modules: []*ModuleState{
  6956  			&ModuleState{
  6957  				Path: rootModulePath,
  6958  				Resources: map[string]*ResourceState{
  6959  					"aws_instance.foo.0": &ResourceState{
  6960  						Primary: &InstanceState{
  6961  							ID: "i-abc123",
  6962  							Attributes: map[string]string{
  6963  								"ami": "ami-abcd1234",
  6964  								"id":  "i-abc123",
  6965  							},
  6966  						},
  6967  					},
  6968  					"aws_instance.foo.1": &ResourceState{
  6969  						Primary: &InstanceState{
  6970  							ID: "i-bcd234",
  6971  							Attributes: map[string]string{
  6972  								"ami": "ami-abcd1234",
  6973  								"id":  "i-bcd234",
  6974  							},
  6975  						},
  6976  					},
  6977  					"aws_eip.foo.0": &ResourceState{
  6978  						Primary: &InstanceState{
  6979  							ID: "eip-abc123",
  6980  							Attributes: map[string]string{
  6981  								"id":       "eip-abc123",
  6982  								"instance": "i-abc123",
  6983  							},
  6984  						},
  6985  					},
  6986  					"aws_eip.foo.1": &ResourceState{
  6987  						Primary: &InstanceState{
  6988  							ID: "eip-bcd234",
  6989  							Attributes: map[string]string{
  6990  								"id":       "eip-bcd234",
  6991  								"instance": "i-bcd234",
  6992  							},
  6993  						},
  6994  					},
  6995  				},
  6996  			},
  6997  		},
  6998  	}
  6999  	ctx := testContext2(t, &ContextOpts{
  7000  		Module: m,
  7001  		Providers: map[string]ResourceProviderFactory{
  7002  			"aws": testProviderFuncFixed(p),
  7003  		},
  7004  		State: s,
  7005  	})
  7006  
  7007  	if p, err := ctx.Plan(); err != nil {
  7008  		t.Fatalf("err: %s", err)
  7009  	} else {
  7010  		t.Logf(p.String())
  7011  	}
  7012  
  7013  	state, err := ctx.Apply()
  7014  	if err != nil {
  7015  		t.Fatalf("err: %s", err)
  7016  	}
  7017  
  7018  	actual := strings.TrimSpace(state.String())
  7019  	expected := strings.TrimSpace(s.String())
  7020  	if actual != expected {
  7021  		t.Fatalf("bad: \n%s", actual)
  7022  	}
  7023  }
  7024  
  7025  func TestContext2Apply_ignoreChangesWildcard(t *testing.T) {
  7026  	m := testModule(t, "apply-ignore-changes-wildcard")
  7027  	p := testProvider("aws")
  7028  	p.ApplyFn = testApplyFn
  7029  	p.DiffFn = testDiffFn
  7030  	ctx := testContext2(t, &ContextOpts{
  7031  		Module: m,
  7032  		Providers: map[string]ResourceProviderFactory{
  7033  			"aws": testProviderFuncFixed(p),
  7034  		},
  7035  	})
  7036  
  7037  	if p, err := ctx.Plan(); err != nil {
  7038  		t.Fatalf("err: %s", err)
  7039  	} else {
  7040  		t.Logf(p.String())
  7041  	}
  7042  
  7043  	state, err := ctx.Apply()
  7044  	if err != nil {
  7045  		t.Fatalf("err: %s", err)
  7046  	}
  7047  
  7048  	mod := state.RootModule()
  7049  	if len(mod.Resources) != 1 {
  7050  		t.Fatalf("bad: %s", state)
  7051  	}
  7052  
  7053  	actual := strings.TrimSpace(state.String())
  7054  	// Expect no changes from original state
  7055  	expected := strings.TrimSpace(`
  7056  aws_instance.foo:
  7057    ID = foo
  7058    required_field = set
  7059    type = aws_instance
  7060  `)
  7061  	if actual != expected {
  7062  		t.Fatalf("expected:\n%s\ngot:\n%s", expected, actual)
  7063  	}
  7064  }
  7065  
  7066  // https://github.com/hashicorp/terraform/issues/7378
  7067  func TestContext2Apply_destroyNestedModuleWithAttrsReferencingResource(t *testing.T) {
  7068  	m := testModule(t, "apply-destroy-nested-module-with-attrs")
  7069  	p := testProvider("null")
  7070  	p.ApplyFn = testApplyFn
  7071  	p.DiffFn = testDiffFn
  7072  
  7073  	var state *State
  7074  	var err error
  7075  	{
  7076  		ctx := testContext2(t, &ContextOpts{
  7077  			Module: m,
  7078  			Providers: map[string]ResourceProviderFactory{
  7079  				"null": testProviderFuncFixed(p),
  7080  			},
  7081  		})
  7082  
  7083  		// First plan and apply a create operation
  7084  		if _, err := ctx.Plan(); err != nil {
  7085  			t.Fatalf("plan err: %s", err)
  7086  		}
  7087  
  7088  		state, err = ctx.Apply()
  7089  		if err != nil {
  7090  			t.Fatalf("apply err: %s", err)
  7091  		}
  7092  	}
  7093  
  7094  	{
  7095  		ctx := testContext2(t, &ContextOpts{
  7096  			Destroy: true,
  7097  			Module:  m,
  7098  			State:   state,
  7099  			Providers: map[string]ResourceProviderFactory{
  7100  				"null": testProviderFuncFixed(p),
  7101  			},
  7102  		})
  7103  
  7104  		plan, err := ctx.Plan()
  7105  		if err != nil {
  7106  			t.Fatalf("destroy plan err: %s", err)
  7107  		}
  7108  
  7109  		var buf bytes.Buffer
  7110  		if err := WritePlan(plan, &buf); err != nil {
  7111  			t.Fatalf("plan write err: %s", err)
  7112  		}
  7113  
  7114  		planFromFile, err := ReadPlan(&buf)
  7115  		if err != nil {
  7116  			t.Fatalf("plan read err: %s", err)
  7117  		}
  7118  
  7119  		ctx, err = planFromFile.Context(&ContextOpts{
  7120  			Providers: map[string]ResourceProviderFactory{
  7121  				"null": testProviderFuncFixed(p),
  7122  			},
  7123  		})
  7124  		if err != nil {
  7125  			t.Fatalf("err: %s", err)
  7126  		}
  7127  
  7128  		state, err = ctx.Apply()
  7129  		if err != nil {
  7130  			t.Fatalf("destroy apply err: %s", err)
  7131  		}
  7132  	}
  7133  
  7134  	//Test that things were destroyed
  7135  	actual := strings.TrimSpace(state.String())
  7136  	expected := strings.TrimSpace(`
  7137  <no state>
  7138  module.middle:
  7139    <no state>
  7140  module.middle.bottom:
  7141    <no state>
  7142  		`)
  7143  	if actual != expected {
  7144  		t.Fatalf("expected: \n%s\n\nbad: \n%s", expected, actual)
  7145  	}
  7146  }
  7147  
  7148  // If a data source explicitly depends on another resource, it's because we need
  7149  // that resource to be applied first.
  7150  func TestContext2Apply_dataDependsOn(t *testing.T) {
  7151  	p := testProvider("null")
  7152  	m := testModule(t, "apply-data-depends-on")
  7153  
  7154  	ctx := testContext2(t, &ContextOpts{
  7155  		Module: m,
  7156  		Providers: map[string]ResourceProviderFactory{
  7157  			"null": testProviderFuncFixed(p),
  7158  		},
  7159  	})
  7160  
  7161  	// the "provisioner" here writes to this variable, because the intent is to
  7162  	// create a dependency which can't be viewed through the graph, and depends
  7163  	// solely on the configuration providing "depends_on"
  7164  	provisionerOutput := ""
  7165  
  7166  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  7167  		// the side effect of the resource being applied
  7168  		provisionerOutput = "APPLIED"
  7169  		return testApplyFn(info, s, d)
  7170  	}
  7171  
  7172  	p.DiffFn = testDiffFn
  7173  	p.ReadDataDiffFn = testDataDiffFn
  7174  
  7175  	p.ReadDataApplyFn = func(*InstanceInfo, *InstanceDiff) (*InstanceState, error) {
  7176  		// Read the artifact created by our dependency being applied.
  7177  		// Without any "depends_on", this would be skipped as it's assumed the
  7178  		// initial diff during refresh was all that's needed.
  7179  		return &InstanceState{
  7180  			ID: "read",
  7181  			Attributes: map[string]string{
  7182  				"foo": provisionerOutput,
  7183  			},
  7184  		}, nil
  7185  	}
  7186  
  7187  	_, err := ctx.Refresh()
  7188  	if err != nil {
  7189  		t.Fatalf("err: %s", err)
  7190  	}
  7191  
  7192  	if _, err := ctx.Plan(); err != nil {
  7193  		t.Fatalf("err: %s", err)
  7194  	}
  7195  
  7196  	state, err := ctx.Apply()
  7197  	if err != nil {
  7198  		t.Fatalf("err: %s", err)
  7199  	}
  7200  
  7201  	root := state.ModuleByPath(RootModulePath)
  7202  	actual := root.Resources["data.null_data_source.read"].Primary.Attributes["foo"]
  7203  
  7204  	expected := "APPLIED"
  7205  	if actual != expected {
  7206  		t.Fatalf("bad:\n%s", strings.TrimSpace(state.String()))
  7207  	}
  7208  }