github.com/rhenning/terraform@v0.8.0-beta2/terraform/context_apply_test.go (about)

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