github.com/pbthorste/terraform@v0.8.6-0.20170127005045-deb56bd93da2/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  // Verify that a normal provisioner with on_failure "continue" set won't
  4002  // taint the resource and continues executing.
  4003  func TestContext2Apply_provisionerFailContinue(t *testing.T) {
  4004  	m := testModule(t, "apply-provisioner-fail-continue")
  4005  	p := testProvider("aws")
  4006  	pr := testProvisioner()
  4007  	p.ApplyFn = testApplyFn
  4008  	p.DiffFn = testDiffFn
  4009  
  4010  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  4011  		return fmt.Errorf("provisioner error")
  4012  	}
  4013  
  4014  	ctx := testContext2(t, &ContextOpts{
  4015  		Module: m,
  4016  		Providers: map[string]ResourceProviderFactory{
  4017  			"aws": testProviderFuncFixed(p),
  4018  		},
  4019  		Provisioners: map[string]ResourceProvisionerFactory{
  4020  			"shell": testProvisionerFuncFixed(pr),
  4021  		},
  4022  	})
  4023  
  4024  	if _, err := ctx.Plan(); err != nil {
  4025  		t.Fatalf("err: %s", err)
  4026  	}
  4027  
  4028  	state, err := ctx.Apply()
  4029  	if err != nil {
  4030  		t.Fatalf("err: %s", err)
  4031  	}
  4032  
  4033  	checkStateString(t, state, `
  4034  aws_instance.foo:
  4035    ID = foo
  4036    foo = bar
  4037    type = aws_instance
  4038    `)
  4039  
  4040  	// Verify apply was invoked
  4041  	if !pr.ApplyCalled {
  4042  		t.Fatalf("provisioner not invoked")
  4043  	}
  4044  }
  4045  
  4046  // Verify that a normal provisioner with on_failure "continue" records
  4047  // the error with the hook.
  4048  func TestContext2Apply_provisionerFailContinueHook(t *testing.T) {
  4049  	h := new(MockHook)
  4050  	m := testModule(t, "apply-provisioner-fail-continue")
  4051  	p := testProvider("aws")
  4052  	pr := testProvisioner()
  4053  	p.ApplyFn = testApplyFn
  4054  	p.DiffFn = testDiffFn
  4055  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  4056  		return fmt.Errorf("provisioner error")
  4057  	}
  4058  
  4059  	ctx := testContext2(t, &ContextOpts{
  4060  		Module: m,
  4061  		Hooks:  []Hook{h},
  4062  		Providers: map[string]ResourceProviderFactory{
  4063  			"aws": testProviderFuncFixed(p),
  4064  		},
  4065  		Provisioners: map[string]ResourceProvisionerFactory{
  4066  			"shell": testProvisionerFuncFixed(pr),
  4067  		},
  4068  	})
  4069  
  4070  	if _, err := ctx.Plan(); err != nil {
  4071  		t.Fatalf("err: %s", err)
  4072  	}
  4073  
  4074  	if _, err := ctx.Apply(); err != nil {
  4075  		t.Fatalf("err: %s", err)
  4076  	}
  4077  
  4078  	if !h.PostProvisionCalled {
  4079  		t.Fatal("PostProvision not called")
  4080  	}
  4081  	if h.PostProvisionErrorArg == nil {
  4082  		t.Fatal("should have error")
  4083  	}
  4084  }
  4085  
  4086  func TestContext2Apply_provisionerDestroy(t *testing.T) {
  4087  	m := testModule(t, "apply-provisioner-destroy")
  4088  	p := testProvider("aws")
  4089  	pr := testProvisioner()
  4090  	p.ApplyFn = testApplyFn
  4091  	p.DiffFn = testDiffFn
  4092  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  4093  		val, ok := c.Config["foo"]
  4094  		if !ok || val != "destroy" {
  4095  			t.Fatalf("bad value for foo: %v %#v", val, c)
  4096  		}
  4097  
  4098  		return nil
  4099  	}
  4100  
  4101  	state := &State{
  4102  		Modules: []*ModuleState{
  4103  			&ModuleState{
  4104  				Path: rootModulePath,
  4105  				Resources: map[string]*ResourceState{
  4106  					"aws_instance.foo": &ResourceState{
  4107  						Type: "aws_instance",
  4108  						Primary: &InstanceState{
  4109  							ID: "bar",
  4110  						},
  4111  					},
  4112  				},
  4113  			},
  4114  		},
  4115  	}
  4116  
  4117  	ctx := testContext2(t, &ContextOpts{
  4118  		Module:  m,
  4119  		State:   state,
  4120  		Destroy: true,
  4121  		Providers: map[string]ResourceProviderFactory{
  4122  			"aws": testProviderFuncFixed(p),
  4123  		},
  4124  		Provisioners: map[string]ResourceProvisionerFactory{
  4125  			"shell": testProvisionerFuncFixed(pr),
  4126  		},
  4127  	})
  4128  
  4129  	if _, err := ctx.Plan(); err != nil {
  4130  		t.Fatalf("err: %s", err)
  4131  	}
  4132  
  4133  	state, err := ctx.Apply()
  4134  	if err != nil {
  4135  		t.Fatalf("err: %s", err)
  4136  	}
  4137  
  4138  	checkStateString(t, state, `<no state>`)
  4139  
  4140  	// Verify apply was invoked
  4141  	if !pr.ApplyCalled {
  4142  		t.Fatalf("provisioner not invoked")
  4143  	}
  4144  }
  4145  
  4146  // Verify that on destroy provisioner failure, nothing happens to the instance
  4147  func TestContext2Apply_provisionerDestroyFail(t *testing.T) {
  4148  	m := testModule(t, "apply-provisioner-destroy")
  4149  	p := testProvider("aws")
  4150  	pr := testProvisioner()
  4151  	p.ApplyFn = testApplyFn
  4152  	p.DiffFn = testDiffFn
  4153  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  4154  		return fmt.Errorf("provisioner error")
  4155  	}
  4156  
  4157  	state := &State{
  4158  		Modules: []*ModuleState{
  4159  			&ModuleState{
  4160  				Path: rootModulePath,
  4161  				Resources: map[string]*ResourceState{
  4162  					"aws_instance.foo": &ResourceState{
  4163  						Type: "aws_instance",
  4164  						Primary: &InstanceState{
  4165  							ID: "bar",
  4166  						},
  4167  					},
  4168  				},
  4169  			},
  4170  		},
  4171  	}
  4172  
  4173  	ctx := testContext2(t, &ContextOpts{
  4174  		Module:  m,
  4175  		State:   state,
  4176  		Destroy: true,
  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.Fatal("should error")
  4192  	}
  4193  
  4194  	checkStateString(t, state, `
  4195  aws_instance.foo:
  4196    ID = bar
  4197  	`)
  4198  
  4199  	// Verify apply was invoked
  4200  	if !pr.ApplyCalled {
  4201  		t.Fatalf("provisioner not invoked")
  4202  	}
  4203  }
  4204  
  4205  // Verify that on destroy provisioner failure with "continue" that
  4206  // we continue to the next provisioner.
  4207  func TestContext2Apply_provisionerDestroyFailContinue(t *testing.T) {
  4208  	m := testModule(t, "apply-provisioner-destroy-continue")
  4209  	p := testProvider("aws")
  4210  	pr := testProvisioner()
  4211  	p.ApplyFn = testApplyFn
  4212  	p.DiffFn = testDiffFn
  4213  
  4214  	var calls []string
  4215  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  4216  		val, ok := c.Config["foo"]
  4217  		if !ok {
  4218  			t.Fatalf("bad value for foo: %v %#v", val, c)
  4219  		}
  4220  
  4221  		calls = append(calls, val.(string))
  4222  		return fmt.Errorf("provisioner error")
  4223  	}
  4224  
  4225  	state := &State{
  4226  		Modules: []*ModuleState{
  4227  			&ModuleState{
  4228  				Path: rootModulePath,
  4229  				Resources: map[string]*ResourceState{
  4230  					"aws_instance.foo": &ResourceState{
  4231  						Type: "aws_instance",
  4232  						Primary: &InstanceState{
  4233  							ID: "bar",
  4234  						},
  4235  					},
  4236  				},
  4237  			},
  4238  		},
  4239  	}
  4240  
  4241  	ctx := testContext2(t, &ContextOpts{
  4242  		Module:  m,
  4243  		State:   state,
  4244  		Destroy: true,
  4245  		Providers: map[string]ResourceProviderFactory{
  4246  			"aws": testProviderFuncFixed(p),
  4247  		},
  4248  		Provisioners: map[string]ResourceProvisionerFactory{
  4249  			"shell": testProvisionerFuncFixed(pr),
  4250  		},
  4251  	})
  4252  
  4253  	if _, err := ctx.Plan(); err != nil {
  4254  		t.Fatalf("err: %s", err)
  4255  	}
  4256  
  4257  	state, err := ctx.Apply()
  4258  	if err != nil {
  4259  		t.Fatalf("err: %s", err)
  4260  	}
  4261  
  4262  	checkStateString(t, state, `<no state>`)
  4263  
  4264  	// Verify apply was invoked
  4265  	if !pr.ApplyCalled {
  4266  		t.Fatalf("provisioner not invoked")
  4267  	}
  4268  
  4269  	expected := []string{"one", "two"}
  4270  	if !reflect.DeepEqual(calls, expected) {
  4271  		t.Fatalf("bad: %#v", calls)
  4272  	}
  4273  }
  4274  
  4275  // Verify that on destroy provisioner failure with "continue" that
  4276  // we continue to the next provisioner. But if the next provisioner defines
  4277  // to fail, then we fail after running it.
  4278  func TestContext2Apply_provisionerDestroyFailContinueFail(t *testing.T) {
  4279  	m := testModule(t, "apply-provisioner-destroy-fail")
  4280  	p := testProvider("aws")
  4281  	pr := testProvisioner()
  4282  	p.ApplyFn = testApplyFn
  4283  	p.DiffFn = testDiffFn
  4284  
  4285  	var calls []string
  4286  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  4287  		val, ok := c.Config["foo"]
  4288  		if !ok {
  4289  			t.Fatalf("bad value for foo: %v %#v", val, c)
  4290  		}
  4291  
  4292  		calls = append(calls, val.(string))
  4293  		return fmt.Errorf("provisioner error")
  4294  	}
  4295  
  4296  	state := &State{
  4297  		Modules: []*ModuleState{
  4298  			&ModuleState{
  4299  				Path: rootModulePath,
  4300  				Resources: map[string]*ResourceState{
  4301  					"aws_instance.foo": &ResourceState{
  4302  						Type: "aws_instance",
  4303  						Primary: &InstanceState{
  4304  							ID: "bar",
  4305  						},
  4306  					},
  4307  				},
  4308  			},
  4309  		},
  4310  	}
  4311  
  4312  	ctx := testContext2(t, &ContextOpts{
  4313  		Module:  m,
  4314  		State:   state,
  4315  		Destroy: true,
  4316  		Providers: map[string]ResourceProviderFactory{
  4317  			"aws": testProviderFuncFixed(p),
  4318  		},
  4319  		Provisioners: map[string]ResourceProvisionerFactory{
  4320  			"shell": testProvisionerFuncFixed(pr),
  4321  		},
  4322  	})
  4323  
  4324  	if _, err := ctx.Plan(); err != nil {
  4325  		t.Fatalf("err: %s", err)
  4326  	}
  4327  
  4328  	state, err := ctx.Apply()
  4329  	if err == nil {
  4330  		t.Fatal("should error")
  4331  	}
  4332  
  4333  	checkStateString(t, state, `
  4334  aws_instance.foo:
  4335    ID = bar
  4336    `)
  4337  
  4338  	// Verify apply was invoked
  4339  	if !pr.ApplyCalled {
  4340  		t.Fatalf("provisioner not invoked")
  4341  	}
  4342  
  4343  	expected := []string{"one", "two"}
  4344  	if !reflect.DeepEqual(calls, expected) {
  4345  		t.Fatalf("bad: %#v", calls)
  4346  	}
  4347  }
  4348  
  4349  // Verify destroy provisioners are not run for tainted instances.
  4350  func TestContext2Apply_provisionerDestroyTainted(t *testing.T) {
  4351  	m := testModule(t, "apply-provisioner-destroy")
  4352  	p := testProvider("aws")
  4353  	pr := testProvisioner()
  4354  	p.ApplyFn = testApplyFn
  4355  	p.DiffFn = testDiffFn
  4356  
  4357  	destroyCalled := false
  4358  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  4359  		expected := "create"
  4360  		if rs.ID == "bar" {
  4361  			destroyCalled = true
  4362  			return nil
  4363  		}
  4364  
  4365  		val, ok := c.Config["foo"]
  4366  		if !ok || val != expected {
  4367  			t.Fatalf("bad value for foo: %v %#v", val, c)
  4368  		}
  4369  
  4370  		return nil
  4371  	}
  4372  
  4373  	state := &State{
  4374  		Modules: []*ModuleState{
  4375  			&ModuleState{
  4376  				Path: rootModulePath,
  4377  				Resources: map[string]*ResourceState{
  4378  					"aws_instance.foo": &ResourceState{
  4379  						Type: "aws_instance",
  4380  						Primary: &InstanceState{
  4381  							ID:      "bar",
  4382  							Tainted: true,
  4383  						},
  4384  					},
  4385  				},
  4386  			},
  4387  		},
  4388  	}
  4389  
  4390  	ctx := testContext2(t, &ContextOpts{
  4391  		Module: m,
  4392  		State:  state,
  4393  		Providers: map[string]ResourceProviderFactory{
  4394  			"aws": testProviderFuncFixed(p),
  4395  		},
  4396  		Provisioners: map[string]ResourceProvisionerFactory{
  4397  			"shell": testProvisionerFuncFixed(pr),
  4398  		},
  4399  	})
  4400  
  4401  	if _, err := ctx.Plan(); err != nil {
  4402  		t.Fatalf("err: %s", err)
  4403  	}
  4404  
  4405  	state, err := ctx.Apply()
  4406  	if err != nil {
  4407  		t.Fatalf("err: %s", err)
  4408  	}
  4409  
  4410  	checkStateString(t, state, `
  4411  aws_instance.foo:
  4412    ID = foo
  4413    foo = bar
  4414    type = aws_instance
  4415  	`)
  4416  
  4417  	// Verify apply was invoked
  4418  	if !pr.ApplyCalled {
  4419  		t.Fatalf("provisioner not invoked")
  4420  	}
  4421  
  4422  	if destroyCalled {
  4423  		t.Fatal("destroy should not be called")
  4424  	}
  4425  }
  4426  
  4427  func TestContext2Apply_provisionerResourceRef(t *testing.T) {
  4428  	m := testModule(t, "apply-provisioner-resource-ref")
  4429  	p := testProvider("aws")
  4430  	pr := testProvisioner()
  4431  	p.ApplyFn = testApplyFn
  4432  	p.DiffFn = testDiffFn
  4433  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  4434  		val, ok := c.Config["foo"]
  4435  		if !ok || val != "2" {
  4436  			t.Fatalf("bad value for foo: %v %#v", val, c)
  4437  		}
  4438  
  4439  		return nil
  4440  	}
  4441  
  4442  	ctx := testContext2(t, &ContextOpts{
  4443  		Module: m,
  4444  		Providers: map[string]ResourceProviderFactory{
  4445  			"aws": testProviderFuncFixed(p),
  4446  		},
  4447  		Provisioners: map[string]ResourceProvisionerFactory{
  4448  			"shell": testProvisionerFuncFixed(pr),
  4449  		},
  4450  	})
  4451  
  4452  	if _, err := ctx.Plan(); err != nil {
  4453  		t.Fatalf("err: %s", err)
  4454  	}
  4455  
  4456  	state, err := ctx.Apply()
  4457  	if err != nil {
  4458  		t.Fatalf("err: %s", err)
  4459  	}
  4460  
  4461  	actual := strings.TrimSpace(state.String())
  4462  	expected := strings.TrimSpace(testTerraformApplyProvisionerResourceRefStr)
  4463  	if actual != expected {
  4464  		t.Fatalf("bad: \n%s", actual)
  4465  	}
  4466  
  4467  	// Verify apply was invoked
  4468  	if !pr.ApplyCalled {
  4469  		t.Fatalf("provisioner not invoked")
  4470  	}
  4471  }
  4472  
  4473  func TestContext2Apply_provisionerSelfRef(t *testing.T) {
  4474  	m := testModule(t, "apply-provisioner-self-ref")
  4475  	p := testProvider("aws")
  4476  	pr := testProvisioner()
  4477  	p.ApplyFn = testApplyFn
  4478  	p.DiffFn = testDiffFn
  4479  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  4480  		val, ok := c.Config["command"]
  4481  		if !ok || val != "bar" {
  4482  			t.Fatalf("bad value for command: %v %#v", val, c)
  4483  		}
  4484  
  4485  		return nil
  4486  	}
  4487  
  4488  	ctx := testContext2(t, &ContextOpts{
  4489  		Module: m,
  4490  		Providers: map[string]ResourceProviderFactory{
  4491  			"aws": testProviderFuncFixed(p),
  4492  		},
  4493  		Provisioners: map[string]ResourceProvisionerFactory{
  4494  			"shell": testProvisionerFuncFixed(pr),
  4495  		},
  4496  	})
  4497  
  4498  	if _, err := ctx.Plan(); err != nil {
  4499  		t.Fatalf("err: %s", err)
  4500  	}
  4501  
  4502  	state, err := ctx.Apply()
  4503  	if err != nil {
  4504  		t.Fatalf("err: %s", err)
  4505  	}
  4506  
  4507  	actual := strings.TrimSpace(state.String())
  4508  	expected := strings.TrimSpace(testTerraformApplyProvisionerSelfRefStr)
  4509  	if actual != expected {
  4510  		t.Fatalf("bad: \n%s", actual)
  4511  	}
  4512  
  4513  	// Verify apply was invoked
  4514  	if !pr.ApplyCalled {
  4515  		t.Fatalf("provisioner not invoked")
  4516  	}
  4517  }
  4518  
  4519  func TestContext2Apply_provisionerMultiSelfRef(t *testing.T) {
  4520  	var lock sync.Mutex
  4521  	commands := make([]string, 0, 5)
  4522  
  4523  	m := testModule(t, "apply-provisioner-multi-self-ref")
  4524  	p := testProvider("aws")
  4525  	pr := testProvisioner()
  4526  	p.ApplyFn = testApplyFn
  4527  	p.DiffFn = testDiffFn
  4528  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  4529  		lock.Lock()
  4530  		defer lock.Unlock()
  4531  
  4532  		val, ok := c.Config["command"]
  4533  		if !ok {
  4534  			t.Fatalf("bad value for command: %v %#v", val, c)
  4535  		}
  4536  
  4537  		commands = append(commands, val.(string))
  4538  		return nil
  4539  	}
  4540  
  4541  	ctx := testContext2(t, &ContextOpts{
  4542  		Module: m,
  4543  		Providers: map[string]ResourceProviderFactory{
  4544  			"aws": testProviderFuncFixed(p),
  4545  		},
  4546  		Provisioners: map[string]ResourceProvisionerFactory{
  4547  			"shell": testProvisionerFuncFixed(pr),
  4548  		},
  4549  	})
  4550  
  4551  	if _, err := ctx.Plan(); err != nil {
  4552  		t.Fatalf("err: %s", err)
  4553  	}
  4554  
  4555  	state, err := ctx.Apply()
  4556  	if err != nil {
  4557  		t.Fatalf("err: %s", err)
  4558  	}
  4559  
  4560  	actual := strings.TrimSpace(state.String())
  4561  	expected := strings.TrimSpace(testTerraformApplyProvisionerMultiSelfRefStr)
  4562  	if actual != expected {
  4563  		t.Fatalf("bad: \n%s", actual)
  4564  	}
  4565  
  4566  	// Verify apply was invoked
  4567  	if !pr.ApplyCalled {
  4568  		t.Fatalf("provisioner not invoked")
  4569  	}
  4570  
  4571  	// Verify our result
  4572  	sort.Strings(commands)
  4573  	expectedCommands := []string{"number 0", "number 1", "number 2"}
  4574  	if !reflect.DeepEqual(commands, expectedCommands) {
  4575  		t.Fatalf("bad: %#v", commands)
  4576  	}
  4577  }
  4578  
  4579  func TestContext2Apply_provisionerMultiSelfRefSingle(t *testing.T) {
  4580  	var lock sync.Mutex
  4581  	order := make([]string, 0, 5)
  4582  
  4583  	m := testModule(t, "apply-provisioner-multi-self-ref-single")
  4584  	p := testProvider("aws")
  4585  	pr := testProvisioner()
  4586  	p.ApplyFn = testApplyFn
  4587  	p.DiffFn = testDiffFn
  4588  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  4589  		lock.Lock()
  4590  		defer lock.Unlock()
  4591  
  4592  		val, ok := c.Config["order"]
  4593  		if !ok {
  4594  			t.Fatalf("bad value for order: %v %#v", val, c)
  4595  		}
  4596  
  4597  		order = append(order, val.(string))
  4598  		return nil
  4599  	}
  4600  
  4601  	ctx := testContext2(t, &ContextOpts{
  4602  		Module: m,
  4603  		Providers: map[string]ResourceProviderFactory{
  4604  			"aws": testProviderFuncFixed(p),
  4605  		},
  4606  		Provisioners: map[string]ResourceProvisionerFactory{
  4607  			"shell": testProvisionerFuncFixed(pr),
  4608  		},
  4609  	})
  4610  
  4611  	if _, err := ctx.Plan(); err != nil {
  4612  		t.Fatalf("err: %s", err)
  4613  	}
  4614  
  4615  	state, err := ctx.Apply()
  4616  	if err != nil {
  4617  		t.Fatalf("err: %s", err)
  4618  	}
  4619  
  4620  	actual := strings.TrimSpace(state.String())
  4621  	expected := strings.TrimSpace(testTerraformApplyProvisionerMultiSelfRefSingleStr)
  4622  	if actual != expected {
  4623  		t.Fatalf("bad: \n%s", actual)
  4624  	}
  4625  
  4626  	// Verify apply was invoked
  4627  	if !pr.ApplyCalled {
  4628  		t.Fatalf("provisioner not invoked")
  4629  	}
  4630  
  4631  	// Verify our result
  4632  	sort.Strings(order)
  4633  	expectedOrder := []string{"0", "1", "2"}
  4634  	if !reflect.DeepEqual(order, expectedOrder) {
  4635  		t.Fatalf("bad: %#v", order)
  4636  	}
  4637  }
  4638  
  4639  func TestContext2Apply_provisionerMultiSelfRefCount(t *testing.T) {
  4640  	var lock sync.Mutex
  4641  	commands := make([]string, 0, 5)
  4642  
  4643  	m := testModule(t, "apply-provisioner-multi-self-ref-count")
  4644  	p := testProvider("aws")
  4645  	pr := testProvisioner()
  4646  	p.ApplyFn = testApplyFn
  4647  	p.DiffFn = testDiffFn
  4648  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  4649  		lock.Lock()
  4650  		defer lock.Unlock()
  4651  
  4652  		val, ok := c.Config["command"]
  4653  		if !ok {
  4654  			t.Fatalf("bad value for command: %v %#v", val, c)
  4655  		}
  4656  
  4657  		commands = append(commands, val.(string))
  4658  		return nil
  4659  	}
  4660  
  4661  	ctx := testContext2(t, &ContextOpts{
  4662  		Module: m,
  4663  		Providers: map[string]ResourceProviderFactory{
  4664  			"aws": testProviderFuncFixed(p),
  4665  		},
  4666  		Provisioners: map[string]ResourceProvisionerFactory{
  4667  			"shell": testProvisionerFuncFixed(pr),
  4668  		},
  4669  	})
  4670  
  4671  	if _, err := ctx.Plan(); err != nil {
  4672  		t.Fatalf("err: %s", err)
  4673  	}
  4674  
  4675  	if _, err := ctx.Apply(); err != nil {
  4676  		t.Fatalf("err: %s", err)
  4677  	}
  4678  
  4679  	// Verify apply was invoked
  4680  	if !pr.ApplyCalled {
  4681  		t.Fatalf("provisioner not invoked")
  4682  	}
  4683  
  4684  	// Verify our result
  4685  	sort.Strings(commands)
  4686  	expectedCommands := []string{"3", "3", "3"}
  4687  	if !reflect.DeepEqual(commands, expectedCommands) {
  4688  		t.Fatalf("bad: %#v", commands)
  4689  	}
  4690  }
  4691  
  4692  func TestContext2Apply_provisionerExplicitSelfRef(t *testing.T) {
  4693  	m := testModule(t, "apply-provisioner-explicit-self-ref")
  4694  	p := testProvider("aws")
  4695  	pr := testProvisioner()
  4696  	p.ApplyFn = testApplyFn
  4697  	p.DiffFn = testDiffFn
  4698  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  4699  		val, ok := c.Config["command"]
  4700  		if !ok || val != "bar" {
  4701  			t.Fatalf("bad value for command: %v %#v", val, c)
  4702  		}
  4703  
  4704  		return nil
  4705  	}
  4706  
  4707  	var state *State
  4708  	{
  4709  		ctx := testContext2(t, &ContextOpts{
  4710  			Module: m,
  4711  			Providers: map[string]ResourceProviderFactory{
  4712  				"aws": testProviderFuncFixed(p),
  4713  			},
  4714  			Provisioners: map[string]ResourceProvisionerFactory{
  4715  				"shell": testProvisionerFuncFixed(pr),
  4716  			},
  4717  		})
  4718  
  4719  		_, err := ctx.Plan()
  4720  		if err != nil {
  4721  			t.Fatalf("err: %s", err)
  4722  		}
  4723  
  4724  		state, err = ctx.Apply()
  4725  		if err != nil {
  4726  			t.Fatalf("err: %s", err)
  4727  		}
  4728  
  4729  		// Verify apply was invoked
  4730  		if !pr.ApplyCalled {
  4731  			t.Fatalf("provisioner not invoked")
  4732  		}
  4733  	}
  4734  
  4735  	{
  4736  		ctx := testContext2(t, &ContextOpts{
  4737  			Module:  m,
  4738  			Destroy: true,
  4739  			State:   state,
  4740  			Providers: map[string]ResourceProviderFactory{
  4741  				"aws": testProviderFuncFixed(p),
  4742  			},
  4743  			Provisioners: map[string]ResourceProvisionerFactory{
  4744  				"shell": testProvisionerFuncFixed(pr),
  4745  			},
  4746  		})
  4747  
  4748  		_, err := ctx.Plan()
  4749  		if err != nil {
  4750  			t.Fatalf("err: %s", err)
  4751  		}
  4752  
  4753  		state, err = ctx.Apply()
  4754  		if err != nil {
  4755  			t.Fatalf("err: %s", err)
  4756  		}
  4757  
  4758  		checkStateString(t, state, `<no state>`)
  4759  	}
  4760  }
  4761  
  4762  // Provisioner should NOT run on a diff, only create
  4763  func TestContext2Apply_Provisioner_Diff(t *testing.T) {
  4764  	m := testModule(t, "apply-provisioner-diff")
  4765  	p := testProvider("aws")
  4766  	pr := testProvisioner()
  4767  	p.ApplyFn = testApplyFn
  4768  	p.DiffFn = testDiffFn
  4769  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  4770  		return nil
  4771  	}
  4772  	ctx := testContext2(t, &ContextOpts{
  4773  		Module: m,
  4774  		Providers: map[string]ResourceProviderFactory{
  4775  			"aws": testProviderFuncFixed(p),
  4776  		},
  4777  		Provisioners: map[string]ResourceProvisionerFactory{
  4778  			"shell": testProvisionerFuncFixed(pr),
  4779  		},
  4780  	})
  4781  
  4782  	if _, err := ctx.Plan(); err != nil {
  4783  		t.Fatalf("err: %s", err)
  4784  	}
  4785  
  4786  	state, err := ctx.Apply()
  4787  	if err != nil {
  4788  		t.Fatalf("err: %s", err)
  4789  	}
  4790  
  4791  	actual := strings.TrimSpace(state.String())
  4792  	expected := strings.TrimSpace(testTerraformApplyProvisionerDiffStr)
  4793  	if actual != expected {
  4794  		t.Fatalf("bad: \n%s", actual)
  4795  	}
  4796  
  4797  	// Verify apply was invoked
  4798  	if !pr.ApplyCalled {
  4799  		t.Fatalf("provisioner not invoked")
  4800  	}
  4801  	pr.ApplyCalled = false
  4802  
  4803  	// Change the state to force a diff
  4804  	mod := state.RootModule()
  4805  	mod.Resources["aws_instance.bar"].Primary.Attributes["foo"] = "baz"
  4806  
  4807  	// Re-create context with state
  4808  	ctx = testContext2(t, &ContextOpts{
  4809  		Module: m,
  4810  		Providers: map[string]ResourceProviderFactory{
  4811  			"aws": testProviderFuncFixed(p),
  4812  		},
  4813  		Provisioners: map[string]ResourceProvisionerFactory{
  4814  			"shell": testProvisionerFuncFixed(pr),
  4815  		},
  4816  		State: state,
  4817  	})
  4818  
  4819  	if _, err := ctx.Plan(); err != nil {
  4820  		t.Fatalf("err: %s", err)
  4821  	}
  4822  
  4823  	state2, err := ctx.Apply()
  4824  	if err != nil {
  4825  		t.Fatalf("err: %s", err)
  4826  	}
  4827  
  4828  	actual = strings.TrimSpace(state2.String())
  4829  	if actual != expected {
  4830  		t.Fatalf("bad: \n%s", actual)
  4831  	}
  4832  
  4833  	// Verify apply was NOT invoked
  4834  	if pr.ApplyCalled {
  4835  		t.Fatalf("provisioner invoked")
  4836  	}
  4837  }
  4838  
  4839  func TestContext2Apply_outputDiffVars(t *testing.T) {
  4840  	m := testModule(t, "apply-good")
  4841  	p := testProvider("aws")
  4842  	s := &State{
  4843  		Modules: []*ModuleState{
  4844  			&ModuleState{
  4845  				Path: rootModulePath,
  4846  				Resources: map[string]*ResourceState{
  4847  					"aws_instance.baz": &ResourceState{
  4848  						Type: "aws_instance",
  4849  						Primary: &InstanceState{
  4850  							ID: "bar",
  4851  						},
  4852  					},
  4853  				},
  4854  			},
  4855  		},
  4856  	}
  4857  	ctx := testContext2(t, &ContextOpts{
  4858  		Module: m,
  4859  		Providers: map[string]ResourceProviderFactory{
  4860  			"aws": testProviderFuncFixed(p),
  4861  		},
  4862  		State: s,
  4863  	})
  4864  
  4865  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  4866  		for k, ad := range d.Attributes {
  4867  			if ad.NewComputed {
  4868  				return nil, fmt.Errorf("%s: computed", k)
  4869  			}
  4870  		}
  4871  
  4872  		result := s.MergeDiff(d)
  4873  		result.ID = "foo"
  4874  		return result, nil
  4875  	}
  4876  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  4877  		return &InstanceDiff{
  4878  			Attributes: map[string]*ResourceAttrDiff{
  4879  				"foo": &ResourceAttrDiff{
  4880  					NewComputed: true,
  4881  					Type:        DiffAttrOutput,
  4882  				},
  4883  				"bar": &ResourceAttrDiff{
  4884  					New: "baz",
  4885  				},
  4886  			},
  4887  		}, nil
  4888  	}
  4889  
  4890  	if _, err := ctx.Plan(); err != nil {
  4891  		t.Fatalf("err: %s", err)
  4892  	}
  4893  	if _, err := ctx.Apply(); err != nil {
  4894  		t.Fatalf("err: %s", err)
  4895  	}
  4896  }
  4897  
  4898  func TestContext2Apply_Provisioner_ConnInfo(t *testing.T) {
  4899  	m := testModule(t, "apply-provisioner-conninfo")
  4900  	p := testProvider("aws")
  4901  	pr := testProvisioner()
  4902  
  4903  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  4904  		if s.Ephemeral.ConnInfo == nil {
  4905  			t.Fatalf("ConnInfo not initialized")
  4906  		}
  4907  
  4908  		result, _ := testApplyFn(info, s, d)
  4909  		result.Ephemeral.ConnInfo = map[string]string{
  4910  			"type": "ssh",
  4911  			"host": "127.0.0.1",
  4912  			"port": "22",
  4913  		}
  4914  		return result, nil
  4915  	}
  4916  	p.DiffFn = testDiffFn
  4917  
  4918  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  4919  		conn := rs.Ephemeral.ConnInfo
  4920  		if conn["type"] != "telnet" {
  4921  			t.Fatalf("Bad: %#v", conn)
  4922  		}
  4923  		if conn["host"] != "127.0.0.1" {
  4924  			t.Fatalf("Bad: %#v", conn)
  4925  		}
  4926  		if conn["port"] != "2222" {
  4927  			t.Fatalf("Bad: %#v", conn)
  4928  		}
  4929  		if conn["user"] != "superuser" {
  4930  			t.Fatalf("Bad: %#v", conn)
  4931  		}
  4932  		if conn["pass"] != "test" {
  4933  			t.Fatalf("Bad: %#v", conn)
  4934  		}
  4935  
  4936  		return nil
  4937  	}
  4938  
  4939  	ctx := testContext2(t, &ContextOpts{
  4940  		Module: m,
  4941  		Providers: map[string]ResourceProviderFactory{
  4942  			"aws": testProviderFuncFixed(p),
  4943  		},
  4944  		Provisioners: map[string]ResourceProvisionerFactory{
  4945  			"shell": testProvisionerFuncFixed(pr),
  4946  		},
  4947  		Variables: map[string]interface{}{
  4948  			"value": "1",
  4949  			"pass":  "test",
  4950  		},
  4951  	})
  4952  
  4953  	if _, err := ctx.Plan(); err != nil {
  4954  		t.Fatalf("err: %s", err)
  4955  	}
  4956  
  4957  	state, err := ctx.Apply()
  4958  	if err != nil {
  4959  		t.Fatalf("err: %s", err)
  4960  	}
  4961  
  4962  	actual := strings.TrimSpace(state.String())
  4963  	expected := strings.TrimSpace(testTerraformApplyProvisionerStr)
  4964  	if actual != expected {
  4965  		t.Fatalf("bad: \n%s", actual)
  4966  	}
  4967  
  4968  	// Verify apply was invoked
  4969  	if !pr.ApplyCalled {
  4970  		t.Fatalf("provisioner not invoked")
  4971  	}
  4972  }
  4973  
  4974  func TestContext2Apply_destroyX(t *testing.T) {
  4975  	m := testModule(t, "apply-destroy")
  4976  	h := new(HookRecordApplyOrder)
  4977  	p := testProvider("aws")
  4978  	p.ApplyFn = testApplyFn
  4979  	p.DiffFn = testDiffFn
  4980  	ctx := testContext2(t, &ContextOpts{
  4981  		Module: m,
  4982  		Hooks:  []Hook{h},
  4983  		Providers: map[string]ResourceProviderFactory{
  4984  			"aws": testProviderFuncFixed(p),
  4985  		},
  4986  	})
  4987  
  4988  	// First plan and apply a create operation
  4989  	if _, err := ctx.Plan(); err != nil {
  4990  		t.Fatalf("err: %s", err)
  4991  	}
  4992  
  4993  	state, err := ctx.Apply()
  4994  	if err != nil {
  4995  		t.Fatalf("err: %s", err)
  4996  	}
  4997  
  4998  	// Next, plan and apply a destroy operation
  4999  	h.Active = true
  5000  	ctx = testContext2(t, &ContextOpts{
  5001  		Destroy: true,
  5002  		State:   state,
  5003  		Module:  m,
  5004  		Hooks:   []Hook{h},
  5005  		Providers: map[string]ResourceProviderFactory{
  5006  			"aws": testProviderFuncFixed(p),
  5007  		},
  5008  	})
  5009  
  5010  	if _, err := ctx.Plan(); err != nil {
  5011  		t.Fatalf("err: %s", err)
  5012  	}
  5013  
  5014  	state, err = ctx.Apply()
  5015  	if err != nil {
  5016  		t.Fatalf("err: %s", err)
  5017  	}
  5018  
  5019  	// Test that things were destroyed
  5020  	actual := strings.TrimSpace(state.String())
  5021  	expected := strings.TrimSpace(testTerraformApplyDestroyStr)
  5022  	if actual != expected {
  5023  		t.Fatalf("bad: \n%s", actual)
  5024  	}
  5025  
  5026  	// Test that things were destroyed _in the right order_
  5027  	expected2 := []string{"aws_instance.bar", "aws_instance.foo"}
  5028  	actual2 := h.IDs
  5029  	if !reflect.DeepEqual(actual2, expected2) {
  5030  		t.Fatalf("expected: %#v\n\ngot:%#v", expected2, actual2)
  5031  	}
  5032  }
  5033  
  5034  func TestContext2Apply_destroyOrder(t *testing.T) {
  5035  	m := testModule(t, "apply-destroy")
  5036  	h := new(HookRecordApplyOrder)
  5037  	p := testProvider("aws")
  5038  	p.ApplyFn = testApplyFn
  5039  	p.DiffFn = testDiffFn
  5040  	ctx := testContext2(t, &ContextOpts{
  5041  		Module: m,
  5042  		Hooks:  []Hook{h},
  5043  		Providers: map[string]ResourceProviderFactory{
  5044  			"aws": testProviderFuncFixed(p),
  5045  		},
  5046  	})
  5047  
  5048  	// First plan and apply a create operation
  5049  	if _, err := ctx.Plan(); err != nil {
  5050  		t.Fatalf("err: %s", err)
  5051  	}
  5052  
  5053  	state, err := ctx.Apply()
  5054  	if err != nil {
  5055  		t.Fatalf("err: %s", err)
  5056  	}
  5057  
  5058  	t.Logf("State 1: %s", state)
  5059  
  5060  	// Next, plan and apply config-less to force a destroy with "apply"
  5061  	h.Active = true
  5062  	ctx = testContext2(t, &ContextOpts{
  5063  		State:  state,
  5064  		Module: module.NewEmptyTree(),
  5065  		Hooks:  []Hook{h},
  5066  		Providers: map[string]ResourceProviderFactory{
  5067  			"aws": testProviderFuncFixed(p),
  5068  		},
  5069  	})
  5070  
  5071  	if _, err := ctx.Plan(); err != nil {
  5072  		t.Fatalf("err: %s", err)
  5073  	}
  5074  
  5075  	state, err = ctx.Apply()
  5076  	if err != nil {
  5077  		t.Fatalf("err: %s", err)
  5078  	}
  5079  
  5080  	// Test that things were destroyed
  5081  	actual := strings.TrimSpace(state.String())
  5082  	expected := strings.TrimSpace(testTerraformApplyDestroyStr)
  5083  	if actual != expected {
  5084  		t.Fatalf("bad: \n%s", actual)
  5085  	}
  5086  
  5087  	// Test that things were destroyed _in the right order_
  5088  	expected2 := []string{"aws_instance.bar", "aws_instance.foo"}
  5089  	actual2 := h.IDs
  5090  	if !reflect.DeepEqual(actual2, expected2) {
  5091  		t.Fatalf("expected: %#v\n\ngot:%#v", expected2, actual2)
  5092  	}
  5093  }
  5094  
  5095  // https://github.com/hashicorp/terraform/issues/2767
  5096  func TestContext2Apply_destroyModulePrefix(t *testing.T) {
  5097  	m := testModule(t, "apply-destroy-module-resource-prefix")
  5098  	h := new(MockHook)
  5099  	p := testProvider("aws")
  5100  	p.ApplyFn = testApplyFn
  5101  	p.DiffFn = testDiffFn
  5102  	ctx := testContext2(t, &ContextOpts{
  5103  		Module: m,
  5104  		Hooks:  []Hook{h},
  5105  		Providers: map[string]ResourceProviderFactory{
  5106  			"aws": testProviderFuncFixed(p),
  5107  		},
  5108  	})
  5109  
  5110  	// First plan and apply a create operation
  5111  	if _, err := ctx.Plan(); err != nil {
  5112  		t.Fatalf("err: %s", err)
  5113  	}
  5114  
  5115  	state, err := ctx.Apply()
  5116  	if err != nil {
  5117  		t.Fatalf("err: %s", err)
  5118  	}
  5119  
  5120  	// Verify that we got the apply info correct
  5121  	if v := h.PreApplyInfo.HumanId(); v != "module.child.aws_instance.foo" {
  5122  		t.Fatalf("bad: %s", v)
  5123  	}
  5124  
  5125  	// Next, plan and apply a destroy operation and reset the hook
  5126  	h = new(MockHook)
  5127  	ctx = testContext2(t, &ContextOpts{
  5128  		Destroy: true,
  5129  		State:   state,
  5130  		Module:  m,
  5131  		Hooks:   []Hook{h},
  5132  		Providers: map[string]ResourceProviderFactory{
  5133  			"aws": testProviderFuncFixed(p),
  5134  		},
  5135  	})
  5136  
  5137  	if _, err := ctx.Plan(); err != nil {
  5138  		t.Fatalf("err: %s", err)
  5139  	}
  5140  
  5141  	state, err = ctx.Apply()
  5142  	if err != nil {
  5143  		t.Fatalf("err: %s", err)
  5144  	}
  5145  
  5146  	// Test that things were destroyed
  5147  	if v := h.PreApplyInfo.HumanId(); v != "module.child.aws_instance.foo" {
  5148  		t.Fatalf("bad: %s", v)
  5149  	}
  5150  }
  5151  
  5152  func TestContext2Apply_destroyNestedModule(t *testing.T) {
  5153  	m := testModule(t, "apply-destroy-nested-module")
  5154  	p := testProvider("aws")
  5155  	p.ApplyFn = testApplyFn
  5156  	p.DiffFn = testDiffFn
  5157  
  5158  	s := &State{
  5159  		Modules: []*ModuleState{
  5160  			&ModuleState{
  5161  				Path: []string{"root", "child", "subchild"},
  5162  				Resources: map[string]*ResourceState{
  5163  					"aws_instance.bar": &ResourceState{
  5164  						Type: "aws_instance",
  5165  						Primary: &InstanceState{
  5166  							ID: "bar",
  5167  						},
  5168  					},
  5169  				},
  5170  			},
  5171  		},
  5172  	}
  5173  
  5174  	ctx := testContext2(t, &ContextOpts{
  5175  		Module: m,
  5176  		Providers: map[string]ResourceProviderFactory{
  5177  			"aws": testProviderFuncFixed(p),
  5178  		},
  5179  		State: s,
  5180  	})
  5181  
  5182  	// First plan and apply a create operation
  5183  	if _, err := ctx.Plan(); err != nil {
  5184  		t.Fatalf("err: %s", err)
  5185  	}
  5186  
  5187  	state, err := ctx.Apply()
  5188  	if err != nil {
  5189  		t.Fatalf("err: %s", err)
  5190  	}
  5191  
  5192  	// Test that things were destroyed
  5193  	actual := strings.TrimSpace(state.String())
  5194  	expected := strings.TrimSpace(testTerraformApplyDestroyNestedModuleStr)
  5195  	if actual != expected {
  5196  		t.Fatalf("bad: \n%s", actual)
  5197  	}
  5198  }
  5199  
  5200  func TestContext2Apply_destroyDeeplyNestedModule(t *testing.T) {
  5201  	m := testModule(t, "apply-destroy-deeply-nested-module")
  5202  	p := testProvider("aws")
  5203  	p.ApplyFn = testApplyFn
  5204  	p.DiffFn = testDiffFn
  5205  
  5206  	s := &State{
  5207  		Modules: []*ModuleState{
  5208  			&ModuleState{
  5209  				Path: []string{"root", "child", "subchild", "subsubchild"},
  5210  				Resources: map[string]*ResourceState{
  5211  					"aws_instance.bar": &ResourceState{
  5212  						Type: "aws_instance",
  5213  						Primary: &InstanceState{
  5214  							ID: "bar",
  5215  						},
  5216  					},
  5217  				},
  5218  			},
  5219  		},
  5220  	}
  5221  
  5222  	ctx := testContext2(t, &ContextOpts{
  5223  		Module: m,
  5224  		Providers: map[string]ResourceProviderFactory{
  5225  			"aws": testProviderFuncFixed(p),
  5226  		},
  5227  		State: s,
  5228  	})
  5229  
  5230  	// First plan and apply a create operation
  5231  	if _, err := ctx.Plan(); err != nil {
  5232  		t.Fatalf("err: %s", err)
  5233  	}
  5234  
  5235  	state, err := ctx.Apply()
  5236  	if err != nil {
  5237  		t.Fatalf("err: %s", err)
  5238  	}
  5239  
  5240  	// Test that things were destroyed
  5241  	actual := strings.TrimSpace(state.String())
  5242  	expected := strings.TrimSpace(`
  5243  module.child.subchild.subsubchild:
  5244    <no state>
  5245  	`)
  5246  	if actual != expected {
  5247  		t.Fatalf("bad: \n%s", actual)
  5248  	}
  5249  }
  5250  
  5251  // https://github.com/hashicorp/terraform/issues/5440
  5252  func TestContext2Apply_destroyModuleWithAttrsReferencingResource(t *testing.T) {
  5253  	m := testModule(t, "apply-destroy-module-with-attrs")
  5254  	p := testProvider("aws")
  5255  	p.ApplyFn = testApplyFn
  5256  	p.DiffFn = testDiffFn
  5257  
  5258  	var state *State
  5259  	var err error
  5260  	{
  5261  		ctx := testContext2(t, &ContextOpts{
  5262  			Module: m,
  5263  			Providers: map[string]ResourceProviderFactory{
  5264  				"aws": testProviderFuncFixed(p),
  5265  			},
  5266  		})
  5267  
  5268  		// First plan and apply a create operation
  5269  		if p, err := ctx.Plan(); err != nil {
  5270  			t.Fatalf("plan err: %s", err)
  5271  		} else {
  5272  			t.Logf("Step 1 plan: %s", p)
  5273  		}
  5274  
  5275  		state, err = ctx.Apply()
  5276  		if err != nil {
  5277  			t.Fatalf("apply err: %s", err)
  5278  		}
  5279  
  5280  		t.Logf("Step 1 state: %s", state)
  5281  	}
  5282  
  5283  	h := new(HookRecordApplyOrder)
  5284  	h.Active = true
  5285  
  5286  	{
  5287  		ctx := testContext2(t, &ContextOpts{
  5288  			Destroy: true,
  5289  			Module:  m,
  5290  			State:   state,
  5291  			Hooks:   []Hook{h},
  5292  			Providers: map[string]ResourceProviderFactory{
  5293  				"aws": testProviderFuncFixed(p),
  5294  			},
  5295  			Variables: map[string]interface{}{
  5296  				"key_name": "foobarkey",
  5297  			},
  5298  		})
  5299  
  5300  		// First plan and apply a create operation
  5301  		plan, err := ctx.Plan()
  5302  		if err != nil {
  5303  			t.Fatalf("destroy plan err: %s", err)
  5304  		}
  5305  
  5306  		t.Logf("Step 2 plan: %s", plan)
  5307  
  5308  		var buf bytes.Buffer
  5309  		if err := WritePlan(plan, &buf); err != nil {
  5310  			t.Fatalf("plan write err: %s", err)
  5311  		}
  5312  
  5313  		planFromFile, err := ReadPlan(&buf)
  5314  		if err != nil {
  5315  			t.Fatalf("plan read err: %s", err)
  5316  		}
  5317  
  5318  		ctx, err = planFromFile.Context(&ContextOpts{
  5319  			Providers: map[string]ResourceProviderFactory{
  5320  				"aws": testProviderFuncFixed(p),
  5321  			},
  5322  		})
  5323  		if err != nil {
  5324  			t.Fatalf("err: %s", err)
  5325  		}
  5326  
  5327  		state, err = ctx.Apply()
  5328  		if err != nil {
  5329  			t.Fatalf("destroy apply err: %s", err)
  5330  		}
  5331  
  5332  		t.Logf("Step 2 state: %s", state)
  5333  	}
  5334  
  5335  	//Test that things were destroyed
  5336  	actual := strings.TrimSpace(state.String())
  5337  	expected := strings.TrimSpace(`
  5338  <no state>
  5339  module.child:
  5340    <no state>
  5341  		`)
  5342  	if actual != expected {
  5343  		t.Fatalf("expected:\n\n%s\n\nactual:\n\n%s", expected, actual)
  5344  	}
  5345  }
  5346  
  5347  func TestContext2Apply_destroyWithModuleVariableAndCount(t *testing.T) {
  5348  	m := testModule(t, "apply-destroy-mod-var-and-count")
  5349  	p := testProvider("aws")
  5350  	p.ApplyFn = testApplyFn
  5351  	p.DiffFn = testDiffFn
  5352  
  5353  	var state *State
  5354  	var err error
  5355  	{
  5356  		ctx := testContext2(t, &ContextOpts{
  5357  			Module: m,
  5358  			Providers: map[string]ResourceProviderFactory{
  5359  				"aws": testProviderFuncFixed(p),
  5360  			},
  5361  		})
  5362  
  5363  		// First plan and apply a create operation
  5364  		if _, err := ctx.Plan(); err != nil {
  5365  			t.Fatalf("plan err: %s", err)
  5366  		}
  5367  
  5368  		state, err = ctx.Apply()
  5369  		if err != nil {
  5370  			t.Fatalf("apply err: %s", err)
  5371  		}
  5372  	}
  5373  
  5374  	h := new(HookRecordApplyOrder)
  5375  	h.Active = true
  5376  
  5377  	{
  5378  		ctx := testContext2(t, &ContextOpts{
  5379  			Destroy: true,
  5380  			Module:  m,
  5381  			State:   state,
  5382  			Hooks:   []Hook{h},
  5383  			Providers: map[string]ResourceProviderFactory{
  5384  				"aws": testProviderFuncFixed(p),
  5385  			},
  5386  		})
  5387  
  5388  		// First plan and apply a create operation
  5389  		plan, err := ctx.Plan()
  5390  		if err != nil {
  5391  			t.Fatalf("destroy plan err: %s", err)
  5392  		}
  5393  
  5394  		var buf bytes.Buffer
  5395  		if err := WritePlan(plan, &buf); err != nil {
  5396  			t.Fatalf("plan write err: %s", err)
  5397  		}
  5398  
  5399  		planFromFile, err := ReadPlan(&buf)
  5400  		if err != nil {
  5401  			t.Fatalf("plan read err: %s", err)
  5402  		}
  5403  
  5404  		ctx, err = planFromFile.Context(&ContextOpts{
  5405  			Providers: map[string]ResourceProviderFactory{
  5406  				"aws": testProviderFuncFixed(p),
  5407  			},
  5408  		})
  5409  		if err != nil {
  5410  			t.Fatalf("err: %s", err)
  5411  		}
  5412  
  5413  		state, err = ctx.Apply()
  5414  		if err != nil {
  5415  			t.Fatalf("destroy apply err: %s", err)
  5416  		}
  5417  	}
  5418  
  5419  	//Test that things were destroyed
  5420  	actual := strings.TrimSpace(state.String())
  5421  	expected := strings.TrimSpace(`
  5422  <no state>
  5423  module.child:
  5424    <no state>
  5425  		`)
  5426  	if actual != expected {
  5427  		t.Fatalf("expected: \n%s\n\nbad: \n%s", expected, actual)
  5428  	}
  5429  }
  5430  
  5431  func TestContext2Apply_destroyTargetWithModuleVariableAndCount(t *testing.T) {
  5432  	m := testModule(t, "apply-destroy-mod-var-and-count")
  5433  	p := testProvider("aws")
  5434  	p.ApplyFn = testApplyFn
  5435  	p.DiffFn = testDiffFn
  5436  
  5437  	var state *State
  5438  	var err error
  5439  	{
  5440  		ctx := testContext2(t, &ContextOpts{
  5441  			Module: m,
  5442  			Providers: map[string]ResourceProviderFactory{
  5443  				"aws": testProviderFuncFixed(p),
  5444  			},
  5445  		})
  5446  
  5447  		// First plan and apply a create operation
  5448  		if _, err := ctx.Plan(); err != nil {
  5449  			t.Fatalf("plan err: %s", err)
  5450  		}
  5451  
  5452  		state, err = ctx.Apply()
  5453  		if err != nil {
  5454  			t.Fatalf("apply err: %s", err)
  5455  		}
  5456  	}
  5457  
  5458  	{
  5459  		ctx := testContext2(t, &ContextOpts{
  5460  			Destroy: true,
  5461  			Module:  m,
  5462  			State:   state,
  5463  			Providers: map[string]ResourceProviderFactory{
  5464  				"aws": testProviderFuncFixed(p),
  5465  			},
  5466  			Targets: []string{"module.child"},
  5467  		})
  5468  
  5469  		_, err := ctx.Plan()
  5470  		if err != nil {
  5471  			t.Fatalf("plan err: %s", err)
  5472  		}
  5473  
  5474  		// Destroy, targeting the module explicitly
  5475  		state, err = ctx.Apply()
  5476  		if err != nil {
  5477  			t.Fatalf("destroy apply err: %s", err)
  5478  		}
  5479  	}
  5480  
  5481  	//Test that things were destroyed
  5482  	actual := strings.TrimSpace(state.String())
  5483  	expected := strings.TrimSpace(`
  5484  <no state>
  5485  module.child:
  5486    <no state>
  5487  		`)
  5488  	if actual != expected {
  5489  		t.Fatalf("expected: \n%s\n\nbad: \n%s", expected, actual)
  5490  	}
  5491  }
  5492  
  5493  func TestContext2Apply_destroyWithModuleVariableAndCountNested(t *testing.T) {
  5494  	m := testModule(t, "apply-destroy-mod-var-and-count-nested")
  5495  	p := testProvider("aws")
  5496  	p.ApplyFn = testApplyFn
  5497  	p.DiffFn = testDiffFn
  5498  
  5499  	var state *State
  5500  	var err error
  5501  	{
  5502  		ctx := testContext2(t, &ContextOpts{
  5503  			Module: m,
  5504  			Providers: map[string]ResourceProviderFactory{
  5505  				"aws": testProviderFuncFixed(p),
  5506  			},
  5507  		})
  5508  
  5509  		// First plan and apply a create operation
  5510  		if _, err := ctx.Plan(); err != nil {
  5511  			t.Fatalf("plan err: %s", err)
  5512  		}
  5513  
  5514  		state, err = ctx.Apply()
  5515  		if err != nil {
  5516  			t.Fatalf("apply err: %s", err)
  5517  		}
  5518  	}
  5519  
  5520  	h := new(HookRecordApplyOrder)
  5521  	h.Active = true
  5522  
  5523  	{
  5524  		ctx := testContext2(t, &ContextOpts{
  5525  			Destroy: true,
  5526  			Module:  m,
  5527  			State:   state,
  5528  			Hooks:   []Hook{h},
  5529  			Providers: map[string]ResourceProviderFactory{
  5530  				"aws": testProviderFuncFixed(p),
  5531  			},
  5532  		})
  5533  
  5534  		// First plan and apply a create operation
  5535  		plan, err := ctx.Plan()
  5536  		if err != nil {
  5537  			t.Fatalf("destroy plan err: %s", err)
  5538  		}
  5539  
  5540  		var buf bytes.Buffer
  5541  		if err := WritePlan(plan, &buf); err != nil {
  5542  			t.Fatalf("plan write err: %s", err)
  5543  		}
  5544  
  5545  		planFromFile, err := ReadPlan(&buf)
  5546  		if err != nil {
  5547  			t.Fatalf("plan read err: %s", err)
  5548  		}
  5549  
  5550  		ctx, err = planFromFile.Context(&ContextOpts{
  5551  			Providers: map[string]ResourceProviderFactory{
  5552  				"aws": testProviderFuncFixed(p),
  5553  			},
  5554  		})
  5555  		if err != nil {
  5556  			t.Fatalf("err: %s", err)
  5557  		}
  5558  
  5559  		state, err = ctx.Apply()
  5560  		if err != nil {
  5561  			t.Fatalf("destroy apply err: %s", err)
  5562  		}
  5563  	}
  5564  
  5565  	//Test that things were destroyed
  5566  	actual := strings.TrimSpace(state.String())
  5567  	expected := strings.TrimSpace(`
  5568  <no state>
  5569  module.child:
  5570    <no state>
  5571  module.child.child2:
  5572    <no state>
  5573  		`)
  5574  	if actual != expected {
  5575  		t.Fatalf("expected: \n%s\n\nbad: \n%s", expected, actual)
  5576  	}
  5577  }
  5578  
  5579  func TestContext2Apply_destroyOutputs(t *testing.T) {
  5580  	m := testModule(t, "apply-destroy-outputs")
  5581  	h := new(HookRecordApplyOrder)
  5582  	p := testProvider("aws")
  5583  	p.ApplyFn = testApplyFn
  5584  	p.DiffFn = testDiffFn
  5585  	ctx := testContext2(t, &ContextOpts{
  5586  		Module: m,
  5587  		Hooks:  []Hook{h},
  5588  		Providers: map[string]ResourceProviderFactory{
  5589  			"aws": testProviderFuncFixed(p),
  5590  		},
  5591  	})
  5592  
  5593  	// First plan and apply a create operation
  5594  	if _, err := ctx.Plan(); err != nil {
  5595  		t.Fatalf("err: %s", err)
  5596  	}
  5597  
  5598  	state, err := ctx.Apply()
  5599  
  5600  	if err != nil {
  5601  		t.Fatalf("err: %s", err)
  5602  	}
  5603  
  5604  	// Next, plan and apply a destroy operation
  5605  	h.Active = true
  5606  	ctx = testContext2(t, &ContextOpts{
  5607  		Destroy: true,
  5608  		State:   state,
  5609  		Module:  m,
  5610  		Hooks:   []Hook{h},
  5611  		Providers: map[string]ResourceProviderFactory{
  5612  			"aws": testProviderFuncFixed(p),
  5613  		},
  5614  	})
  5615  
  5616  	if _, err := ctx.Plan(); err != nil {
  5617  		t.Fatalf("err: %s", err)
  5618  	}
  5619  
  5620  	state, err = ctx.Apply()
  5621  	if err != nil {
  5622  		t.Fatalf("err: %s", err)
  5623  	}
  5624  
  5625  	mod := state.RootModule()
  5626  	if len(mod.Resources) > 0 {
  5627  		t.Fatalf("bad: %#v", mod)
  5628  	}
  5629  }
  5630  
  5631  func TestContext2Apply_destroyOrphan(t *testing.T) {
  5632  	m := testModule(t, "apply-error")
  5633  	p := testProvider("aws")
  5634  	s := &State{
  5635  		Modules: []*ModuleState{
  5636  			&ModuleState{
  5637  				Path: rootModulePath,
  5638  				Resources: map[string]*ResourceState{
  5639  					"aws_instance.baz": &ResourceState{
  5640  						Type: "aws_instance",
  5641  						Primary: &InstanceState{
  5642  							ID: "bar",
  5643  						},
  5644  					},
  5645  				},
  5646  			},
  5647  		},
  5648  	}
  5649  	ctx := testContext2(t, &ContextOpts{
  5650  		Module: m,
  5651  		Providers: map[string]ResourceProviderFactory{
  5652  			"aws": testProviderFuncFixed(p),
  5653  		},
  5654  		State: s,
  5655  	})
  5656  
  5657  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  5658  		if d.Destroy {
  5659  			return nil, nil
  5660  		}
  5661  
  5662  		result := s.MergeDiff(d)
  5663  		result.ID = "foo"
  5664  		return result, nil
  5665  	}
  5666  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  5667  		return &InstanceDiff{
  5668  			Attributes: map[string]*ResourceAttrDiff{
  5669  				"num": &ResourceAttrDiff{
  5670  					New: "bar",
  5671  				},
  5672  			},
  5673  		}, nil
  5674  	}
  5675  
  5676  	if _, err := ctx.Plan(); err != nil {
  5677  		t.Fatalf("err: %s", err)
  5678  	}
  5679  
  5680  	state, err := ctx.Apply()
  5681  	if err != nil {
  5682  		t.Fatalf("err: %s", err)
  5683  	}
  5684  
  5685  	mod := state.RootModule()
  5686  	if _, ok := mod.Resources["aws_instance.baz"]; ok {
  5687  		t.Fatalf("bad: %#v", mod.Resources)
  5688  	}
  5689  }
  5690  
  5691  func TestContext2Apply_destroyTaintedProvisioner(t *testing.T) {
  5692  	m := testModule(t, "apply-destroy-provisioner")
  5693  	p := testProvider("aws")
  5694  	pr := testProvisioner()
  5695  	p.ApplyFn = testApplyFn
  5696  	p.DiffFn = testDiffFn
  5697  
  5698  	called := false
  5699  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  5700  		called = true
  5701  		return nil
  5702  	}
  5703  
  5704  	s := &State{
  5705  		Modules: []*ModuleState{
  5706  			&ModuleState{
  5707  				Path: rootModulePath,
  5708  				Resources: map[string]*ResourceState{
  5709  					"aws_instance.foo": &ResourceState{
  5710  						Type: "aws_instance",
  5711  						Primary: &InstanceState{
  5712  							ID: "bar",
  5713  							Attributes: map[string]string{
  5714  								"id": "bar",
  5715  							},
  5716  							Tainted: true,
  5717  						},
  5718  					},
  5719  				},
  5720  			},
  5721  		},
  5722  	}
  5723  
  5724  	ctx := testContext2(t, &ContextOpts{
  5725  		Module: m,
  5726  		Providers: map[string]ResourceProviderFactory{
  5727  			"aws": testProviderFuncFixed(p),
  5728  		},
  5729  		Provisioners: map[string]ResourceProvisionerFactory{
  5730  			"shell": testProvisionerFuncFixed(pr),
  5731  		},
  5732  		State:   s,
  5733  		Destroy: true,
  5734  	})
  5735  
  5736  	if _, err := ctx.Plan(); err != nil {
  5737  		t.Fatalf("err: %s", err)
  5738  	}
  5739  
  5740  	state, err := ctx.Apply()
  5741  	if err != nil {
  5742  		t.Fatalf("err: %s", err)
  5743  	}
  5744  
  5745  	if called {
  5746  		t.Fatal("provisioner should not be called")
  5747  	}
  5748  
  5749  	actual := strings.TrimSpace(state.String())
  5750  	expected := strings.TrimSpace("<no state>")
  5751  	if actual != expected {
  5752  		t.Fatalf("bad: \n%s", actual)
  5753  	}
  5754  }
  5755  
  5756  func TestContext2Apply_error(t *testing.T) {
  5757  	errored := false
  5758  
  5759  	m := testModule(t, "apply-error")
  5760  	p := testProvider("aws")
  5761  	ctx := testContext2(t, &ContextOpts{
  5762  		Module: m,
  5763  		Providers: map[string]ResourceProviderFactory{
  5764  			"aws": testProviderFuncFixed(p),
  5765  		},
  5766  	})
  5767  
  5768  	p.ApplyFn = func(*InstanceInfo, *InstanceState, *InstanceDiff) (*InstanceState, error) {
  5769  		if errored {
  5770  			state := &InstanceState{
  5771  				ID: "bar",
  5772  			}
  5773  			return state, fmt.Errorf("error")
  5774  		}
  5775  		errored = true
  5776  
  5777  		return &InstanceState{
  5778  			ID: "foo",
  5779  			Attributes: map[string]string{
  5780  				"num": "2",
  5781  			},
  5782  		}, nil
  5783  	}
  5784  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  5785  		return &InstanceDiff{
  5786  			Attributes: map[string]*ResourceAttrDiff{
  5787  				"num": &ResourceAttrDiff{
  5788  					New: "bar",
  5789  				},
  5790  			},
  5791  		}, nil
  5792  	}
  5793  
  5794  	if _, err := ctx.Plan(); err != nil {
  5795  		t.Fatalf("err: %s", err)
  5796  	}
  5797  
  5798  	state, err := ctx.Apply()
  5799  	if err == nil {
  5800  		t.Fatal("should have error")
  5801  	}
  5802  
  5803  	actual := strings.TrimSpace(state.String())
  5804  	expected := strings.TrimSpace(testTerraformApplyErrorStr)
  5805  	if actual != expected {
  5806  		t.Fatalf("bad: \n%s", actual)
  5807  	}
  5808  }
  5809  
  5810  func TestContext2Apply_errorPartial(t *testing.T) {
  5811  	errored := false
  5812  
  5813  	m := testModule(t, "apply-error")
  5814  	p := testProvider("aws")
  5815  	s := &State{
  5816  		Modules: []*ModuleState{
  5817  			&ModuleState{
  5818  				Path: rootModulePath,
  5819  				Resources: map[string]*ResourceState{
  5820  					"aws_instance.bar": &ResourceState{
  5821  						Type: "aws_instance",
  5822  						Primary: &InstanceState{
  5823  							ID: "bar",
  5824  						},
  5825  					},
  5826  				},
  5827  			},
  5828  		},
  5829  	}
  5830  	ctx := testContext2(t, &ContextOpts{
  5831  		Module: m,
  5832  		Providers: map[string]ResourceProviderFactory{
  5833  			"aws": testProviderFuncFixed(p),
  5834  		},
  5835  		State: s,
  5836  	})
  5837  
  5838  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  5839  		if errored {
  5840  			return s, fmt.Errorf("error")
  5841  		}
  5842  		errored = true
  5843  
  5844  		return &InstanceState{
  5845  			ID: "foo",
  5846  			Attributes: map[string]string{
  5847  				"num": "2",
  5848  			},
  5849  		}, nil
  5850  	}
  5851  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  5852  		return &InstanceDiff{
  5853  			Attributes: map[string]*ResourceAttrDiff{
  5854  				"num": &ResourceAttrDiff{
  5855  					New: "bar",
  5856  				},
  5857  			},
  5858  		}, nil
  5859  	}
  5860  
  5861  	if _, err := ctx.Plan(); err != nil {
  5862  		t.Fatalf("err: %s", err)
  5863  	}
  5864  
  5865  	state, err := ctx.Apply()
  5866  	if err == nil {
  5867  		t.Fatal("should have error")
  5868  	}
  5869  
  5870  	mod := state.RootModule()
  5871  	if len(mod.Resources) != 2 {
  5872  		t.Fatalf("bad: %#v", mod.Resources)
  5873  	}
  5874  
  5875  	actual := strings.TrimSpace(state.String())
  5876  	expected := strings.TrimSpace(testTerraformApplyErrorPartialStr)
  5877  	if actual != expected {
  5878  		t.Fatalf("bad: \n%s", actual)
  5879  	}
  5880  }
  5881  
  5882  func TestContext2Apply_hook(t *testing.T) {
  5883  	m := testModule(t, "apply-good")
  5884  	h := new(MockHook)
  5885  	p := testProvider("aws")
  5886  	p.ApplyFn = testApplyFn
  5887  	p.DiffFn = testDiffFn
  5888  	ctx := testContext2(t, &ContextOpts{
  5889  		Module: m,
  5890  		Hooks:  []Hook{h},
  5891  		Providers: map[string]ResourceProviderFactory{
  5892  			"aws": testProviderFuncFixed(p),
  5893  		},
  5894  	})
  5895  
  5896  	if _, err := ctx.Plan(); err != nil {
  5897  		t.Fatalf("err: %s", err)
  5898  	}
  5899  
  5900  	if _, err := ctx.Apply(); err != nil {
  5901  		t.Fatalf("err: %s", err)
  5902  	}
  5903  
  5904  	if !h.PreApplyCalled {
  5905  		t.Fatal("should be called")
  5906  	}
  5907  	if !h.PostApplyCalled {
  5908  		t.Fatal("should be called")
  5909  	}
  5910  	if !h.PostStateUpdateCalled {
  5911  		t.Fatalf("should call post state update")
  5912  	}
  5913  }
  5914  
  5915  func TestContext2Apply_hookOrphan(t *testing.T) {
  5916  	m := testModule(t, "apply-blank")
  5917  	h := new(MockHook)
  5918  	p := testProvider("aws")
  5919  	p.ApplyFn = testApplyFn
  5920  	p.DiffFn = testDiffFn
  5921  
  5922  	state := &State{
  5923  		Modules: []*ModuleState{
  5924  			&ModuleState{
  5925  				Path: rootModulePath,
  5926  				Resources: map[string]*ResourceState{
  5927  					"aws_instance.bar": &ResourceState{
  5928  						Type: "aws_instance",
  5929  						Primary: &InstanceState{
  5930  							ID: "bar",
  5931  						},
  5932  					},
  5933  				},
  5934  			},
  5935  		},
  5936  	}
  5937  
  5938  	ctx := testContext2(t, &ContextOpts{
  5939  		Module: m,
  5940  		State:  state,
  5941  		Hooks:  []Hook{h},
  5942  		Providers: map[string]ResourceProviderFactory{
  5943  			"aws": testProviderFuncFixed(p),
  5944  		},
  5945  	})
  5946  
  5947  	if _, err := ctx.Plan(); err != nil {
  5948  		t.Fatalf("err: %s", err)
  5949  	}
  5950  
  5951  	if _, err := ctx.Apply(); err != nil {
  5952  		t.Fatalf("err: %s", err)
  5953  	}
  5954  
  5955  	if !h.PreApplyCalled {
  5956  		t.Fatal("should be called")
  5957  	}
  5958  	if !h.PostApplyCalled {
  5959  		t.Fatal("should be called")
  5960  	}
  5961  	if !h.PostStateUpdateCalled {
  5962  		t.Fatalf("should call post state update")
  5963  	}
  5964  }
  5965  
  5966  func TestContext2Apply_idAttr(t *testing.T) {
  5967  	m := testModule(t, "apply-idattr")
  5968  	p := testProvider("aws")
  5969  	ctx := testContext2(t, &ContextOpts{
  5970  		Module: m,
  5971  		Providers: map[string]ResourceProviderFactory{
  5972  			"aws": testProviderFuncFixed(p),
  5973  		},
  5974  	})
  5975  
  5976  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  5977  		result := s.MergeDiff(d)
  5978  		result.ID = "foo"
  5979  		result.Attributes = map[string]string{
  5980  			"id": "bar",
  5981  		}
  5982  
  5983  		return result, nil
  5984  	}
  5985  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  5986  		return &InstanceDiff{
  5987  			Attributes: map[string]*ResourceAttrDiff{
  5988  				"num": &ResourceAttrDiff{
  5989  					New: "bar",
  5990  				},
  5991  			},
  5992  		}, nil
  5993  	}
  5994  
  5995  	if _, err := ctx.Plan(); err != nil {
  5996  		t.Fatalf("err: %s", err)
  5997  	}
  5998  
  5999  	state, err := ctx.Apply()
  6000  	if err != nil {
  6001  		t.Fatalf("err: %s", err)
  6002  	}
  6003  
  6004  	mod := state.RootModule()
  6005  	rs, ok := mod.Resources["aws_instance.foo"]
  6006  	if !ok {
  6007  		t.Fatal("not in state")
  6008  	}
  6009  	if rs.Primary.ID != "foo" {
  6010  		t.Fatalf("bad: %#v", rs.Primary.ID)
  6011  	}
  6012  	if rs.Primary.Attributes["id"] != "foo" {
  6013  		t.Fatalf("bad: %#v", rs.Primary.Attributes)
  6014  	}
  6015  }
  6016  
  6017  func TestContext2Apply_outputBasic(t *testing.T) {
  6018  	m := testModule(t, "apply-output")
  6019  	p := testProvider("aws")
  6020  	p.ApplyFn = testApplyFn
  6021  	p.DiffFn = testDiffFn
  6022  	ctx := testContext2(t, &ContextOpts{
  6023  		Module: m,
  6024  		Providers: map[string]ResourceProviderFactory{
  6025  			"aws": testProviderFuncFixed(p),
  6026  		},
  6027  	})
  6028  
  6029  	if _, err := ctx.Plan(); err != nil {
  6030  		t.Fatalf("err: %s", err)
  6031  	}
  6032  
  6033  	state, err := ctx.Apply()
  6034  	if err != nil {
  6035  		t.Fatalf("err: %s", err)
  6036  	}
  6037  
  6038  	actual := strings.TrimSpace(state.String())
  6039  	expected := strings.TrimSpace(testTerraformApplyOutputStr)
  6040  	if actual != expected {
  6041  		t.Fatalf("bad: \n%s", actual)
  6042  	}
  6043  }
  6044  
  6045  func TestContext2Apply_outputInvalid(t *testing.T) {
  6046  	m := testModule(t, "apply-output-invalid")
  6047  	p := testProvider("aws")
  6048  	p.ApplyFn = testApplyFn
  6049  	p.DiffFn = testDiffFn
  6050  	ctx := testContext2(t, &ContextOpts{
  6051  		Module: m,
  6052  		Providers: map[string]ResourceProviderFactory{
  6053  			"aws": testProviderFuncFixed(p),
  6054  		},
  6055  	})
  6056  
  6057  	_, err := ctx.Plan()
  6058  	if err == nil {
  6059  		t.Fatalf("err: %s", err)
  6060  	}
  6061  	if !strings.Contains(err.Error(), "is not a valid type") {
  6062  		t.Fatalf("err: %s", err)
  6063  	}
  6064  }
  6065  
  6066  func TestContext2Apply_outputAdd(t *testing.T) {
  6067  	m1 := testModule(t, "apply-output-add-before")
  6068  	p1 := testProvider("aws")
  6069  	p1.ApplyFn = testApplyFn
  6070  	p1.DiffFn = testDiffFn
  6071  	ctx1 := testContext2(t, &ContextOpts{
  6072  		Module: m1,
  6073  		Providers: map[string]ResourceProviderFactory{
  6074  			"aws": testProviderFuncFixed(p1),
  6075  		},
  6076  	})
  6077  
  6078  	if _, err := ctx1.Plan(); err != nil {
  6079  		t.Fatalf("err: %s", err)
  6080  	}
  6081  
  6082  	state1, err := ctx1.Apply()
  6083  	if err != nil {
  6084  		t.Fatalf("err: %s", err)
  6085  	}
  6086  
  6087  	m2 := testModule(t, "apply-output-add-after")
  6088  	p2 := testProvider("aws")
  6089  	p2.ApplyFn = testApplyFn
  6090  	p2.DiffFn = testDiffFn
  6091  	ctx2 := testContext2(t, &ContextOpts{
  6092  		Module: m2,
  6093  		Providers: map[string]ResourceProviderFactory{
  6094  			"aws": testProviderFuncFixed(p2),
  6095  		},
  6096  		State: state1,
  6097  	})
  6098  
  6099  	if _, err := ctx2.Plan(); err != nil {
  6100  		t.Fatalf("err: %s", err)
  6101  	}
  6102  
  6103  	state2, err := ctx2.Apply()
  6104  	if err != nil {
  6105  		t.Fatalf("err: %s", err)
  6106  	}
  6107  
  6108  	actual := strings.TrimSpace(state2.String())
  6109  	expected := strings.TrimSpace(testTerraformApplyOutputAddStr)
  6110  	if actual != expected {
  6111  		t.Fatalf("bad: \n%s", actual)
  6112  	}
  6113  }
  6114  
  6115  func TestContext2Apply_outputList(t *testing.T) {
  6116  	m := testModule(t, "apply-output-list")
  6117  	p := testProvider("aws")
  6118  	p.ApplyFn = testApplyFn
  6119  	p.DiffFn = testDiffFn
  6120  	ctx := testContext2(t, &ContextOpts{
  6121  		Module: m,
  6122  		Providers: map[string]ResourceProviderFactory{
  6123  			"aws": testProviderFuncFixed(p),
  6124  		},
  6125  	})
  6126  
  6127  	if _, err := ctx.Plan(); err != nil {
  6128  		t.Fatalf("err: %s", err)
  6129  	}
  6130  
  6131  	state, err := ctx.Apply()
  6132  	if err != nil {
  6133  		t.Fatalf("err: %s", err)
  6134  	}
  6135  
  6136  	actual := strings.TrimSpace(state.String())
  6137  	expected := strings.TrimSpace(testTerraformApplyOutputListStr)
  6138  	if actual != expected {
  6139  		t.Fatalf("expected: \n%s\n\nbad: \n%s", expected, actual)
  6140  	}
  6141  }
  6142  
  6143  func TestContext2Apply_outputMulti(t *testing.T) {
  6144  	m := testModule(t, "apply-output-multi")
  6145  	p := testProvider("aws")
  6146  	p.ApplyFn = testApplyFn
  6147  	p.DiffFn = testDiffFn
  6148  	ctx := testContext2(t, &ContextOpts{
  6149  		Module: m,
  6150  		Providers: map[string]ResourceProviderFactory{
  6151  			"aws": testProviderFuncFixed(p),
  6152  		},
  6153  	})
  6154  
  6155  	if _, err := ctx.Plan(); err != nil {
  6156  		t.Fatalf("err: %s", err)
  6157  	}
  6158  
  6159  	state, err := ctx.Apply()
  6160  	if err != nil {
  6161  		t.Fatalf("err: %s", err)
  6162  	}
  6163  
  6164  	actual := strings.TrimSpace(state.String())
  6165  	expected := strings.TrimSpace(testTerraformApplyOutputMultiStr)
  6166  	if actual != expected {
  6167  		t.Fatalf("bad: \n%s", actual)
  6168  	}
  6169  }
  6170  
  6171  func TestContext2Apply_outputMultiIndex(t *testing.T) {
  6172  	m := testModule(t, "apply-output-multi-index")
  6173  	p := testProvider("aws")
  6174  	p.ApplyFn = testApplyFn
  6175  	p.DiffFn = testDiffFn
  6176  	ctx := testContext2(t, &ContextOpts{
  6177  		Module: m,
  6178  		Providers: map[string]ResourceProviderFactory{
  6179  			"aws": testProviderFuncFixed(p),
  6180  		},
  6181  	})
  6182  
  6183  	if _, err := ctx.Plan(); err != nil {
  6184  		t.Fatalf("err: %s", err)
  6185  	}
  6186  
  6187  	state, err := ctx.Apply()
  6188  	if err != nil {
  6189  		t.Fatalf("err: %s", err)
  6190  	}
  6191  
  6192  	actual := strings.TrimSpace(state.String())
  6193  	expected := strings.TrimSpace(testTerraformApplyOutputMultiIndexStr)
  6194  	if actual != expected {
  6195  		t.Fatalf("bad: \n%s", actual)
  6196  	}
  6197  }
  6198  
  6199  func TestContext2Apply_taintX(t *testing.T) {
  6200  	m := testModule(t, "apply-taint")
  6201  	p := testProvider("aws")
  6202  
  6203  	// destroyCount tests against regression of
  6204  	// https://github.com/hashicorp/terraform/issues/1056
  6205  	var destroyCount = int32(0)
  6206  	var once sync.Once
  6207  	simulateProviderDelay := func() {
  6208  		time.Sleep(10 * time.Millisecond)
  6209  	}
  6210  
  6211  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  6212  		once.Do(simulateProviderDelay)
  6213  		if d.Destroy {
  6214  			atomic.AddInt32(&destroyCount, 1)
  6215  		}
  6216  		return testApplyFn(info, s, d)
  6217  	}
  6218  	p.DiffFn = testDiffFn
  6219  	s := &State{
  6220  		Modules: []*ModuleState{
  6221  			&ModuleState{
  6222  				Path: rootModulePath,
  6223  				Resources: map[string]*ResourceState{
  6224  					"aws_instance.bar": &ResourceState{
  6225  						Type: "aws_instance",
  6226  						Primary: &InstanceState{
  6227  							ID: "baz",
  6228  							Attributes: map[string]string{
  6229  								"num":  "2",
  6230  								"type": "aws_instance",
  6231  							},
  6232  							Tainted: true,
  6233  						},
  6234  					},
  6235  				},
  6236  			},
  6237  		},
  6238  	}
  6239  	ctx := testContext2(t, &ContextOpts{
  6240  		Module: m,
  6241  		Providers: map[string]ResourceProviderFactory{
  6242  			"aws": testProviderFuncFixed(p),
  6243  		},
  6244  		State: s,
  6245  	})
  6246  
  6247  	if p, err := ctx.Plan(); err != nil {
  6248  		t.Fatalf("err: %s", err)
  6249  	} else {
  6250  		t.Logf("plan: %s", p)
  6251  	}
  6252  
  6253  	state, err := ctx.Apply()
  6254  	if err != nil {
  6255  		t.Fatalf("err: %s", err)
  6256  	}
  6257  
  6258  	actual := strings.TrimSpace(state.String())
  6259  	expected := strings.TrimSpace(testTerraformApplyTaintStr)
  6260  	if actual != expected {
  6261  		t.Fatalf("bad:\n%s", actual)
  6262  	}
  6263  
  6264  	if destroyCount != 1 {
  6265  		t.Fatalf("Expected 1 destroy, got %d", destroyCount)
  6266  	}
  6267  }
  6268  
  6269  func TestContext2Apply_taintDep(t *testing.T) {
  6270  	m := testModule(t, "apply-taint-dep")
  6271  	p := testProvider("aws")
  6272  	p.ApplyFn = testApplyFn
  6273  	p.DiffFn = testDiffFn
  6274  	s := &State{
  6275  		Modules: []*ModuleState{
  6276  			&ModuleState{
  6277  				Path: rootModulePath,
  6278  				Resources: map[string]*ResourceState{
  6279  					"aws_instance.foo": &ResourceState{
  6280  						Type: "aws_instance",
  6281  						Primary: &InstanceState{
  6282  							ID: "baz",
  6283  							Attributes: map[string]string{
  6284  								"num":  "2",
  6285  								"type": "aws_instance",
  6286  							},
  6287  							Tainted: true,
  6288  						},
  6289  					},
  6290  					"aws_instance.bar": &ResourceState{
  6291  						Type: "aws_instance",
  6292  						Primary: &InstanceState{
  6293  							ID: "bar",
  6294  							Attributes: map[string]string{
  6295  								"foo":  "baz",
  6296  								"num":  "2",
  6297  								"type": "aws_instance",
  6298  							},
  6299  						},
  6300  					},
  6301  				},
  6302  			},
  6303  		},
  6304  	}
  6305  	ctx := testContext2(t, &ContextOpts{
  6306  		Module: m,
  6307  		Providers: map[string]ResourceProviderFactory{
  6308  			"aws": testProviderFuncFixed(p),
  6309  		},
  6310  		State: s,
  6311  	})
  6312  
  6313  	if p, err := ctx.Plan(); err != nil {
  6314  		t.Fatalf("err: %s", err)
  6315  	} else {
  6316  		t.Logf("plan: %s", p)
  6317  	}
  6318  
  6319  	state, err := ctx.Apply()
  6320  	if err != nil {
  6321  		t.Fatalf("err: %s", err)
  6322  	}
  6323  
  6324  	actual := strings.TrimSpace(state.String())
  6325  	expected := strings.TrimSpace(testTerraformApplyTaintDepStr)
  6326  	if actual != expected {
  6327  		t.Fatalf("bad:\n%s", actual)
  6328  	}
  6329  }
  6330  
  6331  func TestContext2Apply_taintDepRequiresNew(t *testing.T) {
  6332  	m := testModule(t, "apply-taint-dep-requires-new")
  6333  	p := testProvider("aws")
  6334  	p.ApplyFn = testApplyFn
  6335  	p.DiffFn = testDiffFn
  6336  	s := &State{
  6337  		Modules: []*ModuleState{
  6338  			&ModuleState{
  6339  				Path: rootModulePath,
  6340  				Resources: map[string]*ResourceState{
  6341  					"aws_instance.foo": &ResourceState{
  6342  						Type: "aws_instance",
  6343  						Primary: &InstanceState{
  6344  							ID: "baz",
  6345  							Attributes: map[string]string{
  6346  								"num":  "2",
  6347  								"type": "aws_instance",
  6348  							},
  6349  							Tainted: true,
  6350  						},
  6351  					},
  6352  					"aws_instance.bar": &ResourceState{
  6353  						Type: "aws_instance",
  6354  						Primary: &InstanceState{
  6355  							ID: "bar",
  6356  							Attributes: map[string]string{
  6357  								"foo":  "baz",
  6358  								"num":  "2",
  6359  								"type": "aws_instance",
  6360  							},
  6361  						},
  6362  					},
  6363  				},
  6364  			},
  6365  		},
  6366  	}
  6367  	ctx := testContext2(t, &ContextOpts{
  6368  		Module: m,
  6369  		Providers: map[string]ResourceProviderFactory{
  6370  			"aws": testProviderFuncFixed(p),
  6371  		},
  6372  		State: s,
  6373  	})
  6374  
  6375  	if p, err := ctx.Plan(); err != nil {
  6376  		t.Fatalf("err: %s", err)
  6377  	} else {
  6378  		t.Logf("plan: %s", p)
  6379  	}
  6380  
  6381  	state, err := ctx.Apply()
  6382  	if err != nil {
  6383  		t.Fatalf("err: %s", err)
  6384  	}
  6385  
  6386  	actual := strings.TrimSpace(state.String())
  6387  	expected := strings.TrimSpace(testTerraformApplyTaintDepRequireNewStr)
  6388  	if actual != expected {
  6389  		t.Fatalf("bad:\n%s", actual)
  6390  	}
  6391  }
  6392  
  6393  func TestContext2Apply_targeted(t *testing.T) {
  6394  	m := testModule(t, "apply-targeted")
  6395  	p := testProvider("aws")
  6396  	p.ApplyFn = testApplyFn
  6397  	p.DiffFn = testDiffFn
  6398  	ctx := testContext2(t, &ContextOpts{
  6399  		Module: m,
  6400  		Providers: map[string]ResourceProviderFactory{
  6401  			"aws": testProviderFuncFixed(p),
  6402  		},
  6403  		Targets: []string{"aws_instance.foo"},
  6404  	})
  6405  
  6406  	if _, err := ctx.Plan(); err != nil {
  6407  		t.Fatalf("err: %s", err)
  6408  	}
  6409  
  6410  	state, err := ctx.Apply()
  6411  	if err != nil {
  6412  		t.Fatalf("err: %s", err)
  6413  	}
  6414  
  6415  	mod := state.RootModule()
  6416  	if len(mod.Resources) != 1 {
  6417  		t.Fatalf("expected 1 resource, got: %#v", mod.Resources)
  6418  	}
  6419  
  6420  	checkStateString(t, state, `
  6421  aws_instance.foo:
  6422    ID = foo
  6423    num = 2
  6424    type = aws_instance
  6425  	`)
  6426  }
  6427  
  6428  func TestContext2Apply_targetedCount(t *testing.T) {
  6429  	m := testModule(t, "apply-targeted-count")
  6430  	p := testProvider("aws")
  6431  	p.ApplyFn = testApplyFn
  6432  	p.DiffFn = testDiffFn
  6433  	ctx := testContext2(t, &ContextOpts{
  6434  		Module: m,
  6435  		Providers: map[string]ResourceProviderFactory{
  6436  			"aws": testProviderFuncFixed(p),
  6437  		},
  6438  		Targets: []string{"aws_instance.foo"},
  6439  	})
  6440  
  6441  	if _, err := ctx.Plan(); err != nil {
  6442  		t.Fatalf("err: %s", err)
  6443  	}
  6444  
  6445  	state, err := ctx.Apply()
  6446  	if err != nil {
  6447  		t.Fatalf("err: %s", err)
  6448  	}
  6449  
  6450  	checkStateString(t, state, `
  6451  aws_instance.foo.0:
  6452    ID = foo
  6453  aws_instance.foo.1:
  6454    ID = foo
  6455  aws_instance.foo.2:
  6456    ID = foo
  6457  	`)
  6458  }
  6459  
  6460  func TestContext2Apply_targetedCountIndex(t *testing.T) {
  6461  	m := testModule(t, "apply-targeted-count")
  6462  	p := testProvider("aws")
  6463  	p.ApplyFn = testApplyFn
  6464  	p.DiffFn = testDiffFn
  6465  	ctx := testContext2(t, &ContextOpts{
  6466  		Module: m,
  6467  		Providers: map[string]ResourceProviderFactory{
  6468  			"aws": testProviderFuncFixed(p),
  6469  		},
  6470  		Targets: []string{"aws_instance.foo[1]"},
  6471  	})
  6472  
  6473  	if _, err := ctx.Plan(); err != nil {
  6474  		t.Fatalf("err: %s", err)
  6475  	}
  6476  
  6477  	state, err := ctx.Apply()
  6478  	if err != nil {
  6479  		t.Fatalf("err: %s", err)
  6480  	}
  6481  
  6482  	checkStateString(t, state, `
  6483  aws_instance.foo.1:
  6484    ID = foo
  6485  	`)
  6486  }
  6487  
  6488  func TestContext2Apply_targetedDestroy(t *testing.T) {
  6489  	m := testModule(t, "apply-targeted")
  6490  	p := testProvider("aws")
  6491  	p.ApplyFn = testApplyFn
  6492  	p.DiffFn = testDiffFn
  6493  	ctx := testContext2(t, &ContextOpts{
  6494  		Module: m,
  6495  		Providers: map[string]ResourceProviderFactory{
  6496  			"aws": testProviderFuncFixed(p),
  6497  		},
  6498  		State: &State{
  6499  			Modules: []*ModuleState{
  6500  				&ModuleState{
  6501  					Path: rootModulePath,
  6502  					Resources: map[string]*ResourceState{
  6503  						"aws_instance.foo": resourceState("aws_instance", "i-bcd345"),
  6504  						"aws_instance.bar": resourceState("aws_instance", "i-abc123"),
  6505  					},
  6506  				},
  6507  			},
  6508  		},
  6509  		Targets: []string{"aws_instance.foo"},
  6510  		Destroy: true,
  6511  	})
  6512  
  6513  	if _, err := ctx.Plan(); err != nil {
  6514  		t.Fatalf("err: %s", err)
  6515  	}
  6516  
  6517  	state, err := ctx.Apply()
  6518  	if err != nil {
  6519  		t.Fatalf("err: %s", err)
  6520  	}
  6521  
  6522  	mod := state.RootModule()
  6523  	if len(mod.Resources) != 1 {
  6524  		t.Fatalf("expected 1 resource, got: %#v", mod.Resources)
  6525  	}
  6526  
  6527  	checkStateString(t, state, `
  6528  aws_instance.bar:
  6529    ID = i-abc123
  6530  	`)
  6531  }
  6532  
  6533  func TestContext2Apply_targetedDestroyCountDeps(t *testing.T) {
  6534  	m := testModule(t, "apply-destroy-targeted-count")
  6535  	p := testProvider("aws")
  6536  	p.ApplyFn = testApplyFn
  6537  	p.DiffFn = testDiffFn
  6538  	ctx := testContext2(t, &ContextOpts{
  6539  		Module: m,
  6540  		Providers: map[string]ResourceProviderFactory{
  6541  			"aws": testProviderFuncFixed(p),
  6542  		},
  6543  		State: &State{
  6544  			Modules: []*ModuleState{
  6545  				&ModuleState{
  6546  					Path: rootModulePath,
  6547  					Resources: map[string]*ResourceState{
  6548  						"aws_instance.foo": resourceState("aws_instance", "i-bcd345"),
  6549  						"aws_instance.bar": resourceState("aws_instance", "i-abc123"),
  6550  					},
  6551  				},
  6552  			},
  6553  		},
  6554  		Targets: []string{"aws_instance.foo"},
  6555  		Destroy: true,
  6556  	})
  6557  
  6558  	if _, err := ctx.Plan(); err != nil {
  6559  		t.Fatalf("err: %s", err)
  6560  	}
  6561  
  6562  	state, err := ctx.Apply()
  6563  	if err != nil {
  6564  		t.Fatalf("err: %s", err)
  6565  	}
  6566  
  6567  	checkStateString(t, state, `<no state>`)
  6568  }
  6569  
  6570  // https://github.com/hashicorp/terraform/issues/4462
  6571  func TestContext2Apply_targetedDestroyModule(t *testing.T) {
  6572  	m := testModule(t, "apply-targeted-module")
  6573  	p := testProvider("aws")
  6574  	p.ApplyFn = testApplyFn
  6575  	p.DiffFn = testDiffFn
  6576  	ctx := testContext2(t, &ContextOpts{
  6577  		Module: m,
  6578  		Providers: map[string]ResourceProviderFactory{
  6579  			"aws": testProviderFuncFixed(p),
  6580  		},
  6581  		State: &State{
  6582  			Modules: []*ModuleState{
  6583  				&ModuleState{
  6584  					Path: rootModulePath,
  6585  					Resources: map[string]*ResourceState{
  6586  						"aws_instance.foo": resourceState("aws_instance", "i-bcd345"),
  6587  						"aws_instance.bar": resourceState("aws_instance", "i-abc123"),
  6588  					},
  6589  				},
  6590  				&ModuleState{
  6591  					Path: []string{"root", "child"},
  6592  					Resources: map[string]*ResourceState{
  6593  						"aws_instance.foo": resourceState("aws_instance", "i-bcd345"),
  6594  						"aws_instance.bar": resourceState("aws_instance", "i-abc123"),
  6595  					},
  6596  				},
  6597  			},
  6598  		},
  6599  		Targets: []string{"module.child.aws_instance.foo"},
  6600  		Destroy: true,
  6601  	})
  6602  
  6603  	if _, err := ctx.Plan(); err != nil {
  6604  		t.Fatalf("err: %s", err)
  6605  	}
  6606  
  6607  	state, err := ctx.Apply()
  6608  	if err != nil {
  6609  		t.Fatalf("err: %s", err)
  6610  	}
  6611  
  6612  	checkStateString(t, state, `
  6613  aws_instance.bar:
  6614    ID = i-abc123
  6615  aws_instance.foo:
  6616    ID = i-bcd345
  6617  
  6618  module.child:
  6619    aws_instance.bar:
  6620      ID = i-abc123
  6621  	`)
  6622  }
  6623  
  6624  func TestContext2Apply_targetedDestroyCountIndex(t *testing.T) {
  6625  	m := testModule(t, "apply-targeted-count")
  6626  	p := testProvider("aws")
  6627  	p.ApplyFn = testApplyFn
  6628  	p.DiffFn = testDiffFn
  6629  	ctx := testContext2(t, &ContextOpts{
  6630  		Module: m,
  6631  		Providers: map[string]ResourceProviderFactory{
  6632  			"aws": testProviderFuncFixed(p),
  6633  		},
  6634  		State: &State{
  6635  			Modules: []*ModuleState{
  6636  				&ModuleState{
  6637  					Path: rootModulePath,
  6638  					Resources: map[string]*ResourceState{
  6639  						"aws_instance.foo.0": resourceState("aws_instance", "i-bcd345"),
  6640  						"aws_instance.foo.1": resourceState("aws_instance", "i-bcd345"),
  6641  						"aws_instance.foo.2": resourceState("aws_instance", "i-bcd345"),
  6642  						"aws_instance.bar.0": resourceState("aws_instance", "i-abc123"),
  6643  						"aws_instance.bar.1": resourceState("aws_instance", "i-abc123"),
  6644  						"aws_instance.bar.2": resourceState("aws_instance", "i-abc123"),
  6645  					},
  6646  				},
  6647  			},
  6648  		},
  6649  		Targets: []string{
  6650  			"aws_instance.foo[2]",
  6651  			"aws_instance.bar[1]",
  6652  		},
  6653  		Destroy: true,
  6654  	})
  6655  
  6656  	if _, err := ctx.Plan(); err != nil {
  6657  		t.Fatalf("err: %s", err)
  6658  	}
  6659  
  6660  	state, err := ctx.Apply()
  6661  	if err != nil {
  6662  		t.Fatalf("err: %s", err)
  6663  	}
  6664  
  6665  	checkStateString(t, state, `
  6666  aws_instance.bar.0:
  6667    ID = i-abc123
  6668  aws_instance.bar.2:
  6669    ID = i-abc123
  6670  aws_instance.foo.0:
  6671    ID = i-bcd345
  6672  aws_instance.foo.1:
  6673    ID = i-bcd345
  6674  	`)
  6675  }
  6676  
  6677  func TestContext2Apply_targetedModule(t *testing.T) {
  6678  	m := testModule(t, "apply-targeted-module")
  6679  	p := testProvider("aws")
  6680  	p.ApplyFn = testApplyFn
  6681  	p.DiffFn = testDiffFn
  6682  	ctx := testContext2(t, &ContextOpts{
  6683  		Module: m,
  6684  		Providers: map[string]ResourceProviderFactory{
  6685  			"aws": testProviderFuncFixed(p),
  6686  		},
  6687  		Targets: []string{"module.child"},
  6688  	})
  6689  
  6690  	if _, err := ctx.Plan(); err != nil {
  6691  		t.Fatalf("err: %s", err)
  6692  	}
  6693  
  6694  	state, err := ctx.Apply()
  6695  	if err != nil {
  6696  		t.Fatalf("err: %s", err)
  6697  	}
  6698  
  6699  	mod := state.ModuleByPath([]string{"root", "child"})
  6700  	if mod == nil {
  6701  		t.Fatalf("no child module found in the state!\n\n%#v", state)
  6702  	}
  6703  	if len(mod.Resources) != 2 {
  6704  		t.Fatalf("expected 2 resources, got: %#v", mod.Resources)
  6705  	}
  6706  
  6707  	checkStateString(t, state, `
  6708  <no state>
  6709  module.child:
  6710    aws_instance.bar:
  6711      ID = foo
  6712      num = 2
  6713      type = aws_instance
  6714    aws_instance.foo:
  6715      ID = foo
  6716      num = 2
  6717      type = aws_instance
  6718  	`)
  6719  }
  6720  
  6721  // GH-1858
  6722  func TestContext2Apply_targetedModuleDep(t *testing.T) {
  6723  	m := testModule(t, "apply-targeted-module-dep")
  6724  	p := testProvider("aws")
  6725  	p.ApplyFn = testApplyFn
  6726  	p.DiffFn = testDiffFn
  6727  	ctx := testContext2(t, &ContextOpts{
  6728  		Module: m,
  6729  		Providers: map[string]ResourceProviderFactory{
  6730  			"aws": testProviderFuncFixed(p),
  6731  		},
  6732  		Targets: []string{"aws_instance.foo"},
  6733  	})
  6734  
  6735  	if p, err := ctx.Plan(); err != nil {
  6736  		t.Fatalf("err: %s", err)
  6737  	} else {
  6738  		t.Logf("Diff: %s", p)
  6739  	}
  6740  
  6741  	state, err := ctx.Apply()
  6742  	if err != nil {
  6743  		t.Fatalf("err: %s", err)
  6744  	}
  6745  
  6746  	checkStateString(t, state, `
  6747  aws_instance.foo:
  6748    ID = foo
  6749    foo = foo
  6750    type = aws_instance
  6751  
  6752    Dependencies:
  6753      module.child
  6754  
  6755  module.child:
  6756    aws_instance.mod:
  6757      ID = foo
  6758  
  6759    Outputs:
  6760  
  6761    output = foo
  6762  	`)
  6763  }
  6764  
  6765  func TestContext2Apply_targetedModuleResource(t *testing.T) {
  6766  	m := testModule(t, "apply-targeted-module-resource")
  6767  	p := testProvider("aws")
  6768  	p.ApplyFn = testApplyFn
  6769  	p.DiffFn = testDiffFn
  6770  	ctx := testContext2(t, &ContextOpts{
  6771  		Module: m,
  6772  		Providers: map[string]ResourceProviderFactory{
  6773  			"aws": testProviderFuncFixed(p),
  6774  		},
  6775  		Targets: []string{"module.child.aws_instance.foo"},
  6776  	})
  6777  
  6778  	if _, err := ctx.Plan(); err != nil {
  6779  		t.Fatalf("err: %s", err)
  6780  	}
  6781  
  6782  	state, err := ctx.Apply()
  6783  	if err != nil {
  6784  		t.Fatalf("err: %s", err)
  6785  	}
  6786  
  6787  	mod := state.ModuleByPath([]string{"root", "child"})
  6788  	if mod == nil || len(mod.Resources) != 1 {
  6789  		t.Fatalf("expected 1 resource, got: %#v", mod)
  6790  	}
  6791  
  6792  	checkStateString(t, state, `
  6793  <no state>
  6794  module.child:
  6795    aws_instance.foo:
  6796      ID = foo
  6797      num = 2
  6798      type = aws_instance
  6799  	`)
  6800  }
  6801  
  6802  func TestContext2Apply_unknownAttribute(t *testing.T) {
  6803  	m := testModule(t, "apply-unknown")
  6804  	p := testProvider("aws")
  6805  	p.ApplyFn = testApplyFn
  6806  	p.DiffFn = testDiffFn
  6807  	ctx := testContext2(t, &ContextOpts{
  6808  		Module: m,
  6809  		Providers: map[string]ResourceProviderFactory{
  6810  			"aws": testProviderFuncFixed(p),
  6811  		},
  6812  	})
  6813  
  6814  	if _, err := ctx.Plan(); err != nil {
  6815  		t.Fatalf("err: %s", err)
  6816  	}
  6817  
  6818  	state, err := ctx.Apply()
  6819  	if err == nil {
  6820  		t.Fatal("should error")
  6821  	}
  6822  
  6823  	actual := strings.TrimSpace(state.String())
  6824  	expected := strings.TrimSpace(testTerraformApplyUnknownAttrStr)
  6825  	if actual != expected {
  6826  		t.Fatalf("bad: \n%s", actual)
  6827  	}
  6828  }
  6829  
  6830  func TestContext2Apply_unknownAttributeInterpolate(t *testing.T) {
  6831  	m := testModule(t, "apply-unknown-interpolate")
  6832  	p := testProvider("aws")
  6833  	p.ApplyFn = testApplyFn
  6834  	p.DiffFn = testDiffFn
  6835  	ctx := testContext2(t, &ContextOpts{
  6836  		Module: m,
  6837  		Providers: map[string]ResourceProviderFactory{
  6838  			"aws": testProviderFuncFixed(p),
  6839  		},
  6840  	})
  6841  
  6842  	if _, err := ctx.Plan(); err == nil {
  6843  		t.Fatal("should error")
  6844  	}
  6845  }
  6846  
  6847  func TestContext2Apply_vars(t *testing.T) {
  6848  	m := testModule(t, "apply-vars")
  6849  	p := testProvider("aws")
  6850  	p.ApplyFn = testApplyFn
  6851  	p.DiffFn = testDiffFn
  6852  	ctx := testContext2(t, &ContextOpts{
  6853  		Module: m,
  6854  		Providers: map[string]ResourceProviderFactory{
  6855  			"aws": testProviderFuncFixed(p),
  6856  		},
  6857  		Variables: map[string]interface{}{
  6858  			"foo":       "us-west-2",
  6859  			"test_list": []interface{}{"Hello", "World"},
  6860  			"test_map": map[string]interface{}{
  6861  				"Hello": "World",
  6862  				"Foo":   "Bar",
  6863  				"Baz":   "Foo",
  6864  			},
  6865  			"amis": []map[string]interface{}{
  6866  				map[string]interface{}{
  6867  					"us-east-1": "override",
  6868  				},
  6869  			},
  6870  		},
  6871  	})
  6872  
  6873  	w, e := ctx.Validate()
  6874  	if len(w) > 0 {
  6875  		t.Fatalf("bad: %#v", w)
  6876  	}
  6877  	if len(e) > 0 {
  6878  		t.Fatalf("bad: %s", e)
  6879  	}
  6880  
  6881  	if _, err := ctx.Plan(); err != nil {
  6882  		t.Fatalf("err: %s", err)
  6883  	}
  6884  
  6885  	state, err := ctx.Apply()
  6886  	if err != nil {
  6887  		t.Fatalf("err: %s", err)
  6888  	}
  6889  
  6890  	actual := strings.TrimSpace(state.String())
  6891  	expected := strings.TrimSpace(testTerraformApplyVarsStr)
  6892  	if actual != expected {
  6893  		t.Fatalf("expected: %s\n got:\n%s", expected, actual)
  6894  	}
  6895  }
  6896  
  6897  func TestContext2Apply_varsEnv(t *testing.T) {
  6898  	// Set the env var
  6899  	defer tempEnv(t, "TF_VAR_ami", "baz")()
  6900  	defer tempEnv(t, "TF_VAR_list", `["Hello", "World"]`)()
  6901  	defer tempEnv(t, "TF_VAR_map", `{"Hello" = "World", "Foo" = "Bar", "Baz" = "Foo"}`)()
  6902  
  6903  	m := testModule(t, "apply-vars-env")
  6904  	p := testProvider("aws")
  6905  	p.ApplyFn = testApplyFn
  6906  	p.DiffFn = testDiffFn
  6907  	ctx := testContext2(t, &ContextOpts{
  6908  		Module: m,
  6909  		Providers: map[string]ResourceProviderFactory{
  6910  			"aws": testProviderFuncFixed(p),
  6911  		},
  6912  	})
  6913  
  6914  	w, e := ctx.Validate()
  6915  	if len(w) > 0 {
  6916  		t.Fatalf("bad: %#v", w)
  6917  	}
  6918  	if len(e) > 0 {
  6919  		t.Fatalf("bad: %s", e)
  6920  	}
  6921  
  6922  	if _, err := ctx.Plan(); err != nil {
  6923  		t.Fatalf("err: %s", err)
  6924  	}
  6925  
  6926  	state, err := ctx.Apply()
  6927  	if err != nil {
  6928  		t.Fatalf("err: %s", err)
  6929  	}
  6930  
  6931  	actual := strings.TrimSpace(state.String())
  6932  	expected := strings.TrimSpace(testTerraformApplyVarsEnvStr)
  6933  	if actual != expected {
  6934  		t.Fatalf("bad: \n%s", actual)
  6935  	}
  6936  }
  6937  
  6938  func TestContext2Apply_createBefore_depends(t *testing.T) {
  6939  	m := testModule(t, "apply-depends-create-before")
  6940  	h := new(HookRecordApplyOrder)
  6941  	p := testProvider("aws")
  6942  	p.ApplyFn = testApplyFn
  6943  	p.DiffFn = testDiffFn
  6944  	state := &State{
  6945  		Modules: []*ModuleState{
  6946  			&ModuleState{
  6947  				Path: rootModulePath,
  6948  				Resources: map[string]*ResourceState{
  6949  					"aws_instance.web": &ResourceState{
  6950  						Type: "aws_instance",
  6951  						Primary: &InstanceState{
  6952  							ID: "bar",
  6953  							Attributes: map[string]string{
  6954  								"require_new": "ami-old",
  6955  							},
  6956  						},
  6957  					},
  6958  					"aws_instance.lb": &ResourceState{
  6959  						Type: "aws_instance",
  6960  						Primary: &InstanceState{
  6961  							ID: "baz",
  6962  							Attributes: map[string]string{
  6963  								"instance": "bar",
  6964  							},
  6965  						},
  6966  					},
  6967  				},
  6968  			},
  6969  		},
  6970  	}
  6971  	ctx := testContext2(t, &ContextOpts{
  6972  		Module: m,
  6973  		Hooks:  []Hook{h},
  6974  		Providers: map[string]ResourceProviderFactory{
  6975  			"aws": testProviderFuncFixed(p),
  6976  		},
  6977  		State: state,
  6978  	})
  6979  
  6980  	if p, err := ctx.Plan(); err != nil {
  6981  		t.Fatalf("err: %s", err)
  6982  	} else {
  6983  		t.Logf("plan: %s", p)
  6984  	}
  6985  
  6986  	h.Active = true
  6987  	state, err := ctx.Apply()
  6988  	if err != nil {
  6989  		t.Fatalf("err: %s", err)
  6990  	}
  6991  
  6992  	mod := state.RootModule()
  6993  	if len(mod.Resources) < 2 {
  6994  		t.Fatalf("bad: %#v", mod.Resources)
  6995  	}
  6996  
  6997  	actual := strings.TrimSpace(state.String())
  6998  	expected := strings.TrimSpace(testTerraformApplyDependsCreateBeforeStr)
  6999  	if actual != expected {
  7000  		t.Fatalf("bad: \n%s\n\n%s", actual, expected)
  7001  	}
  7002  
  7003  	// Test that things were managed _in the right order_
  7004  	order := h.States
  7005  	diffs := h.Diffs
  7006  	if order[0].ID != "" || diffs[0].Destroy {
  7007  		t.Fatalf("should create new instance first: %#v", order)
  7008  	}
  7009  
  7010  	if order[1].ID != "baz" {
  7011  		t.Fatalf("update must happen after create: %#v", order)
  7012  	}
  7013  
  7014  	if order[2].ID != "bar" || !diffs[2].Destroy {
  7015  		t.Fatalf("destroy must happen after update: %#v", order)
  7016  	}
  7017  }
  7018  
  7019  func TestContext2Apply_singleDestroy(t *testing.T) {
  7020  	m := testModule(t, "apply-depends-create-before")
  7021  	h := new(HookRecordApplyOrder)
  7022  	p := testProvider("aws")
  7023  
  7024  	invokeCount := 0
  7025  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  7026  		invokeCount++
  7027  		switch invokeCount {
  7028  		case 1:
  7029  			if d.Destroy {
  7030  				t.Fatalf("should not destroy")
  7031  			}
  7032  			if s.ID != "" {
  7033  				t.Fatalf("should not have ID")
  7034  			}
  7035  		case 2:
  7036  			if d.Destroy {
  7037  				t.Fatalf("should not destroy")
  7038  			}
  7039  			if s.ID != "baz" {
  7040  				t.Fatalf("should have id")
  7041  			}
  7042  		case 3:
  7043  			if !d.Destroy {
  7044  				t.Fatalf("should destroy")
  7045  			}
  7046  			if s.ID == "" {
  7047  				t.Fatalf("should have ID")
  7048  			}
  7049  		default:
  7050  			t.Fatalf("bad invoke count %d", invokeCount)
  7051  		}
  7052  		return testApplyFn(info, s, d)
  7053  	}
  7054  	p.DiffFn = testDiffFn
  7055  	state := &State{
  7056  		Modules: []*ModuleState{
  7057  			&ModuleState{
  7058  				Path: rootModulePath,
  7059  				Resources: map[string]*ResourceState{
  7060  					"aws_instance.web": &ResourceState{
  7061  						Type: "aws_instance",
  7062  						Primary: &InstanceState{
  7063  							ID: "bar",
  7064  							Attributes: map[string]string{
  7065  								"require_new": "ami-old",
  7066  							},
  7067  						},
  7068  					},
  7069  					"aws_instance.lb": &ResourceState{
  7070  						Type: "aws_instance",
  7071  						Primary: &InstanceState{
  7072  							ID: "baz",
  7073  							Attributes: map[string]string{
  7074  								"instance": "bar",
  7075  							},
  7076  						},
  7077  					},
  7078  				},
  7079  			},
  7080  		},
  7081  	}
  7082  	ctx := testContext2(t, &ContextOpts{
  7083  		Module: m,
  7084  		Hooks:  []Hook{h},
  7085  		Providers: map[string]ResourceProviderFactory{
  7086  			"aws": testProviderFuncFixed(p),
  7087  		},
  7088  		State: state,
  7089  	})
  7090  
  7091  	if _, err := ctx.Plan(); err != nil {
  7092  		t.Fatalf("err: %s", err)
  7093  	}
  7094  
  7095  	h.Active = true
  7096  	state, err := ctx.Apply()
  7097  	if err != nil {
  7098  		t.Fatalf("err: %s", err)
  7099  	}
  7100  
  7101  	if invokeCount != 3 {
  7102  		t.Fatalf("bad: %d", invokeCount)
  7103  	}
  7104  }
  7105  
  7106  // GH-7824
  7107  func TestContext2Apply_issue7824(t *testing.T) {
  7108  	p := testProvider("template")
  7109  	p.ResourcesReturn = append(p.ResourcesReturn, ResourceType{
  7110  		Name: "template_file",
  7111  	})
  7112  
  7113  	p.ApplyFn = testApplyFn
  7114  	p.DiffFn = testDiffFn
  7115  
  7116  	// Apply cleanly step 0
  7117  	ctx := testContext2(t, &ContextOpts{
  7118  		Module: testModule(t, "issue-7824"),
  7119  		Providers: map[string]ResourceProviderFactory{
  7120  			"template": testProviderFuncFixed(p),
  7121  		},
  7122  	})
  7123  
  7124  	plan, err := ctx.Plan()
  7125  	if err != nil {
  7126  		t.Fatalf("err: %s", err)
  7127  	}
  7128  
  7129  	// Write / Read plan to simulate running it through a Plan file
  7130  	var buf bytes.Buffer
  7131  	if err := WritePlan(plan, &buf); err != nil {
  7132  		t.Fatalf("err: %s", err)
  7133  	}
  7134  
  7135  	planFromFile, err := ReadPlan(&buf)
  7136  	if err != nil {
  7137  		t.Fatalf("err: %s", err)
  7138  	}
  7139  
  7140  	ctx, err = planFromFile.Context(&ContextOpts{
  7141  		Providers: map[string]ResourceProviderFactory{
  7142  			"template": testProviderFuncFixed(p),
  7143  		},
  7144  	})
  7145  	if err != nil {
  7146  		t.Fatalf("err: %s", err)
  7147  	}
  7148  
  7149  	_, err = ctx.Apply()
  7150  	if err != nil {
  7151  		t.Fatalf("err: %s", err)
  7152  	}
  7153  }
  7154  
  7155  // GH-5254
  7156  func TestContext2Apply_issue5254(t *testing.T) {
  7157  	// Create a provider. We use "template" here just to match the repro
  7158  	// we got from the issue itself.
  7159  	p := testProvider("template")
  7160  	p.ResourcesReturn = append(p.ResourcesReturn, ResourceType{
  7161  		Name: "template_file",
  7162  	})
  7163  
  7164  	p.ApplyFn = testApplyFn
  7165  	p.DiffFn = testDiffFn
  7166  
  7167  	// Apply cleanly step 0
  7168  	ctx := testContext2(t, &ContextOpts{
  7169  		Module: testModule(t, "issue-5254/step-0"),
  7170  		Providers: map[string]ResourceProviderFactory{
  7171  			"template": testProviderFuncFixed(p),
  7172  		},
  7173  	})
  7174  
  7175  	plan, err := ctx.Plan()
  7176  	if err != nil {
  7177  		t.Fatalf("err: %s", err)
  7178  	}
  7179  
  7180  	state, err := ctx.Apply()
  7181  	if err != nil {
  7182  		t.Fatalf("err: %s", err)
  7183  	}
  7184  
  7185  	// Application success. Now make the modification and store a plan
  7186  	ctx = testContext2(t, &ContextOpts{
  7187  		Module: testModule(t, "issue-5254/step-1"),
  7188  		State:  state,
  7189  		Providers: map[string]ResourceProviderFactory{
  7190  			"template": testProviderFuncFixed(p),
  7191  		},
  7192  	})
  7193  
  7194  	plan, err = ctx.Plan()
  7195  	if err != nil {
  7196  		t.Fatalf("err: %s", err)
  7197  	}
  7198  
  7199  	// Write / Read plan to simulate running it through a Plan file
  7200  	var buf bytes.Buffer
  7201  	if err := WritePlan(plan, &buf); err != nil {
  7202  		t.Fatalf("err: %s", err)
  7203  	}
  7204  
  7205  	planFromFile, err := ReadPlan(&buf)
  7206  	if err != nil {
  7207  		t.Fatalf("err: %s", err)
  7208  	}
  7209  
  7210  	ctx, err = planFromFile.Context(&ContextOpts{
  7211  		Providers: map[string]ResourceProviderFactory{
  7212  			"template": testProviderFuncFixed(p),
  7213  		},
  7214  	})
  7215  	if err != nil {
  7216  		t.Fatalf("err: %s", err)
  7217  	}
  7218  
  7219  	state, err = ctx.Apply()
  7220  	if err != nil {
  7221  		t.Fatalf("err: %s", err)
  7222  	}
  7223  
  7224  	actual := strings.TrimSpace(state.String())
  7225  	expected := strings.TrimSpace(`
  7226  template_file.child:
  7227    ID = foo
  7228    template = Hi
  7229    type = template_file
  7230  
  7231    Dependencies:
  7232      template_file.parent
  7233  template_file.parent:
  7234    ID = foo
  7235    template = Hi
  7236    type = template_file
  7237  		`)
  7238  	if actual != expected {
  7239  		t.Fatalf("expected state: \n%s\ngot: \n%s", expected, actual)
  7240  	}
  7241  }
  7242  
  7243  func TestContext2Apply_targetedWithTaintedInState(t *testing.T) {
  7244  	p := testProvider("aws")
  7245  	p.DiffFn = testDiffFn
  7246  	p.ApplyFn = testApplyFn
  7247  	ctx := testContext2(t, &ContextOpts{
  7248  		Module: testModule(t, "apply-tainted-targets"),
  7249  		Providers: map[string]ResourceProviderFactory{
  7250  			"aws": testProviderFuncFixed(p),
  7251  		},
  7252  		Targets: []string{"aws_instance.iambeingadded"},
  7253  		State: &State{
  7254  			Modules: []*ModuleState{
  7255  				&ModuleState{
  7256  					Path: rootModulePath,
  7257  					Resources: map[string]*ResourceState{
  7258  						"aws_instance.ifailedprovisioners": &ResourceState{
  7259  							Primary: &InstanceState{
  7260  								ID:      "ifailedprovisioners",
  7261  								Tainted: true,
  7262  							},
  7263  						},
  7264  					},
  7265  				},
  7266  			},
  7267  		},
  7268  	})
  7269  
  7270  	plan, err := ctx.Plan()
  7271  	if err != nil {
  7272  		t.Fatalf("err: %s", err)
  7273  	}
  7274  
  7275  	// Write / Read plan to simulate running it through a Plan file
  7276  	var buf bytes.Buffer
  7277  	if err := WritePlan(plan, &buf); err != nil {
  7278  		t.Fatalf("err: %s", err)
  7279  	}
  7280  
  7281  	planFromFile, err := ReadPlan(&buf)
  7282  	if err != nil {
  7283  		t.Fatalf("err: %s", err)
  7284  	}
  7285  
  7286  	ctx, err = planFromFile.Context(&ContextOpts{
  7287  		Module: testModule(t, "apply-tainted-targets"),
  7288  		Providers: map[string]ResourceProviderFactory{
  7289  			"aws": testProviderFuncFixed(p),
  7290  		},
  7291  	})
  7292  	if err != nil {
  7293  		t.Fatalf("err: %s", err)
  7294  	}
  7295  
  7296  	state, err := ctx.Apply()
  7297  	if err != nil {
  7298  		t.Fatalf("err: %s", err)
  7299  	}
  7300  
  7301  	actual := strings.TrimSpace(state.String())
  7302  	expected := strings.TrimSpace(`
  7303  aws_instance.iambeingadded:
  7304    ID = foo
  7305  aws_instance.ifailedprovisioners: (tainted)
  7306    ID = ifailedprovisioners
  7307  		`)
  7308  	if actual != expected {
  7309  		t.Fatalf("expected state: \n%s\ngot: \n%s", expected, actual)
  7310  	}
  7311  }
  7312  
  7313  // Higher level test exposing the bug this covers in
  7314  // TestResource_ignoreChangesRequired
  7315  func TestContext2Apply_ignoreChangesCreate(t *testing.T) {
  7316  	m := testModule(t, "apply-ignore-changes-create")
  7317  	p := testProvider("aws")
  7318  	p.ApplyFn = testApplyFn
  7319  	p.DiffFn = testDiffFn
  7320  	ctx := testContext2(t, &ContextOpts{
  7321  		Module: m,
  7322  		Providers: map[string]ResourceProviderFactory{
  7323  			"aws": testProviderFuncFixed(p),
  7324  		},
  7325  	})
  7326  
  7327  	if p, err := ctx.Plan(); err != nil {
  7328  		t.Fatalf("err: %s", err)
  7329  	} else {
  7330  		t.Logf(p.String())
  7331  	}
  7332  
  7333  	state, err := ctx.Apply()
  7334  	if err != nil {
  7335  		t.Fatalf("err: %s", err)
  7336  	}
  7337  
  7338  	mod := state.RootModule()
  7339  	if len(mod.Resources) != 1 {
  7340  		t.Fatalf("bad: %s", state)
  7341  	}
  7342  
  7343  	actual := strings.TrimSpace(state.String())
  7344  	// Expect no changes from original state
  7345  	expected := strings.TrimSpace(`
  7346  aws_instance.foo:
  7347    ID = foo
  7348    required_field = set
  7349    type = aws_instance
  7350  `)
  7351  	if actual != expected {
  7352  		t.Fatalf("expected:\n%s\ngot:\n%s", expected, actual)
  7353  	}
  7354  }
  7355  
  7356  func TestContext2Apply_ignoreChangesWithDep(t *testing.T) {
  7357  	m := testModule(t, "apply-ignore-changes-dep")
  7358  	p := testProvider("aws")
  7359  	p.ApplyFn = testApplyFn
  7360  	p.DiffFn = func(i *InstanceInfo, s *InstanceState, c *ResourceConfig) (*InstanceDiff, error) {
  7361  		switch i.Type {
  7362  		case "aws_instance":
  7363  			newAmi, _ := c.Get("ami")
  7364  			return &InstanceDiff{
  7365  				Attributes: map[string]*ResourceAttrDiff{
  7366  					"ami": &ResourceAttrDiff{
  7367  						Old:         s.Attributes["ami"],
  7368  						New:         newAmi.(string),
  7369  						RequiresNew: true,
  7370  					},
  7371  				},
  7372  			}, nil
  7373  		case "aws_eip":
  7374  			return testDiffFn(i, s, c)
  7375  		default:
  7376  			t.Fatalf("Unexpected type: %s", i.Type)
  7377  			return nil, nil
  7378  		}
  7379  	}
  7380  	s := &State{
  7381  		Modules: []*ModuleState{
  7382  			&ModuleState{
  7383  				Path: rootModulePath,
  7384  				Resources: map[string]*ResourceState{
  7385  					"aws_instance.foo.0": &ResourceState{
  7386  						Primary: &InstanceState{
  7387  							ID: "i-abc123",
  7388  							Attributes: map[string]string{
  7389  								"ami": "ami-abcd1234",
  7390  								"id":  "i-abc123",
  7391  							},
  7392  						},
  7393  					},
  7394  					"aws_instance.foo.1": &ResourceState{
  7395  						Primary: &InstanceState{
  7396  							ID: "i-bcd234",
  7397  							Attributes: map[string]string{
  7398  								"ami": "ami-abcd1234",
  7399  								"id":  "i-bcd234",
  7400  							},
  7401  						},
  7402  					},
  7403  					"aws_eip.foo.0": &ResourceState{
  7404  						Primary: &InstanceState{
  7405  							ID: "eip-abc123",
  7406  							Attributes: map[string]string{
  7407  								"id":       "eip-abc123",
  7408  								"instance": "i-abc123",
  7409  							},
  7410  						},
  7411  					},
  7412  					"aws_eip.foo.1": &ResourceState{
  7413  						Primary: &InstanceState{
  7414  							ID: "eip-bcd234",
  7415  							Attributes: map[string]string{
  7416  								"id":       "eip-bcd234",
  7417  								"instance": "i-bcd234",
  7418  							},
  7419  						},
  7420  					},
  7421  				},
  7422  			},
  7423  		},
  7424  	}
  7425  	ctx := testContext2(t, &ContextOpts{
  7426  		Module: m,
  7427  		Providers: map[string]ResourceProviderFactory{
  7428  			"aws": testProviderFuncFixed(p),
  7429  		},
  7430  		State: s,
  7431  	})
  7432  
  7433  	if p, err := ctx.Plan(); err != nil {
  7434  		t.Fatalf("err: %s", err)
  7435  	} else {
  7436  		t.Logf(p.String())
  7437  	}
  7438  
  7439  	state, err := ctx.Apply()
  7440  	if err != nil {
  7441  		t.Fatalf("err: %s", err)
  7442  	}
  7443  
  7444  	actual := strings.TrimSpace(state.String())
  7445  	expected := strings.TrimSpace(s.String())
  7446  	if actual != expected {
  7447  		t.Fatalf("bad: \n%s", actual)
  7448  	}
  7449  }
  7450  
  7451  func TestContext2Apply_ignoreChangesWildcard(t *testing.T) {
  7452  	m := testModule(t, "apply-ignore-changes-wildcard")
  7453  	p := testProvider("aws")
  7454  	p.ApplyFn = testApplyFn
  7455  	p.DiffFn = testDiffFn
  7456  	ctx := testContext2(t, &ContextOpts{
  7457  		Module: m,
  7458  		Providers: map[string]ResourceProviderFactory{
  7459  			"aws": testProviderFuncFixed(p),
  7460  		},
  7461  	})
  7462  
  7463  	if p, err := ctx.Plan(); err != nil {
  7464  		t.Fatalf("err: %s", err)
  7465  	} else {
  7466  		t.Logf(p.String())
  7467  	}
  7468  
  7469  	state, err := ctx.Apply()
  7470  	if err != nil {
  7471  		t.Fatalf("err: %s", err)
  7472  	}
  7473  
  7474  	mod := state.RootModule()
  7475  	if len(mod.Resources) != 1 {
  7476  		t.Fatalf("bad: %s", state)
  7477  	}
  7478  
  7479  	actual := strings.TrimSpace(state.String())
  7480  	// Expect no changes from original state
  7481  	expected := strings.TrimSpace(`
  7482  aws_instance.foo:
  7483    ID = foo
  7484    required_field = set
  7485    type = aws_instance
  7486  `)
  7487  	if actual != expected {
  7488  		t.Fatalf("expected:\n%s\ngot:\n%s", expected, actual)
  7489  	}
  7490  }
  7491  
  7492  // https://github.com/hashicorp/terraform/issues/7378
  7493  func TestContext2Apply_destroyNestedModuleWithAttrsReferencingResource(t *testing.T) {
  7494  	m := testModule(t, "apply-destroy-nested-module-with-attrs")
  7495  	p := testProvider("null")
  7496  	p.ApplyFn = testApplyFn
  7497  	p.DiffFn = testDiffFn
  7498  
  7499  	var state *State
  7500  	var err error
  7501  	{
  7502  		ctx := testContext2(t, &ContextOpts{
  7503  			Module: m,
  7504  			Providers: map[string]ResourceProviderFactory{
  7505  				"null": testProviderFuncFixed(p),
  7506  			},
  7507  		})
  7508  
  7509  		// First plan and apply a create operation
  7510  		if _, err := ctx.Plan(); err != nil {
  7511  			t.Fatalf("plan err: %s", err)
  7512  		}
  7513  
  7514  		state, err = ctx.Apply()
  7515  		if err != nil {
  7516  			t.Fatalf("apply err: %s", err)
  7517  		}
  7518  	}
  7519  
  7520  	{
  7521  		ctx := testContext2(t, &ContextOpts{
  7522  			Destroy: true,
  7523  			Module:  m,
  7524  			State:   state,
  7525  			Providers: map[string]ResourceProviderFactory{
  7526  				"null": testProviderFuncFixed(p),
  7527  			},
  7528  		})
  7529  
  7530  		plan, err := ctx.Plan()
  7531  		if err != nil {
  7532  			t.Fatalf("destroy plan err: %s", err)
  7533  		}
  7534  
  7535  		var buf bytes.Buffer
  7536  		if err := WritePlan(plan, &buf); err != nil {
  7537  			t.Fatalf("plan write err: %s", err)
  7538  		}
  7539  
  7540  		planFromFile, err := ReadPlan(&buf)
  7541  		if err != nil {
  7542  			t.Fatalf("plan read err: %s", err)
  7543  		}
  7544  
  7545  		ctx, err = planFromFile.Context(&ContextOpts{
  7546  			Providers: map[string]ResourceProviderFactory{
  7547  				"null": testProviderFuncFixed(p),
  7548  			},
  7549  		})
  7550  		if err != nil {
  7551  			t.Fatalf("err: %s", err)
  7552  		}
  7553  
  7554  		state, err = ctx.Apply()
  7555  		if err != nil {
  7556  			t.Fatalf("destroy apply err: %s", err)
  7557  		}
  7558  	}
  7559  
  7560  	//Test that things were destroyed
  7561  	actual := strings.TrimSpace(state.String())
  7562  	expected := strings.TrimSpace(`
  7563  <no state>
  7564  module.middle:
  7565    <no state>
  7566  module.middle.bottom:
  7567    <no state>
  7568  		`)
  7569  	if actual != expected {
  7570  		t.Fatalf("expected: \n%s\n\nbad: \n%s", expected, actual)
  7571  	}
  7572  }
  7573  
  7574  // If a data source explicitly depends on another resource, it's because we need
  7575  // that resource to be applied first.
  7576  func TestContext2Apply_dataDependsOn(t *testing.T) {
  7577  	p := testProvider("null")
  7578  	m := testModule(t, "apply-data-depends-on")
  7579  
  7580  	ctx := testContext2(t, &ContextOpts{
  7581  		Module: m,
  7582  		Providers: map[string]ResourceProviderFactory{
  7583  			"null": testProviderFuncFixed(p),
  7584  		},
  7585  	})
  7586  
  7587  	// the "provisioner" here writes to this variable, because the intent is to
  7588  	// create a dependency which can't be viewed through the graph, and depends
  7589  	// solely on the configuration providing "depends_on"
  7590  	provisionerOutput := ""
  7591  
  7592  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  7593  		// the side effect of the resource being applied
  7594  		provisionerOutput = "APPLIED"
  7595  		return testApplyFn(info, s, d)
  7596  	}
  7597  
  7598  	p.DiffFn = testDiffFn
  7599  	p.ReadDataDiffFn = testDataDiffFn
  7600  
  7601  	p.ReadDataApplyFn = func(*InstanceInfo, *InstanceDiff) (*InstanceState, error) {
  7602  		// Read the artifact created by our dependency being applied.
  7603  		// Without any "depends_on", this would be skipped as it's assumed the
  7604  		// initial diff during refresh was all that's needed.
  7605  		return &InstanceState{
  7606  			ID: "read",
  7607  			Attributes: map[string]string{
  7608  				"foo": provisionerOutput,
  7609  			},
  7610  		}, nil
  7611  	}
  7612  
  7613  	_, err := ctx.Refresh()
  7614  	if err != nil {
  7615  		t.Fatalf("err: %s", err)
  7616  	}
  7617  
  7618  	if _, err := ctx.Plan(); err != nil {
  7619  		t.Fatalf("err: %s", err)
  7620  	}
  7621  
  7622  	state, err := ctx.Apply()
  7623  	if err != nil {
  7624  		t.Fatalf("err: %s", err)
  7625  	}
  7626  
  7627  	root := state.ModuleByPath(RootModulePath)
  7628  	actual := root.Resources["data.null_data_source.read"].Primary.Attributes["foo"]
  7629  
  7630  	expected := "APPLIED"
  7631  	if actual != expected {
  7632  		t.Fatalf("bad:\n%s", strings.TrimSpace(state.String()))
  7633  	}
  7634  }