github.com/ggriffiths/terraform@v0.9.0-beta1.0.20170222213024-79c4935604cb/terraform/context_apply_test.go (about)

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