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