github.com/bpineau/terraform@v0.8.0-rc1.0.20161126184705-a8886012d185/terraform/context_apply_test.go (about)

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