github.com/IBM-Cloud/terraform@v0.6.4-0.20170726051544-8872b87621df/terraform/context_apply_test.go (about)

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