github.com/danrjohnson/terraform@v0.7.0-rc2.0.20160627135212-d0fc1fa086ff/terraform/context_apply_test.go (about)

     1  package terraform
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"os"
     7  	"reflect"
     8  	"sort"
     9  	"strings"
    10  	"sync"
    11  	"sync/atomic"
    12  	"testing"
    13  	"time"
    14  
    15  	"github.com/hashicorp/terraform/config/module"
    16  )
    17  
    18  func TestContext2Apply(t *testing.T) {
    19  	m := testModule(t, "apply-good")
    20  	p := testProvider("aws")
    21  	p.ApplyFn = testApplyFn
    22  	p.DiffFn = testDiffFn
    23  	ctx := testContext2(t, &ContextOpts{
    24  		Module: m,
    25  		Providers: map[string]ResourceProviderFactory{
    26  			"aws": testProviderFuncFixed(p),
    27  		},
    28  	})
    29  
    30  	if _, err := ctx.Plan(); err != nil {
    31  		t.Fatalf("err: %s", err)
    32  	}
    33  
    34  	state, err := ctx.Apply()
    35  	if err != nil {
    36  		t.Fatalf("err: %s", err)
    37  	}
    38  
    39  	mod := state.RootModule()
    40  	if len(mod.Resources) < 2 {
    41  		t.Fatalf("bad: %#v", mod.Resources)
    42  	}
    43  
    44  	actual := strings.TrimSpace(state.String())
    45  	expected := strings.TrimSpace(testTerraformApplyStr)
    46  	if actual != expected {
    47  		t.Fatalf("bad: \n%s", actual)
    48  	}
    49  }
    50  
    51  func TestContext2Apply_resourceCountOneList(t *testing.T) {
    52  	m := testModule(t, "apply-resource-count-one-list")
    53  	p := testProvider("null")
    54  	p.ApplyFn = testApplyFn
    55  	p.DiffFn = testDiffFn
    56  	ctx := testContext2(t, &ContextOpts{
    57  		Module: m,
    58  		Providers: map[string]ResourceProviderFactory{
    59  			"null": testProviderFuncFixed(p),
    60  		},
    61  	})
    62  
    63  	if _, err := ctx.Plan(); err != nil {
    64  		t.Fatalf("err: %s", err)
    65  	}
    66  
    67  	state, err := ctx.Apply()
    68  	if err != nil {
    69  		t.Fatalf("err: %s", err)
    70  	}
    71  
    72  	actual := strings.TrimSpace(state.String())
    73  	expected := strings.TrimSpace(`null_resource.foo:
    74    ID = foo
    75  
    76  Outputs:
    77  
    78  test = [foo]`)
    79  	if actual != expected {
    80  		t.Fatalf("expected: \n%s\n\ngot: \n%s\n", expected, actual)
    81  	}
    82  }
    83  func TestContext2Apply_resourceCountZeroList(t *testing.T) {
    84  	m := testModule(t, "apply-resource-count-zero-list")
    85  	p := testProvider("null")
    86  	p.ApplyFn = testApplyFn
    87  	p.DiffFn = testDiffFn
    88  	ctx := testContext2(t, &ContextOpts{
    89  		Module: m,
    90  		Providers: map[string]ResourceProviderFactory{
    91  			"null": testProviderFuncFixed(p),
    92  		},
    93  	})
    94  
    95  	if _, err := ctx.Plan(); err != nil {
    96  		t.Fatalf("err: %s", err)
    97  	}
    98  
    99  	state, err := ctx.Apply()
   100  	if err != nil {
   101  		t.Fatalf("err: %s", err)
   102  	}
   103  
   104  	actual := strings.TrimSpace(state.String())
   105  	expected := strings.TrimSpace(`<no state>
   106  Outputs:
   107  
   108  test = []`)
   109  	if actual != expected {
   110  		t.Fatalf("expected: \n%s\n\ngot: \n%s\n", expected, actual)
   111  	}
   112  }
   113  
   114  func TestContext2Apply_mapVarBetweenModules(t *testing.T) {
   115  	m := testModule(t, "apply-map-var-through-module")
   116  	p := testProvider("null")
   117  	p.ApplyFn = testApplyFn
   118  	p.DiffFn = testDiffFn
   119  	ctx := testContext2(t, &ContextOpts{
   120  		Module: m,
   121  		Providers: map[string]ResourceProviderFactory{
   122  			"null": testProviderFuncFixed(p),
   123  		},
   124  	})
   125  
   126  	if _, err := ctx.Plan(); err != nil {
   127  		t.Fatalf("err: %s", err)
   128  	}
   129  
   130  	state, err := ctx.Apply()
   131  	if err != nil {
   132  		t.Fatalf("err: %s", err)
   133  	}
   134  
   135  	actual := strings.TrimSpace(state.String())
   136  	expected := strings.TrimSpace(`<no state>
   137  Outputs:
   138  
   139  amis_from_module = {eu-west-1:ami-789012 eu-west-2:ami-989484 us-west-1:ami-123456 us-west-2:ami-456789 }
   140  
   141  module.test:
   142    null_resource.noop:
   143      ID = foo
   144  
   145    Outputs:
   146  
   147    amis_out = {eu-west-1:ami-789012 eu-west-2:ami-989484 us-west-1:ami-123456 us-west-2:ami-456789 }`)
   148  	if actual != expected {
   149  		t.Fatalf("expected: \n%s\n\ngot: \n%s\n", expected, actual)
   150  	}
   151  }
   152  
   153  func TestContext2Apply_providerAlias(t *testing.T) {
   154  	m := testModule(t, "apply-provider-alias")
   155  	p := testProvider("aws")
   156  	p.ApplyFn = testApplyFn
   157  	p.DiffFn = testDiffFn
   158  	ctx := testContext2(t, &ContextOpts{
   159  		Module: m,
   160  		Providers: map[string]ResourceProviderFactory{
   161  			"aws": testProviderFuncFixed(p),
   162  		},
   163  	})
   164  
   165  	if _, err := ctx.Plan(); err != nil {
   166  		t.Fatalf("err: %s", err)
   167  	}
   168  
   169  	state, err := ctx.Apply()
   170  	if err != nil {
   171  		t.Fatalf("err: %s", err)
   172  	}
   173  
   174  	mod := state.RootModule()
   175  	if len(mod.Resources) < 2 {
   176  		t.Fatalf("bad: %#v", mod.Resources)
   177  	}
   178  
   179  	actual := strings.TrimSpace(state.String())
   180  	expected := strings.TrimSpace(testTerraformApplyProviderAliasStr)
   181  	if actual != expected {
   182  		t.Fatalf("bad: \n%s", actual)
   183  	}
   184  }
   185  
   186  // GH-2870
   187  func TestContext2Apply_providerWarning(t *testing.T) {
   188  	m := testModule(t, "apply-provider-warning")
   189  	p := testProvider("aws")
   190  	p.ApplyFn = testApplyFn
   191  	p.DiffFn = testDiffFn
   192  	p.ValidateFn = func(c *ResourceConfig) (ws []string, es []error) {
   193  		ws = append(ws, "Just a warning")
   194  		return
   195  	}
   196  	ctx := testContext2(t, &ContextOpts{
   197  		Module: m,
   198  		Providers: map[string]ResourceProviderFactory{
   199  			"aws": testProviderFuncFixed(p),
   200  		},
   201  	})
   202  
   203  	if _, err := ctx.Plan(); err != nil {
   204  		t.Fatalf("err: %s", err)
   205  	}
   206  
   207  	state, err := ctx.Apply()
   208  	if err != nil {
   209  		t.Fatalf("err: %s", err)
   210  	}
   211  
   212  	actual := strings.TrimSpace(state.String())
   213  	expected := strings.TrimSpace(`
   214  aws_instance.foo:
   215    ID = foo
   216  	`)
   217  	if actual != expected {
   218  		t.Fatalf("got: \n%s\n\nexpected:\n%s", actual, expected)
   219  	}
   220  
   221  	if !p.ConfigureCalled {
   222  		t.Fatalf("provider Configure() was never called!")
   223  	}
   224  }
   225  
   226  func TestContext2Apply_emptyModule(t *testing.T) {
   227  	m := testModule(t, "apply-empty-module")
   228  	p := testProvider("aws")
   229  	p.ApplyFn = testApplyFn
   230  	p.DiffFn = testDiffFn
   231  	ctx := testContext2(t, &ContextOpts{
   232  		Module: m,
   233  		Providers: map[string]ResourceProviderFactory{
   234  			"aws": testProviderFuncFixed(p),
   235  		},
   236  	})
   237  
   238  	if _, err := ctx.Plan(); err != nil {
   239  		t.Fatalf("err: %s", err)
   240  	}
   241  
   242  	state, err := ctx.Apply()
   243  	if err != nil {
   244  		t.Fatalf("err: %s", err)
   245  	}
   246  
   247  	actual := strings.TrimSpace(state.String())
   248  	actual = strings.Replace(actual, "  ", "", -1)
   249  	expected := strings.TrimSpace(testTerraformApplyEmptyModuleStr)
   250  	if actual != expected {
   251  		t.Fatalf("bad: \n%s\nexpect:\n%s", actual, expected)
   252  	}
   253  }
   254  
   255  func TestContext2Apply_createBeforeDestroy(t *testing.T) {
   256  	m := testModule(t, "apply-good-create-before")
   257  	p := testProvider("aws")
   258  	p.ApplyFn = testApplyFn
   259  	p.DiffFn = testDiffFn
   260  	state := &State{
   261  		Modules: []*ModuleState{
   262  			&ModuleState{
   263  				Path: rootModulePath,
   264  				Resources: map[string]*ResourceState{
   265  					"aws_instance.bar": &ResourceState{
   266  						Type: "aws_instance",
   267  						Primary: &InstanceState{
   268  							ID: "bar",
   269  							Attributes: map[string]string{
   270  								"require_new": "abc",
   271  							},
   272  						},
   273  					},
   274  				},
   275  			},
   276  		},
   277  	}
   278  	ctx := testContext2(t, &ContextOpts{
   279  		Module: m,
   280  		Providers: map[string]ResourceProviderFactory{
   281  			"aws": testProviderFuncFixed(p),
   282  		},
   283  		State: state,
   284  	})
   285  
   286  	if p, err := ctx.Plan(); err != nil {
   287  		t.Fatalf("err: %s", err)
   288  	} else {
   289  		t.Logf(p.String())
   290  	}
   291  
   292  	state, err := ctx.Apply()
   293  	if err != nil {
   294  		t.Fatalf("err: %s", err)
   295  	}
   296  
   297  	mod := state.RootModule()
   298  	if len(mod.Resources) != 1 {
   299  		t.Fatalf("bad: %s", state)
   300  	}
   301  
   302  	actual := strings.TrimSpace(state.String())
   303  	expected := strings.TrimSpace(testTerraformApplyCreateBeforeStr)
   304  	if actual != expected {
   305  		t.Fatalf("bad: \n%s", actual)
   306  	}
   307  }
   308  
   309  func TestContext2Apply_createBeforeDestroyUpdate(t *testing.T) {
   310  	m := testModule(t, "apply-good-create-before-update")
   311  	p := testProvider("aws")
   312  	p.ApplyFn = testApplyFn
   313  	p.DiffFn = testDiffFn
   314  	state := &State{
   315  		Modules: []*ModuleState{
   316  			&ModuleState{
   317  				Path: rootModulePath,
   318  				Resources: map[string]*ResourceState{
   319  					"aws_instance.bar": &ResourceState{
   320  						Type: "aws_instance",
   321  						Primary: &InstanceState{
   322  							ID: "bar",
   323  							Attributes: map[string]string{
   324  								"foo": "bar",
   325  							},
   326  						},
   327  					},
   328  				},
   329  			},
   330  		},
   331  	}
   332  	ctx := testContext2(t, &ContextOpts{
   333  		Module: m,
   334  		Providers: map[string]ResourceProviderFactory{
   335  			"aws": testProviderFuncFixed(p),
   336  		},
   337  		State: state,
   338  	})
   339  
   340  	if p, err := ctx.Plan(); err != nil {
   341  		t.Fatalf("err: %s", err)
   342  	} else {
   343  		t.Logf(p.String())
   344  	}
   345  
   346  	state, err := ctx.Apply()
   347  	if err != nil {
   348  		t.Fatalf("err: %s", err)
   349  	}
   350  
   351  	mod := state.RootModule()
   352  	if len(mod.Resources) != 1 {
   353  		t.Fatalf("bad: %s", state)
   354  	}
   355  
   356  	actual := strings.TrimSpace(state.String())
   357  	expected := strings.TrimSpace(testTerraformApplyCreateBeforeUpdateStr)
   358  	if actual != expected {
   359  		t.Fatalf("bad: \n%s", actual)
   360  	}
   361  }
   362  
   363  func TestContext2Apply_destroyComputed(t *testing.T) {
   364  	m := testModule(t, "apply-destroy-computed")
   365  	p := testProvider("aws")
   366  	p.ApplyFn = testApplyFn
   367  	p.DiffFn = testDiffFn
   368  	state := &State{
   369  		Modules: []*ModuleState{
   370  			&ModuleState{
   371  				Path: rootModulePath,
   372  				Resources: map[string]*ResourceState{
   373  					"aws_instance.foo": &ResourceState{
   374  						Type: "aws_instance",
   375  						Primary: &InstanceState{
   376  							ID: "foo",
   377  							Attributes: map[string]string{
   378  								"output": "value",
   379  							},
   380  						},
   381  					},
   382  				},
   383  			},
   384  		},
   385  	}
   386  	ctx := testContext2(t, &ContextOpts{
   387  		Module: m,
   388  		Providers: map[string]ResourceProviderFactory{
   389  			"aws": testProviderFuncFixed(p),
   390  		},
   391  		State:   state,
   392  		Destroy: true,
   393  	})
   394  
   395  	if p, err := ctx.Plan(); err != nil {
   396  		t.Fatalf("err: %s", err)
   397  	} else {
   398  		t.Logf(p.String())
   399  	}
   400  
   401  	if _, err := ctx.Apply(); err != nil {
   402  		t.Fatalf("err: %s", err)
   403  	}
   404  }
   405  
   406  func TestContext2Apply_destroyData(t *testing.T) {
   407  	m := testModule(t, "apply-destroy-data-resource")
   408  	p := testProvider("null")
   409  	p.ApplyFn = testApplyFn
   410  	p.DiffFn = testDiffFn
   411  	state := &State{
   412  		Modules: []*ModuleState{
   413  			&ModuleState{
   414  				Path: rootModulePath,
   415  				Resources: map[string]*ResourceState{
   416  					"data.null_data_source.testing": &ResourceState{
   417  						Type: "aws_instance",
   418  						Primary: &InstanceState{
   419  							ID: "-",
   420  							Attributes: map[string]string{
   421  								"inputs.#":    "1",
   422  								"inputs.test": "yes",
   423  							},
   424  						},
   425  					},
   426  				},
   427  			},
   428  		},
   429  	}
   430  	ctx := testContext2(t, &ContextOpts{
   431  		Module: m,
   432  		Providers: map[string]ResourceProviderFactory{
   433  			"null": testProviderFuncFixed(p),
   434  		},
   435  		State:   state,
   436  		Destroy: true,
   437  	})
   438  
   439  	if p, err := ctx.Plan(); err != nil {
   440  		t.Fatalf("err: %s", err)
   441  	} else {
   442  		t.Logf(p.String())
   443  	}
   444  
   445  	newState, err := ctx.Apply()
   446  	if err != nil {
   447  		t.Fatalf("err: %s", err)
   448  	}
   449  
   450  	if got := len(newState.Modules); got != 1 {
   451  		t.Fatalf("state has %d modules after destroy; want 1", got)
   452  	}
   453  
   454  	if got := len(newState.Modules[0].Resources); got != 0 {
   455  		t.Fatalf("state has %d resources after destroy; want 0", got)
   456  	}
   457  }
   458  
   459  // https://github.com/hashicorp/terraform/pull/5096
   460  func TestContext2Apply_destroySkipsCBD(t *testing.T) {
   461  	// Config contains CBD resource depending on non-CBD resource, which triggers
   462  	// a cycle if they are both replaced, but should _not_ trigger a cycle when
   463  	// just doing a `terraform destroy`.
   464  	m := testModule(t, "apply-destroy-cbd")
   465  	p := testProvider("aws")
   466  	p.ApplyFn = testApplyFn
   467  	p.DiffFn = testDiffFn
   468  	state := &State{
   469  		Modules: []*ModuleState{
   470  			&ModuleState{
   471  				Path: rootModulePath,
   472  				Resources: map[string]*ResourceState{
   473  					"aws_instance.foo": &ResourceState{
   474  						Type: "aws_instance",
   475  						Primary: &InstanceState{
   476  							ID: "foo",
   477  						},
   478  					},
   479  					"aws_instance.bar": &ResourceState{
   480  						Type: "aws_instance",
   481  						Primary: &InstanceState{
   482  							ID: "foo",
   483  						},
   484  					},
   485  				},
   486  			},
   487  		},
   488  	}
   489  	ctx := testContext2(t, &ContextOpts{
   490  		Module: m,
   491  		Providers: map[string]ResourceProviderFactory{
   492  			"aws": testProviderFuncFixed(p),
   493  		},
   494  		State:   state,
   495  		Destroy: true,
   496  	})
   497  
   498  	if p, err := ctx.Plan(); err != nil {
   499  		t.Fatalf("err: %s", err)
   500  	} else {
   501  		t.Logf(p.String())
   502  	}
   503  
   504  	if _, err := ctx.Apply(); err != nil {
   505  		t.Fatalf("err: %s", err)
   506  	}
   507  }
   508  
   509  func TestContext2Apply_destroyModuleVarProviderConfig(t *testing.T) {
   510  	m := testModule(t, "apply-destroy-mod-var-provider-config")
   511  	p := testProvider("aws")
   512  	p.ApplyFn = testApplyFn
   513  	p.DiffFn = testDiffFn
   514  	state := &State{
   515  		Modules: []*ModuleState{
   516  			&ModuleState{
   517  				Path: []string{"root", "child"},
   518  				Resources: map[string]*ResourceState{
   519  					"aws_instance.foo": &ResourceState{
   520  						Type: "aws_instance",
   521  						Primary: &InstanceState{
   522  							ID: "foo",
   523  						},
   524  					},
   525  				},
   526  			},
   527  		},
   528  	}
   529  	ctx := testContext2(t, &ContextOpts{
   530  		Module: m,
   531  		Providers: map[string]ResourceProviderFactory{
   532  			"aws": testProviderFuncFixed(p),
   533  		},
   534  		State:   state,
   535  		Destroy: true,
   536  	})
   537  
   538  	if _, err := ctx.Plan(); err != nil {
   539  		t.Fatalf("err: %s", err)
   540  	}
   541  
   542  	_, err := ctx.Apply()
   543  	if err != nil {
   544  		t.Fatalf("err: %s", err)
   545  	}
   546  }
   547  
   548  // https://github.com/hashicorp/terraform/issues/2892
   549  func TestContext2Apply_destroyCrossProviders(t *testing.T) {
   550  	m := testModule(t, "apply-destroy-cross-providers")
   551  
   552  	p_aws := testProvider("aws")
   553  	p_aws.ApplyFn = testApplyFn
   554  	p_aws.DiffFn = testDiffFn
   555  
   556  	p_tf := testProvider("terraform")
   557  	p_tf.ApplyFn = testApplyFn
   558  	p_tf.DiffFn = testDiffFn
   559  
   560  	providers := map[string]ResourceProviderFactory{
   561  		"aws":       testProviderFuncFixed(p_aws),
   562  		"terraform": testProviderFuncFixed(p_tf),
   563  	}
   564  
   565  	// Bug only appears from time to time,
   566  	// so we run this test multiple times
   567  	// to check for the race-condition
   568  	for i := 0; i <= 10; i++ {
   569  		ctx := getContextForApply_destroyCrossProviders(
   570  			t, m, providers)
   571  
   572  		if p, err := ctx.Plan(); err != nil {
   573  			t.Fatalf("err: %s", err)
   574  		} else {
   575  			t.Logf(p.String())
   576  		}
   577  
   578  		if _, err := ctx.Apply(); err != nil {
   579  			t.Fatalf("err: %s", err)
   580  		}
   581  	}
   582  }
   583  
   584  func getContextForApply_destroyCrossProviders(
   585  	t *testing.T,
   586  	m *module.Tree,
   587  	providers map[string]ResourceProviderFactory) *Context {
   588  	state := &State{
   589  		Modules: []*ModuleState{
   590  			&ModuleState{
   591  				Path: rootModulePath,
   592  				Resources: map[string]*ResourceState{
   593  					"terraform_remote_state.shared": &ResourceState{
   594  						Type: "terraform_remote_state",
   595  						Primary: &InstanceState{
   596  							ID: "remote-2652591293",
   597  							Attributes: map[string]string{
   598  								"output.env_name": "test",
   599  							},
   600  						},
   601  					},
   602  				},
   603  			},
   604  			&ModuleState{
   605  				Path: []string{"root", "example"},
   606  				Resources: map[string]*ResourceState{
   607  					"aws_vpc.bar": &ResourceState{
   608  						Type: "aws_vpc",
   609  						Primary: &InstanceState{
   610  							ID: "vpc-aaabbb12",
   611  							Attributes: map[string]string{
   612  								"value": "test",
   613  							},
   614  						},
   615  					},
   616  				},
   617  			},
   618  		},
   619  	}
   620  	ctx := testContext2(t, &ContextOpts{
   621  		Module:    m,
   622  		Providers: providers,
   623  		State:     state,
   624  		Destroy:   true,
   625  	})
   626  
   627  	return ctx
   628  }
   629  
   630  func TestContext2Apply_minimal(t *testing.T) {
   631  	m := testModule(t, "apply-minimal")
   632  	p := testProvider("aws")
   633  	p.ApplyFn = testApplyFn
   634  	p.DiffFn = testDiffFn
   635  	ctx := testContext2(t, &ContextOpts{
   636  		Module: m,
   637  		Providers: map[string]ResourceProviderFactory{
   638  			"aws": testProviderFuncFixed(p),
   639  		},
   640  	})
   641  
   642  	if _, err := ctx.Plan(); err != nil {
   643  		t.Fatalf("err: %s", err)
   644  	}
   645  
   646  	state, err := ctx.Apply()
   647  	if err != nil {
   648  		t.Fatalf("err: %s", err)
   649  	}
   650  
   651  	actual := strings.TrimSpace(state.String())
   652  	expected := strings.TrimSpace(testTerraformApplyMinimalStr)
   653  	if actual != expected {
   654  		t.Fatalf("bad: \n%s", actual)
   655  	}
   656  }
   657  
   658  func TestContext2Apply_badDiff(t *testing.T) {
   659  	m := testModule(t, "apply-good")
   660  	p := testProvider("aws")
   661  	p.ApplyFn = testApplyFn
   662  	p.DiffFn = testDiffFn
   663  	ctx := testContext2(t, &ContextOpts{
   664  		Module: m,
   665  		Providers: map[string]ResourceProviderFactory{
   666  			"aws": testProviderFuncFixed(p),
   667  		},
   668  	})
   669  
   670  	if _, err := ctx.Plan(); err != nil {
   671  		t.Fatalf("err: %s", err)
   672  	}
   673  
   674  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
   675  		return &InstanceDiff{
   676  			Attributes: map[string]*ResourceAttrDiff{
   677  				"newp": nil,
   678  			},
   679  		}, nil
   680  	}
   681  
   682  	if _, err := ctx.Apply(); err == nil {
   683  		t.Fatal("should error")
   684  	}
   685  }
   686  
   687  func TestContext2Apply_cancel(t *testing.T) {
   688  	stopped := false
   689  
   690  	m := testModule(t, "apply-cancel")
   691  	p := testProvider("aws")
   692  	ctx := testContext2(t, &ContextOpts{
   693  		Module: m,
   694  		Providers: map[string]ResourceProviderFactory{
   695  			"aws": testProviderFuncFixed(p),
   696  		},
   697  	})
   698  
   699  	p.ApplyFn = func(*InstanceInfo, *InstanceState, *InstanceDiff) (*InstanceState, error) {
   700  		if !stopped {
   701  			stopped = true
   702  			go ctx.Stop()
   703  
   704  			for {
   705  				if ctx.sh.Stopped() {
   706  					break
   707  				}
   708  			}
   709  		}
   710  
   711  		return &InstanceState{
   712  			ID: "foo",
   713  			Attributes: map[string]string{
   714  				"num": "2",
   715  			},
   716  		}, nil
   717  	}
   718  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
   719  		return &InstanceDiff{
   720  			Attributes: map[string]*ResourceAttrDiff{
   721  				"num": &ResourceAttrDiff{
   722  					New: "bar",
   723  				},
   724  			},
   725  		}, nil
   726  	}
   727  
   728  	if _, err := ctx.Plan(); err != nil {
   729  		t.Fatalf("err: %s", err)
   730  	}
   731  
   732  	// Start the Apply in a goroutine
   733  	stateCh := make(chan *State)
   734  	go func() {
   735  		state, err := ctx.Apply()
   736  		if err != nil {
   737  			panic(err)
   738  		}
   739  
   740  		stateCh <- state
   741  	}()
   742  
   743  	state := <-stateCh
   744  
   745  	mod := state.RootModule()
   746  	if len(mod.Resources) != 1 {
   747  		t.Fatalf("bad: %s", state.String())
   748  	}
   749  
   750  	actual := strings.TrimSpace(state.String())
   751  	expected := strings.TrimSpace(testTerraformApplyCancelStr)
   752  	if actual != expected {
   753  		t.Fatalf("bad: \n%s", actual)
   754  	}
   755  }
   756  
   757  func TestContext2Apply_compute(t *testing.T) {
   758  	m := testModule(t, "apply-compute")
   759  	p := testProvider("aws")
   760  	p.ApplyFn = testApplyFn
   761  	p.DiffFn = testDiffFn
   762  	ctx := testContext2(t, &ContextOpts{
   763  		Module: m,
   764  		Providers: map[string]ResourceProviderFactory{
   765  			"aws": testProviderFuncFixed(p),
   766  		},
   767  	})
   768  
   769  	if _, err := ctx.Plan(); err != nil {
   770  		t.Fatalf("err: %s", err)
   771  	}
   772  
   773  	ctx.variables = map[string]string{"value": "1"}
   774  
   775  	state, err := ctx.Apply()
   776  	if err != nil {
   777  		t.Fatalf("err: %s", err)
   778  	}
   779  
   780  	actual := strings.TrimSpace(state.String())
   781  	expected := strings.TrimSpace(testTerraformApplyComputeStr)
   782  	if actual != expected {
   783  		t.Fatalf("bad: \n%s", actual)
   784  	}
   785  }
   786  
   787  func TestContext2Apply_countDecrease(t *testing.T) {
   788  	m := testModule(t, "apply-count-dec")
   789  	p := testProvider("aws")
   790  	p.DiffFn = testDiffFn
   791  	s := &State{
   792  		Modules: []*ModuleState{
   793  			&ModuleState{
   794  				Path: rootModulePath,
   795  				Resources: map[string]*ResourceState{
   796  					"aws_instance.foo.0": &ResourceState{
   797  						Type: "aws_instance",
   798  						Primary: &InstanceState{
   799  							ID: "bar",
   800  							Attributes: map[string]string{
   801  								"foo":  "foo",
   802  								"type": "aws_instance",
   803  							},
   804  						},
   805  					},
   806  					"aws_instance.foo.1": &ResourceState{
   807  						Type: "aws_instance",
   808  						Primary: &InstanceState{
   809  							ID: "bar",
   810  							Attributes: map[string]string{
   811  								"foo":  "foo",
   812  								"type": "aws_instance",
   813  							},
   814  						},
   815  					},
   816  					"aws_instance.foo.2": &ResourceState{
   817  						Type: "aws_instance",
   818  						Primary: &InstanceState{
   819  							ID: "bar",
   820  							Attributes: map[string]string{
   821  								"foo":  "foo",
   822  								"type": "aws_instance",
   823  							},
   824  						},
   825  					},
   826  				},
   827  			},
   828  		},
   829  	}
   830  	ctx := testContext2(t, &ContextOpts{
   831  		Module: m,
   832  		Providers: map[string]ResourceProviderFactory{
   833  			"aws": testProviderFuncFixed(p),
   834  		},
   835  		State: s,
   836  	})
   837  
   838  	if _, err := ctx.Plan(); err != nil {
   839  		t.Fatalf("err: %s", err)
   840  	}
   841  
   842  	state, err := ctx.Apply()
   843  	if err != nil {
   844  		t.Fatalf("err: %s", err)
   845  	}
   846  
   847  	actual := strings.TrimSpace(state.String())
   848  	expected := strings.TrimSpace(testTerraformApplyCountDecStr)
   849  	if actual != expected {
   850  		t.Fatalf("bad: \n%s", actual)
   851  	}
   852  }
   853  
   854  func TestContext2Apply_countDecreaseToOne(t *testing.T) {
   855  	m := testModule(t, "apply-count-dec-one")
   856  	p := testProvider("aws")
   857  	p.ApplyFn = testApplyFn
   858  	p.DiffFn = testDiffFn
   859  	s := &State{
   860  		Modules: []*ModuleState{
   861  			&ModuleState{
   862  				Path: rootModulePath,
   863  				Resources: map[string]*ResourceState{
   864  					"aws_instance.foo.0": &ResourceState{
   865  						Type: "aws_instance",
   866  						Primary: &InstanceState{
   867  							ID: "bar",
   868  							Attributes: map[string]string{
   869  								"foo":  "foo",
   870  								"type": "aws_instance",
   871  							},
   872  						},
   873  					},
   874  					"aws_instance.foo.1": &ResourceState{
   875  						Type: "aws_instance",
   876  						Primary: &InstanceState{
   877  							ID: "bar",
   878  						},
   879  					},
   880  					"aws_instance.foo.2": &ResourceState{
   881  						Type: "aws_instance",
   882  						Primary: &InstanceState{
   883  							ID: "bar",
   884  						},
   885  					},
   886  				},
   887  			},
   888  		},
   889  	}
   890  	ctx := testContext2(t, &ContextOpts{
   891  		Module: m,
   892  		Providers: map[string]ResourceProviderFactory{
   893  			"aws": testProviderFuncFixed(p),
   894  		},
   895  		State: s,
   896  	})
   897  
   898  	if _, err := ctx.Plan(); err != nil {
   899  		t.Fatalf("err: %s", err)
   900  	}
   901  
   902  	state, err := ctx.Apply()
   903  	if err != nil {
   904  		t.Fatalf("err: %s", err)
   905  	}
   906  
   907  	actual := strings.TrimSpace(state.String())
   908  	expected := strings.TrimSpace(testTerraformApplyCountDecToOneStr)
   909  	if actual != expected {
   910  		t.Fatalf("bad: \n%s", actual)
   911  	}
   912  }
   913  
   914  // https://github.com/PeoplePerHour/terraform/pull/11
   915  //
   916  // This tests a case where both a "resource" and "resource.0" are in
   917  // the state file, which apparently is a reasonable backwards compatibility
   918  // concern found in the above 3rd party repo.
   919  func TestContext2Apply_countDecreaseToOneCorrupted(t *testing.T) {
   920  	m := testModule(t, "apply-count-dec-one")
   921  	p := testProvider("aws")
   922  	p.ApplyFn = testApplyFn
   923  	p.DiffFn = testDiffFn
   924  	s := &State{
   925  		Modules: []*ModuleState{
   926  			&ModuleState{
   927  				Path: rootModulePath,
   928  				Resources: map[string]*ResourceState{
   929  					"aws_instance.foo": &ResourceState{
   930  						Type: "aws_instance",
   931  						Primary: &InstanceState{
   932  							ID: "bar",
   933  							Attributes: map[string]string{
   934  								"foo":  "foo",
   935  								"type": "aws_instance",
   936  							},
   937  						},
   938  					},
   939  					"aws_instance.foo.0": &ResourceState{
   940  						Type: "aws_instance",
   941  						Primary: &InstanceState{
   942  							ID: "baz",
   943  							Attributes: map[string]string{
   944  								"type": "aws_instance",
   945  							},
   946  						},
   947  					},
   948  				},
   949  			},
   950  		},
   951  	}
   952  	ctx := testContext2(t, &ContextOpts{
   953  		Module: m,
   954  		Providers: map[string]ResourceProviderFactory{
   955  			"aws": testProviderFuncFixed(p),
   956  		},
   957  		State: s,
   958  	})
   959  
   960  	if p, err := ctx.Plan(); err != nil {
   961  		t.Fatalf("err: %s", err)
   962  	} else {
   963  		testStringMatch(t, p, testTerraformApplyCountDecToOneCorruptedPlanStr)
   964  	}
   965  
   966  	state, err := ctx.Apply()
   967  	if err != nil {
   968  		t.Fatalf("err: %s", err)
   969  	}
   970  
   971  	actual := strings.TrimSpace(state.String())
   972  	expected := strings.TrimSpace(testTerraformApplyCountDecToOneCorruptedStr)
   973  	if actual != expected {
   974  		t.Fatalf("bad: \n%s", actual)
   975  	}
   976  }
   977  
   978  func TestContext2Apply_countTainted(t *testing.T) {
   979  	m := testModule(t, "apply-count-tainted")
   980  	p := testProvider("aws")
   981  	p.DiffFn = testDiffFn
   982  	s := &State{
   983  		Modules: []*ModuleState{
   984  			&ModuleState{
   985  				Path: rootModulePath,
   986  				Resources: map[string]*ResourceState{
   987  					"aws_instance.foo.0": &ResourceState{
   988  						Type: "aws_instance",
   989  						Primary: &InstanceState{
   990  							ID: "bar",
   991  							Attributes: map[string]string{
   992  								"foo":  "foo",
   993  								"type": "aws_instance",
   994  							},
   995  							Tainted: true,
   996  						},
   997  					},
   998  				},
   999  			},
  1000  		},
  1001  	}
  1002  	ctx := testContext2(t, &ContextOpts{
  1003  		Module: m,
  1004  		Providers: map[string]ResourceProviderFactory{
  1005  			"aws": testProviderFuncFixed(p),
  1006  		},
  1007  		State: s,
  1008  	})
  1009  
  1010  	if _, err := ctx.Plan(); err != nil {
  1011  		t.Fatalf("err: %s", err)
  1012  	}
  1013  
  1014  	state, err := ctx.Apply()
  1015  	if err != nil {
  1016  		t.Fatalf("err: %s", err)
  1017  	}
  1018  
  1019  	actual := strings.TrimSpace(state.String())
  1020  	expected := strings.TrimSpace(testTerraformApplyCountTaintedStr)
  1021  	if actual != expected {
  1022  		t.Fatalf("bad: \n%s", actual)
  1023  	}
  1024  }
  1025  
  1026  func TestContext2Apply_countVariable(t *testing.T) {
  1027  	m := testModule(t, "apply-count-variable")
  1028  	p := testProvider("aws")
  1029  	p.ApplyFn = testApplyFn
  1030  	p.DiffFn = testDiffFn
  1031  	ctx := testContext2(t, &ContextOpts{
  1032  		Module: m,
  1033  		Providers: map[string]ResourceProviderFactory{
  1034  			"aws": testProviderFuncFixed(p),
  1035  		},
  1036  	})
  1037  
  1038  	if _, err := ctx.Plan(); err != nil {
  1039  		t.Fatalf("err: %s", err)
  1040  	}
  1041  
  1042  	state, err := ctx.Apply()
  1043  	if err != nil {
  1044  		t.Fatalf("err: %s", err)
  1045  	}
  1046  
  1047  	actual := strings.TrimSpace(state.String())
  1048  	expected := strings.TrimSpace(testTerraformApplyCountVariableStr)
  1049  	if actual != expected {
  1050  		t.Fatalf("bad: \n%s", actual)
  1051  	}
  1052  }
  1053  
  1054  func TestContext2Apply_mapVariableOverride(t *testing.T) {
  1055  	m := testModule(t, "apply-map-var-override")
  1056  	p := testProvider("aws")
  1057  	p.ApplyFn = testApplyFn
  1058  	p.DiffFn = testDiffFn
  1059  	ctx := testContext2(t, &ContextOpts{
  1060  		Module: m,
  1061  		Providers: map[string]ResourceProviderFactory{
  1062  			"aws": testProviderFuncFixed(p),
  1063  		},
  1064  		Variables: map[string]string{
  1065  			"images.us-west-2": "overridden",
  1066  		},
  1067  	})
  1068  
  1069  	if _, err := ctx.Plan(); err != nil {
  1070  		t.Fatalf("err: %s", err)
  1071  	}
  1072  
  1073  	state, err := ctx.Apply()
  1074  	if err != nil {
  1075  		t.Fatalf("err: %s", err)
  1076  	}
  1077  
  1078  	actual := strings.TrimSpace(state.String())
  1079  	expected := strings.TrimSpace(`
  1080  aws_instance.bar:
  1081    ID = foo
  1082    ami = overridden
  1083    type = aws_instance
  1084  aws_instance.foo:
  1085    ID = foo
  1086    ami = image-1234
  1087    type = aws_instance
  1088  	`)
  1089  	if actual != expected {
  1090  		t.Fatalf("got: \n%s\nexpected: \n%s", actual, expected)
  1091  	}
  1092  }
  1093  
  1094  func TestContext2Apply_module(t *testing.T) {
  1095  	m := testModule(t, "apply-module")
  1096  	p := testProvider("aws")
  1097  	p.ApplyFn = testApplyFn
  1098  	p.DiffFn = testDiffFn
  1099  	ctx := testContext2(t, &ContextOpts{
  1100  		Module: m,
  1101  		Providers: map[string]ResourceProviderFactory{
  1102  			"aws": testProviderFuncFixed(p),
  1103  		},
  1104  	})
  1105  
  1106  	if _, err := ctx.Plan(); err != nil {
  1107  		t.Fatalf("err: %s", err)
  1108  	}
  1109  
  1110  	state, err := ctx.Apply()
  1111  	if err != nil {
  1112  		t.Fatalf("err: %s", err)
  1113  	}
  1114  
  1115  	actual := strings.TrimSpace(state.String())
  1116  	expected := strings.TrimSpace(testTerraformApplyModuleStr)
  1117  	if actual != expected {
  1118  		t.Fatalf("bad: \n%s", actual)
  1119  	}
  1120  }
  1121  
  1122  func TestContext2Apply_moduleDestroyOrder(t *testing.T) {
  1123  	m := testModule(t, "apply-module-destroy-order")
  1124  	p := testProvider("aws")
  1125  	p.DiffFn = testDiffFn
  1126  
  1127  	// Create a custom apply function to track the order they were destroyed
  1128  	var order []string
  1129  	var orderLock sync.Mutex
  1130  	p.ApplyFn = func(
  1131  		info *InstanceInfo,
  1132  		is *InstanceState,
  1133  		id *InstanceDiff) (*InstanceState, error) {
  1134  		orderLock.Lock()
  1135  		defer orderLock.Unlock()
  1136  
  1137  		order = append(order, is.ID)
  1138  		return nil, nil
  1139  	}
  1140  
  1141  	state := &State{
  1142  		Modules: []*ModuleState{
  1143  			&ModuleState{
  1144  				Path: rootModulePath,
  1145  				Resources: map[string]*ResourceState{
  1146  					"aws_instance.b": &ResourceState{
  1147  						Type: "aws_instance",
  1148  						Primary: &InstanceState{
  1149  							ID: "b",
  1150  						},
  1151  					},
  1152  				},
  1153  			},
  1154  
  1155  			&ModuleState{
  1156  				Path: []string{"root", "child"},
  1157  				Resources: map[string]*ResourceState{
  1158  					"aws_instance.a": &ResourceState{
  1159  						Type: "aws_instance",
  1160  						Primary: &InstanceState{
  1161  							ID: "a",
  1162  						},
  1163  					},
  1164  				},
  1165  				Outputs: map[string]*OutputState{
  1166  					"a_output": &OutputState{
  1167  						Type:      "string",
  1168  						Sensitive: false,
  1169  						Value:     "a",
  1170  					},
  1171  				},
  1172  			},
  1173  		},
  1174  	}
  1175  
  1176  	ctx := testContext2(t, &ContextOpts{
  1177  		Module: m,
  1178  		Providers: map[string]ResourceProviderFactory{
  1179  			"aws": testProviderFuncFixed(p),
  1180  		},
  1181  		State:   state,
  1182  		Destroy: true,
  1183  	})
  1184  
  1185  	if _, err := ctx.Plan(); err != nil {
  1186  		t.Fatalf("err: %s", err)
  1187  	}
  1188  
  1189  	state, err := ctx.Apply()
  1190  	if err != nil {
  1191  		t.Fatalf("err: %s", err)
  1192  	}
  1193  
  1194  	expected := []string{"b", "a"}
  1195  	if !reflect.DeepEqual(order, expected) {
  1196  		t.Fatalf("bad: %#v", order)
  1197  	}
  1198  
  1199  	{
  1200  		actual := strings.TrimSpace(state.String())
  1201  		expected := strings.TrimSpace(testTerraformApplyModuleDestroyOrderStr)
  1202  		if actual != expected {
  1203  			t.Fatalf("bad: \n%s", actual)
  1204  		}
  1205  	}
  1206  }
  1207  
  1208  func TestContext2Apply_moduleOrphanProvider(t *testing.T) {
  1209  	m := testModule(t, "apply-module-orphan-provider-inherit")
  1210  	p := testProvider("aws")
  1211  	p.ApplyFn = testApplyFn
  1212  	p.DiffFn = testDiffFn
  1213  
  1214  	p.ConfigureFn = func(c *ResourceConfig) error {
  1215  		if _, ok := c.Get("value"); !ok {
  1216  			return fmt.Errorf("value is not found")
  1217  		}
  1218  
  1219  		return nil
  1220  	}
  1221  
  1222  	// Create a state with an orphan module
  1223  	state := &State{
  1224  		Modules: []*ModuleState{
  1225  			&ModuleState{
  1226  				Path: []string{"root", "child"},
  1227  				Resources: map[string]*ResourceState{
  1228  					"aws_instance.bar": &ResourceState{
  1229  						Type: "aws_instance",
  1230  						Primary: &InstanceState{
  1231  							ID: "bar",
  1232  						},
  1233  					},
  1234  				},
  1235  			},
  1236  		},
  1237  	}
  1238  
  1239  	ctx := testContext2(t, &ContextOpts{
  1240  		Module: m,
  1241  		State:  state,
  1242  		Providers: map[string]ResourceProviderFactory{
  1243  			"aws": testProviderFuncFixed(p),
  1244  		},
  1245  	})
  1246  
  1247  	if _, err := ctx.Plan(); err != nil {
  1248  		t.Fatalf("err: %s", err)
  1249  	}
  1250  
  1251  	if _, err := ctx.Apply(); err != nil {
  1252  		t.Fatalf("err: %s", err)
  1253  	}
  1254  }
  1255  
  1256  func TestContext2Apply_moduleGrandchildProvider(t *testing.T) {
  1257  	m := testModule(t, "apply-module-grandchild-provider-inherit")
  1258  	p := testProvider("aws")
  1259  	p.ApplyFn = testApplyFn
  1260  	p.DiffFn = testDiffFn
  1261  
  1262  	var callLock sync.Mutex
  1263  	called := false
  1264  	p.ConfigureFn = func(c *ResourceConfig) error {
  1265  		if _, ok := c.Get("value"); !ok {
  1266  			return fmt.Errorf("value is not found")
  1267  		}
  1268  		callLock.Lock()
  1269  		called = true
  1270  		callLock.Unlock()
  1271  
  1272  		return nil
  1273  	}
  1274  
  1275  	ctx := testContext2(t, &ContextOpts{
  1276  		Module: m,
  1277  		Providers: map[string]ResourceProviderFactory{
  1278  			"aws": testProviderFuncFixed(p),
  1279  		},
  1280  	})
  1281  
  1282  	if _, err := ctx.Plan(); err != nil {
  1283  		t.Fatalf("err: %s", err)
  1284  	}
  1285  
  1286  	if _, err := ctx.Apply(); err != nil {
  1287  		t.Fatalf("err: %s", err)
  1288  	}
  1289  
  1290  	callLock.Lock()
  1291  	defer callLock.Unlock()
  1292  	if called != true {
  1293  		t.Fatalf("err: configure never called")
  1294  	}
  1295  }
  1296  
  1297  // This tests an issue where all the providers in a module but not
  1298  // in the root weren't being added to the root properly. In this test
  1299  // case: aws is explicitly added to root, but "test" should be added to.
  1300  // With the bug, it wasn't.
  1301  func TestContext2Apply_moduleOnlyProvider(t *testing.T) {
  1302  	m := testModule(t, "apply-module-only-provider")
  1303  	p := testProvider("aws")
  1304  	p.ApplyFn = testApplyFn
  1305  	p.DiffFn = testDiffFn
  1306  	pTest := testProvider("test")
  1307  	pTest.ApplyFn = testApplyFn
  1308  	pTest.DiffFn = testDiffFn
  1309  
  1310  	ctx := testContext2(t, &ContextOpts{
  1311  		Module: m,
  1312  		Providers: map[string]ResourceProviderFactory{
  1313  			"aws":  testProviderFuncFixed(p),
  1314  			"test": testProviderFuncFixed(pTest),
  1315  		},
  1316  	})
  1317  
  1318  	if _, err := ctx.Plan(); err != nil {
  1319  		t.Fatalf("err: %s", err)
  1320  	}
  1321  
  1322  	state, err := ctx.Apply()
  1323  	if err != nil {
  1324  		t.Fatalf("err: %s", err)
  1325  	}
  1326  
  1327  	actual := strings.TrimSpace(state.String())
  1328  	expected := strings.TrimSpace(testTerraformApplyModuleOnlyProviderStr)
  1329  	if actual != expected {
  1330  		t.Fatalf("bad: \n%s", actual)
  1331  	}
  1332  }
  1333  
  1334  func TestContext2Apply_moduleProviderAlias(t *testing.T) {
  1335  	m := testModule(t, "apply-module-provider-alias")
  1336  	p := testProvider("aws")
  1337  	p.ApplyFn = testApplyFn
  1338  	p.DiffFn = testDiffFn
  1339  	ctx := testContext2(t, &ContextOpts{
  1340  		Module: m,
  1341  		Providers: map[string]ResourceProviderFactory{
  1342  			"aws": testProviderFuncFixed(p),
  1343  		},
  1344  	})
  1345  
  1346  	if _, err := ctx.Plan(); err != nil {
  1347  		t.Fatalf("err: %s", err)
  1348  	}
  1349  
  1350  	state, err := ctx.Apply()
  1351  	if err != nil {
  1352  		t.Fatalf("err: %s", err)
  1353  	}
  1354  
  1355  	actual := strings.TrimSpace(state.String())
  1356  	expected := strings.TrimSpace(testTerraformApplyModuleProviderAliasStr)
  1357  	if actual != expected {
  1358  		t.Fatalf("bad: \n%s", actual)
  1359  	}
  1360  }
  1361  
  1362  func TestContext2Apply_moduleProviderAliasTargets(t *testing.T) {
  1363  	m := testModule(t, "apply-module-provider-alias")
  1364  	p := testProvider("aws")
  1365  	p.ApplyFn = testApplyFn
  1366  	p.DiffFn = testDiffFn
  1367  	ctx := testContext2(t, &ContextOpts{
  1368  		Module: m,
  1369  		Providers: map[string]ResourceProviderFactory{
  1370  			"aws": testProviderFuncFixed(p),
  1371  		},
  1372  		Targets: []string{"no.thing"},
  1373  	})
  1374  
  1375  	if _, err := ctx.Plan(); err != nil {
  1376  		t.Fatalf("err: %s", err)
  1377  	}
  1378  
  1379  	state, err := ctx.Apply()
  1380  	if err != nil {
  1381  		t.Fatalf("err: %s", err)
  1382  	}
  1383  
  1384  	actual := strings.TrimSpace(state.String())
  1385  	expected := strings.TrimSpace(`
  1386  <no state>
  1387  	`)
  1388  	if actual != expected {
  1389  		t.Fatalf("bad: \n%s", actual)
  1390  	}
  1391  }
  1392  
  1393  func TestContext2Apply_moduleProviderCloseNested(t *testing.T) {
  1394  	m := testModule(t, "apply-module-provider-close-nested")
  1395  	p := testProvider("aws")
  1396  	p.ApplyFn = testApplyFn
  1397  	p.DiffFn = testDiffFn
  1398  	ctx := testContext2(t, &ContextOpts{
  1399  		Module: m,
  1400  		Providers: map[string]ResourceProviderFactory{
  1401  			"aws": testProviderFuncFixed(p),
  1402  		},
  1403  		State: &State{
  1404  			Modules: []*ModuleState{
  1405  				&ModuleState{
  1406  					Path: []string{"root", "child", "subchild"},
  1407  					Resources: map[string]*ResourceState{
  1408  						"aws_instance.foo": &ResourceState{
  1409  							Type: "aws_instance",
  1410  							Primary: &InstanceState{
  1411  								ID: "bar",
  1412  							},
  1413  						},
  1414  					},
  1415  				},
  1416  			},
  1417  		},
  1418  		Destroy: true,
  1419  	})
  1420  
  1421  	if _, err := ctx.Plan(); err != nil {
  1422  		t.Fatalf("err: %s", err)
  1423  	}
  1424  
  1425  	if _, err := ctx.Apply(); err != nil {
  1426  		t.Fatalf("err: %s", err)
  1427  	}
  1428  }
  1429  
  1430  func TestContext2Apply_moduleVarResourceCount(t *testing.T) {
  1431  	m := testModule(t, "apply-module-var-resource-count")
  1432  	p := testProvider("aws")
  1433  	p.ApplyFn = testApplyFn
  1434  	p.DiffFn = testDiffFn
  1435  	ctx := testContext2(t, &ContextOpts{
  1436  		Module: m,
  1437  		Providers: map[string]ResourceProviderFactory{
  1438  			"aws": testProviderFuncFixed(p),
  1439  		},
  1440  		Variables: map[string]string{
  1441  			"count": "2",
  1442  		},
  1443  		Destroy: true,
  1444  	})
  1445  
  1446  	if _, err := ctx.Plan(); err != nil {
  1447  		t.Fatalf("err: %s", err)
  1448  	}
  1449  
  1450  	if _, err := ctx.Apply(); err != nil {
  1451  		t.Fatalf("err: %s", err)
  1452  	}
  1453  
  1454  	ctx = testContext2(t, &ContextOpts{
  1455  		Module: m,
  1456  		Providers: map[string]ResourceProviderFactory{
  1457  			"aws": testProviderFuncFixed(p),
  1458  		},
  1459  		Variables: map[string]string{
  1460  			"count": "5",
  1461  		},
  1462  	})
  1463  
  1464  	if _, err := ctx.Plan(); err != nil {
  1465  		t.Fatalf("err: %s", err)
  1466  	}
  1467  
  1468  	if _, err := ctx.Apply(); err != nil {
  1469  		t.Fatalf("err: %s", err)
  1470  	}
  1471  }
  1472  
  1473  // GH-819
  1474  func TestContext2Apply_moduleBool(t *testing.T) {
  1475  	m := testModule(t, "apply-module-bool")
  1476  	p := testProvider("aws")
  1477  	p.ApplyFn = testApplyFn
  1478  	p.DiffFn = testDiffFn
  1479  	ctx := testContext2(t, &ContextOpts{
  1480  		Module: m,
  1481  		Providers: map[string]ResourceProviderFactory{
  1482  			"aws": testProviderFuncFixed(p),
  1483  		},
  1484  	})
  1485  
  1486  	if _, err := ctx.Plan(); err != nil {
  1487  		t.Fatalf("err: %s", err)
  1488  	}
  1489  
  1490  	state, err := ctx.Apply()
  1491  	if err != nil {
  1492  		t.Fatalf("err: %s", err)
  1493  	}
  1494  
  1495  	actual := strings.TrimSpace(state.String())
  1496  	expected := strings.TrimSpace(testTerraformApplyModuleBoolStr)
  1497  	if actual != expected {
  1498  		t.Fatalf("bad: \n%s", actual)
  1499  	}
  1500  }
  1501  
  1502  func TestContext2Apply_multiProvider(t *testing.T) {
  1503  	m := testModule(t, "apply-multi-provider")
  1504  	p := testProvider("aws")
  1505  	p.ApplyFn = testApplyFn
  1506  	p.DiffFn = testDiffFn
  1507  
  1508  	pDO := testProvider("do")
  1509  	pDO.ApplyFn = testApplyFn
  1510  	pDO.DiffFn = testDiffFn
  1511  
  1512  	ctx := testContext2(t, &ContextOpts{
  1513  		Module: m,
  1514  		Providers: map[string]ResourceProviderFactory{
  1515  			"aws": testProviderFuncFixed(p),
  1516  			"do":  testProviderFuncFixed(pDO),
  1517  		},
  1518  	})
  1519  
  1520  	if _, err := ctx.Plan(); err != nil {
  1521  		t.Fatalf("err: %s", err)
  1522  	}
  1523  
  1524  	state, err := ctx.Apply()
  1525  	if err != nil {
  1526  		t.Fatalf("err: %s", err)
  1527  	}
  1528  
  1529  	mod := state.RootModule()
  1530  	if len(mod.Resources) < 2 {
  1531  		t.Fatalf("bad: %#v", mod.Resources)
  1532  	}
  1533  
  1534  	actual := strings.TrimSpace(state.String())
  1535  	expected := strings.TrimSpace(testTerraformApplyMultiProviderStr)
  1536  	if actual != expected {
  1537  		t.Fatalf("bad: \n%s", actual)
  1538  	}
  1539  }
  1540  
  1541  func TestContext2Apply_multiVar(t *testing.T) {
  1542  	m := testModule(t, "apply-multi-var")
  1543  	p := testProvider("aws")
  1544  	p.ApplyFn = testApplyFn
  1545  	p.DiffFn = testDiffFn
  1546  
  1547  	// First, apply with a count of 3
  1548  	ctx := testContext2(t, &ContextOpts{
  1549  		Module: m,
  1550  		Providers: map[string]ResourceProviderFactory{
  1551  			"aws": testProviderFuncFixed(p),
  1552  		},
  1553  		Variables: map[string]string{
  1554  			"count": "3",
  1555  		},
  1556  	})
  1557  
  1558  	if _, err := ctx.Plan(); err != nil {
  1559  		t.Fatalf("err: %s", err)
  1560  	}
  1561  
  1562  	state, err := ctx.Apply()
  1563  	if err != nil {
  1564  		t.Fatalf("err: %s", err)
  1565  	}
  1566  
  1567  	actual := state.RootModule().Outputs["output"]
  1568  	expected := "bar0,bar1,bar2"
  1569  	if actual.Value != expected {
  1570  		t.Fatalf("bad: \n%s", actual)
  1571  	}
  1572  
  1573  	// Apply again, reduce the count to 1
  1574  	{
  1575  		ctx := testContext2(t, &ContextOpts{
  1576  			Module: m,
  1577  			State:  state,
  1578  			Providers: map[string]ResourceProviderFactory{
  1579  				"aws": testProviderFuncFixed(p),
  1580  			},
  1581  			Variables: map[string]string{
  1582  				"count": "1",
  1583  			},
  1584  		})
  1585  
  1586  		if _, err := ctx.Plan(); err != nil {
  1587  			t.Fatalf("err: %s", err)
  1588  		}
  1589  
  1590  		state, err := ctx.Apply()
  1591  		if err != nil {
  1592  			t.Fatalf("err: %s", err)
  1593  		}
  1594  
  1595  		actual := state.RootModule().Outputs["output"]
  1596  		expected := "bar0"
  1597  		if actual.Value != expected {
  1598  			t.Fatalf("bad: \n%s", actual)
  1599  		}
  1600  	}
  1601  }
  1602  
  1603  func TestContext2Apply_nilDiff(t *testing.T) {
  1604  	m := testModule(t, "apply-good")
  1605  	p := testProvider("aws")
  1606  	p.ApplyFn = testApplyFn
  1607  	p.DiffFn = testDiffFn
  1608  	ctx := testContext2(t, &ContextOpts{
  1609  		Module: m,
  1610  		Providers: map[string]ResourceProviderFactory{
  1611  			"aws": testProviderFuncFixed(p),
  1612  		},
  1613  	})
  1614  
  1615  	if _, err := ctx.Plan(); err != nil {
  1616  		t.Fatalf("err: %s", err)
  1617  	}
  1618  
  1619  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  1620  		return nil, nil
  1621  	}
  1622  
  1623  	if _, err := ctx.Apply(); err == nil {
  1624  		t.Fatal("should error")
  1625  	}
  1626  }
  1627  
  1628  func TestContext2Apply_outputOrphan(t *testing.T) {
  1629  	m := testModule(t, "apply-output-orphan")
  1630  	p := testProvider("aws")
  1631  	p.ApplyFn = testApplyFn
  1632  	p.DiffFn = testDiffFn
  1633  
  1634  	state := &State{
  1635  		Modules: []*ModuleState{
  1636  			&ModuleState{
  1637  				Path: rootModulePath,
  1638  				Outputs: map[string]*OutputState{
  1639  					"foo": &OutputState{
  1640  						Type:      "string",
  1641  						Sensitive: false,
  1642  						Value:     "bar",
  1643  					},
  1644  					"bar": &OutputState{
  1645  						Type:      "string",
  1646  						Sensitive: false,
  1647  						Value:     "baz",
  1648  					},
  1649  				},
  1650  			},
  1651  		},
  1652  	}
  1653  
  1654  	ctx := testContext2(t, &ContextOpts{
  1655  		Module: m,
  1656  		Providers: map[string]ResourceProviderFactory{
  1657  			"aws": testProviderFuncFixed(p),
  1658  		},
  1659  		State: state,
  1660  	})
  1661  
  1662  	if _, err := ctx.Plan(); err != nil {
  1663  		t.Fatalf("err: %s", err)
  1664  	}
  1665  
  1666  	state, err := ctx.Apply()
  1667  	if err != nil {
  1668  		t.Fatalf("err: %s", err)
  1669  	}
  1670  
  1671  	actual := strings.TrimSpace(state.String())
  1672  	expected := strings.TrimSpace(testTerraformApplyOutputOrphanStr)
  1673  	if actual != expected {
  1674  		t.Fatalf("bad: \n%s", actual)
  1675  	}
  1676  }
  1677  
  1678  func TestContext2Apply_providerComputedVar(t *testing.T) {
  1679  	m := testModule(t, "apply-provider-computed")
  1680  	p := testProvider("aws")
  1681  	p.ApplyFn = testApplyFn
  1682  	p.DiffFn = testDiffFn
  1683  
  1684  	pTest := testProvider("test")
  1685  	pTest.ApplyFn = testApplyFn
  1686  	pTest.DiffFn = testDiffFn
  1687  
  1688  	ctx := testContext2(t, &ContextOpts{
  1689  		Module: m,
  1690  		Providers: map[string]ResourceProviderFactory{
  1691  			"aws":  testProviderFuncFixed(p),
  1692  			"test": testProviderFuncFixed(pTest),
  1693  		},
  1694  	})
  1695  
  1696  	p.ConfigureFn = func(c *ResourceConfig) error {
  1697  		if c.IsComputed("value") {
  1698  			return fmt.Errorf("value is computed")
  1699  		}
  1700  
  1701  		v, ok := c.Get("value")
  1702  		if !ok {
  1703  			return fmt.Errorf("value is not found")
  1704  		}
  1705  		if v != "yes" {
  1706  			return fmt.Errorf("value is not 'yes': %v", v)
  1707  		}
  1708  
  1709  		return nil
  1710  	}
  1711  
  1712  	if _, err := ctx.Plan(); err != nil {
  1713  		t.Fatalf("err: %s", err)
  1714  	}
  1715  
  1716  	if _, err := ctx.Apply(); err != nil {
  1717  		t.Fatalf("err: %s", err)
  1718  	}
  1719  }
  1720  
  1721  func TestContext2Apply_Provisioner_compute(t *testing.T) {
  1722  	m := testModule(t, "apply-provisioner-compute")
  1723  	p := testProvider("aws")
  1724  	pr := testProvisioner()
  1725  	p.ApplyFn = testApplyFn
  1726  	p.DiffFn = testDiffFn
  1727  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  1728  		val, ok := c.Config["foo"]
  1729  		if !ok || val != "computed_dynamical" {
  1730  			t.Fatalf("bad value for foo: %v %#v", val, c)
  1731  		}
  1732  
  1733  		return nil
  1734  	}
  1735  	ctx := testContext2(t, &ContextOpts{
  1736  		Module: m,
  1737  		Providers: map[string]ResourceProviderFactory{
  1738  			"aws": testProviderFuncFixed(p),
  1739  		},
  1740  		Provisioners: map[string]ResourceProvisionerFactory{
  1741  			"shell": testProvisionerFuncFixed(pr),
  1742  		},
  1743  		Variables: map[string]string{
  1744  			"value": "1",
  1745  		},
  1746  	})
  1747  
  1748  	if _, err := ctx.Plan(); err != nil {
  1749  		t.Fatalf("err: %s", err)
  1750  	}
  1751  
  1752  	state, err := ctx.Apply()
  1753  	if err != nil {
  1754  		t.Fatalf("err: %s", err)
  1755  	}
  1756  
  1757  	actual := strings.TrimSpace(state.String())
  1758  	expected := strings.TrimSpace(testTerraformApplyProvisionerStr)
  1759  	if actual != expected {
  1760  		t.Fatalf("bad: \n%s", actual)
  1761  	}
  1762  
  1763  	// Verify apply was invoked
  1764  	if !pr.ApplyCalled {
  1765  		t.Fatalf("provisioner not invoked")
  1766  	}
  1767  }
  1768  
  1769  func TestContext2Apply_provisionerCreateFail(t *testing.T) {
  1770  	m := testModule(t, "apply-provisioner-fail-create")
  1771  	p := testProvider("aws")
  1772  	pr := testProvisioner()
  1773  	p.DiffFn = testDiffFn
  1774  
  1775  	p.ApplyFn = func(
  1776  		info *InstanceInfo,
  1777  		is *InstanceState,
  1778  		id *InstanceDiff) (*InstanceState, error) {
  1779  		is.ID = "foo"
  1780  		return is, fmt.Errorf("error")
  1781  	}
  1782  
  1783  	ctx := testContext2(t, &ContextOpts{
  1784  		Module: m,
  1785  		Providers: map[string]ResourceProviderFactory{
  1786  			"aws": testProviderFuncFixed(p),
  1787  		},
  1788  		Provisioners: map[string]ResourceProvisionerFactory{
  1789  			"shell": testProvisionerFuncFixed(pr),
  1790  		},
  1791  	})
  1792  
  1793  	if _, err := ctx.Plan(); err != nil {
  1794  		t.Fatalf("err: %s", err)
  1795  	}
  1796  
  1797  	state, err := ctx.Apply()
  1798  	if err == nil {
  1799  		t.Fatal("should error")
  1800  	}
  1801  
  1802  	actual := strings.TrimSpace(state.String())
  1803  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailCreateStr)
  1804  	if actual != expected {
  1805  		t.Fatalf("bad: \n%s", actual)
  1806  	}
  1807  }
  1808  
  1809  func TestContext2Apply_provisionerCreateFailNoId(t *testing.T) {
  1810  	m := testModule(t, "apply-provisioner-fail-create")
  1811  	p := testProvider("aws")
  1812  	pr := testProvisioner()
  1813  	p.DiffFn = testDiffFn
  1814  
  1815  	p.ApplyFn = func(
  1816  		info *InstanceInfo,
  1817  		is *InstanceState,
  1818  		id *InstanceDiff) (*InstanceState, error) {
  1819  		return nil, fmt.Errorf("error")
  1820  	}
  1821  
  1822  	ctx := testContext2(t, &ContextOpts{
  1823  		Module: m,
  1824  		Providers: map[string]ResourceProviderFactory{
  1825  			"aws": testProviderFuncFixed(p),
  1826  		},
  1827  		Provisioners: map[string]ResourceProvisionerFactory{
  1828  			"shell": testProvisionerFuncFixed(pr),
  1829  		},
  1830  	})
  1831  
  1832  	if _, err := ctx.Plan(); err != nil {
  1833  		t.Fatalf("err: %s", err)
  1834  	}
  1835  
  1836  	state, err := ctx.Apply()
  1837  	if err == nil {
  1838  		t.Fatal("should error")
  1839  	}
  1840  
  1841  	actual := strings.TrimSpace(state.String())
  1842  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailCreateNoIdStr)
  1843  	if actual != expected {
  1844  		t.Fatalf("bad: \n%s", actual)
  1845  	}
  1846  }
  1847  
  1848  func TestContext2Apply_provisionerFail(t *testing.T) {
  1849  	m := testModule(t, "apply-provisioner-fail")
  1850  	p := testProvider("aws")
  1851  	pr := testProvisioner()
  1852  	p.ApplyFn = testApplyFn
  1853  	p.DiffFn = testDiffFn
  1854  
  1855  	pr.ApplyFn = func(*InstanceState, *ResourceConfig) error {
  1856  		return fmt.Errorf("EXPLOSION")
  1857  	}
  1858  
  1859  	ctx := testContext2(t, &ContextOpts{
  1860  		Module: m,
  1861  		Providers: map[string]ResourceProviderFactory{
  1862  			"aws": testProviderFuncFixed(p),
  1863  		},
  1864  		Provisioners: map[string]ResourceProvisionerFactory{
  1865  			"shell": testProvisionerFuncFixed(pr),
  1866  		},
  1867  		Variables: map[string]string{
  1868  			"value": "1",
  1869  		},
  1870  	})
  1871  
  1872  	if _, err := ctx.Plan(); err != nil {
  1873  		t.Fatalf("err: %s", err)
  1874  	}
  1875  
  1876  	state, err := ctx.Apply()
  1877  	if err == nil {
  1878  		t.Fatal("should error")
  1879  	}
  1880  
  1881  	actual := strings.TrimSpace(state.String())
  1882  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailStr)
  1883  	if actual != expected {
  1884  		t.Fatalf("bad: \n%s", actual)
  1885  	}
  1886  }
  1887  
  1888  func TestContext2Apply_provisionerFail_createBeforeDestroy(t *testing.T) {
  1889  	m := testModule(t, "apply-provisioner-fail-create-before")
  1890  	p := testProvider("aws")
  1891  	pr := testProvisioner()
  1892  	p.ApplyFn = testApplyFn
  1893  	p.DiffFn = testDiffFn
  1894  	pr.ApplyFn = func(*InstanceState, *ResourceConfig) error {
  1895  		return fmt.Errorf("EXPLOSION")
  1896  	}
  1897  
  1898  	state := &State{
  1899  		Modules: []*ModuleState{
  1900  			&ModuleState{
  1901  				Path: rootModulePath,
  1902  				Resources: map[string]*ResourceState{
  1903  					"aws_instance.bar": &ResourceState{
  1904  						Type: "aws_instance",
  1905  						Primary: &InstanceState{
  1906  							ID: "bar",
  1907  							Attributes: map[string]string{
  1908  								"require_new": "abc",
  1909  							},
  1910  						},
  1911  					},
  1912  				},
  1913  			},
  1914  		},
  1915  	}
  1916  	ctx := testContext2(t, &ContextOpts{
  1917  		Module: m,
  1918  		Providers: map[string]ResourceProviderFactory{
  1919  			"aws": testProviderFuncFixed(p),
  1920  		},
  1921  		Provisioners: map[string]ResourceProvisionerFactory{
  1922  			"shell": testProvisionerFuncFixed(pr),
  1923  		},
  1924  		State: state,
  1925  	})
  1926  
  1927  	if _, err := ctx.Plan(); err != nil {
  1928  		t.Fatalf("err: %s", err)
  1929  	}
  1930  
  1931  	state, err := ctx.Apply()
  1932  	if err == nil {
  1933  		t.Fatal("should error")
  1934  	}
  1935  
  1936  	actual := strings.TrimSpace(state.String())
  1937  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailCreateBeforeDestroyStr)
  1938  	if actual != expected {
  1939  		t.Fatalf("bad: \n%s", actual)
  1940  	}
  1941  }
  1942  
  1943  func TestContext2Apply_error_createBeforeDestroy(t *testing.T) {
  1944  	m := testModule(t, "apply-error-create-before")
  1945  	p := testProvider("aws")
  1946  	state := &State{
  1947  		Modules: []*ModuleState{
  1948  			&ModuleState{
  1949  				Path: rootModulePath,
  1950  				Resources: map[string]*ResourceState{
  1951  					"aws_instance.bar": &ResourceState{
  1952  						Type: "aws_instance",
  1953  						Primary: &InstanceState{
  1954  							ID: "bar",
  1955  							Attributes: map[string]string{
  1956  								"require_new": "abc",
  1957  							},
  1958  						},
  1959  					},
  1960  				},
  1961  			},
  1962  		},
  1963  	}
  1964  	ctx := testContext2(t, &ContextOpts{
  1965  		Module: m,
  1966  		Providers: map[string]ResourceProviderFactory{
  1967  			"aws": testProviderFuncFixed(p),
  1968  		},
  1969  		State: state,
  1970  	})
  1971  	p.ApplyFn = func(info *InstanceInfo, is *InstanceState, id *InstanceDiff) (*InstanceState, error) {
  1972  		return nil, fmt.Errorf("error")
  1973  	}
  1974  	p.DiffFn = testDiffFn
  1975  
  1976  	if _, err := ctx.Plan(); err != nil {
  1977  		t.Fatalf("err: %s", err)
  1978  	}
  1979  
  1980  	state, err := ctx.Apply()
  1981  	if err == nil {
  1982  		t.Fatal("should have error")
  1983  	}
  1984  
  1985  	actual := strings.TrimSpace(state.String())
  1986  	expected := strings.TrimSpace(testTerraformApplyErrorCreateBeforeDestroyStr)
  1987  	if actual != expected {
  1988  		t.Fatalf("bad: \n%s\n\nExpected:\n\n%s", actual, expected)
  1989  	}
  1990  }
  1991  
  1992  func TestContext2Apply_errorDestroy_createBeforeDestroy(t *testing.T) {
  1993  	m := testModule(t, "apply-error-create-before")
  1994  	p := testProvider("aws")
  1995  	state := &State{
  1996  		Modules: []*ModuleState{
  1997  			&ModuleState{
  1998  				Path: rootModulePath,
  1999  				Resources: map[string]*ResourceState{
  2000  					"aws_instance.bar": &ResourceState{
  2001  						Type: "aws_instance",
  2002  						Primary: &InstanceState{
  2003  							ID: "bar",
  2004  							Attributes: map[string]string{
  2005  								"require_new": "abc",
  2006  							},
  2007  						},
  2008  					},
  2009  				},
  2010  			},
  2011  		},
  2012  	}
  2013  	ctx := testContext2(t, &ContextOpts{
  2014  		Module: m,
  2015  		Providers: map[string]ResourceProviderFactory{
  2016  			"aws": testProviderFuncFixed(p),
  2017  		},
  2018  		State: state,
  2019  	})
  2020  	p.ApplyFn = func(info *InstanceInfo, is *InstanceState, id *InstanceDiff) (*InstanceState, error) {
  2021  		// Fail the destroy!
  2022  		if id.Destroy {
  2023  			return is, fmt.Errorf("error")
  2024  		}
  2025  
  2026  		// Create should work
  2027  		is = &InstanceState{
  2028  			ID: "foo",
  2029  		}
  2030  		return is, nil
  2031  	}
  2032  	p.DiffFn = testDiffFn
  2033  
  2034  	if _, err := ctx.Plan(); err != nil {
  2035  		t.Fatalf("err: %s", err)
  2036  	}
  2037  
  2038  	state, err := ctx.Apply()
  2039  	if err == nil {
  2040  		t.Fatal("should have error")
  2041  	}
  2042  
  2043  	actual := strings.TrimSpace(state.String())
  2044  	expected := strings.TrimSpace(testTerraformApplyErrorDestroyCreateBeforeDestroyStr)
  2045  	if actual != expected {
  2046  		t.Fatalf("bad: actual:\n%s\n\nexpected:\n%s", actual, expected)
  2047  	}
  2048  }
  2049  
  2050  func TestContext2Apply_multiDepose_createBeforeDestroy(t *testing.T) {
  2051  	m := testModule(t, "apply-multi-depose-create-before-destroy")
  2052  	p := testProvider("aws")
  2053  	p.DiffFn = testDiffFn
  2054  	ps := map[string]ResourceProviderFactory{"aws": testProviderFuncFixed(p)}
  2055  	state := &State{
  2056  		Modules: []*ModuleState{
  2057  			&ModuleState{
  2058  				Path: rootModulePath,
  2059  				Resources: map[string]*ResourceState{
  2060  					"aws_instance.web": &ResourceState{
  2061  						Type:    "aws_instance",
  2062  						Primary: &InstanceState{ID: "foo"},
  2063  					},
  2064  				},
  2065  			},
  2066  		},
  2067  	}
  2068  
  2069  	ctx := testContext2(t, &ContextOpts{
  2070  		Module:    m,
  2071  		Providers: ps,
  2072  		State:     state,
  2073  	})
  2074  	createdInstanceId := "bar"
  2075  	// Create works
  2076  	createFunc := func(is *InstanceState) (*InstanceState, error) {
  2077  		return &InstanceState{ID: createdInstanceId}, nil
  2078  	}
  2079  	// Destroy starts broken
  2080  	destroyFunc := func(is *InstanceState) (*InstanceState, error) {
  2081  		return is, fmt.Errorf("destroy failed")
  2082  	}
  2083  	p.ApplyFn = func(info *InstanceInfo, is *InstanceState, id *InstanceDiff) (*InstanceState, error) {
  2084  		if id.Destroy {
  2085  			return destroyFunc(is)
  2086  		} else {
  2087  			return createFunc(is)
  2088  		}
  2089  	}
  2090  
  2091  	if _, err := ctx.Plan(); err != nil {
  2092  		t.Fatalf("err: %s", err)
  2093  	}
  2094  
  2095  	// Destroy is broken, so even though CBD successfully replaces the instance,
  2096  	// we'll have to save the Deposed instance to destroy later
  2097  	state, err := ctx.Apply()
  2098  	if err == nil {
  2099  		t.Fatal("should have error")
  2100  	}
  2101  
  2102  	checkStateString(t, state, `
  2103  aws_instance.web: (1 deposed)
  2104    ID = bar
  2105    Deposed ID 1 = foo
  2106  	`)
  2107  
  2108  	createdInstanceId = "baz"
  2109  	ctx = testContext2(t, &ContextOpts{
  2110  		Module:    m,
  2111  		Providers: ps,
  2112  		State:     state,
  2113  	})
  2114  
  2115  	if _, err := ctx.Plan(); err != nil {
  2116  		t.Fatalf("err: %s", err)
  2117  	}
  2118  
  2119  	// We're replacing the primary instance once again. Destroy is _still_
  2120  	// broken, so the Deposed list gets longer
  2121  	state, err = ctx.Apply()
  2122  	if err == nil {
  2123  		t.Fatal("should have error")
  2124  	}
  2125  
  2126  	checkStateString(t, state, `
  2127  aws_instance.web: (2 deposed)
  2128    ID = baz
  2129    Deposed ID 1 = foo
  2130    Deposed ID 2 = bar
  2131  	`)
  2132  
  2133  	// Destroy partially fixed!
  2134  	destroyFunc = func(is *InstanceState) (*InstanceState, error) {
  2135  		if is.ID == "foo" || is.ID == "baz" {
  2136  			return nil, nil
  2137  		} else {
  2138  			return is, fmt.Errorf("destroy partially failed")
  2139  		}
  2140  	}
  2141  
  2142  	createdInstanceId = "qux"
  2143  	if _, err := ctx.Plan(); err != nil {
  2144  		t.Fatalf("err: %s", err)
  2145  	}
  2146  	state, err = ctx.Apply()
  2147  	// Expect error because 1/2 of Deposed destroys failed
  2148  	if err == nil {
  2149  		t.Fatal("should have error")
  2150  	}
  2151  
  2152  	// foo and baz are now gone, bar sticks around
  2153  	checkStateString(t, state, `
  2154  aws_instance.web: (1 deposed)
  2155    ID = qux
  2156    Deposed ID 1 = bar
  2157  	`)
  2158  
  2159  	// Destroy working fully!
  2160  	destroyFunc = func(is *InstanceState) (*InstanceState, error) {
  2161  		return nil, nil
  2162  	}
  2163  
  2164  	createdInstanceId = "quux"
  2165  	if _, err := ctx.Plan(); err != nil {
  2166  		t.Fatalf("err: %s", err)
  2167  	}
  2168  	state, err = ctx.Apply()
  2169  	if err != nil {
  2170  		t.Fatal("should not have error:", err)
  2171  	}
  2172  
  2173  	// And finally the state is clean
  2174  	checkStateString(t, state, `
  2175  aws_instance.web:
  2176    ID = quux
  2177  	`)
  2178  }
  2179  
  2180  func TestContext2Apply_provisionerResourceRef(t *testing.T) {
  2181  	m := testModule(t, "apply-provisioner-resource-ref")
  2182  	p := testProvider("aws")
  2183  	pr := testProvisioner()
  2184  	p.ApplyFn = testApplyFn
  2185  	p.DiffFn = testDiffFn
  2186  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  2187  		val, ok := c.Config["foo"]
  2188  		if !ok || val != "2" {
  2189  			t.Fatalf("bad value for foo: %v %#v", val, c)
  2190  		}
  2191  
  2192  		return nil
  2193  	}
  2194  
  2195  	ctx := testContext2(t, &ContextOpts{
  2196  		Module: m,
  2197  		Providers: map[string]ResourceProviderFactory{
  2198  			"aws": testProviderFuncFixed(p),
  2199  		},
  2200  		Provisioners: map[string]ResourceProvisionerFactory{
  2201  			"shell": testProvisionerFuncFixed(pr),
  2202  		},
  2203  	})
  2204  
  2205  	if _, err := ctx.Plan(); err != nil {
  2206  		t.Fatalf("err: %s", err)
  2207  	}
  2208  
  2209  	state, err := ctx.Apply()
  2210  	if err != nil {
  2211  		t.Fatalf("err: %s", err)
  2212  	}
  2213  
  2214  	actual := strings.TrimSpace(state.String())
  2215  	expected := strings.TrimSpace(testTerraformApplyProvisionerResourceRefStr)
  2216  	if actual != expected {
  2217  		t.Fatalf("bad: \n%s", actual)
  2218  	}
  2219  
  2220  	// Verify apply was invoked
  2221  	if !pr.ApplyCalled {
  2222  		t.Fatalf("provisioner not invoked")
  2223  	}
  2224  }
  2225  
  2226  func TestContext2Apply_provisionerSelfRef(t *testing.T) {
  2227  	m := testModule(t, "apply-provisioner-self-ref")
  2228  	p := testProvider("aws")
  2229  	pr := testProvisioner()
  2230  	p.ApplyFn = testApplyFn
  2231  	p.DiffFn = testDiffFn
  2232  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  2233  		val, ok := c.Config["command"]
  2234  		if !ok || val != "bar" {
  2235  			t.Fatalf("bad value for command: %v %#v", val, c)
  2236  		}
  2237  
  2238  		return nil
  2239  	}
  2240  
  2241  	ctx := testContext2(t, &ContextOpts{
  2242  		Module: m,
  2243  		Providers: map[string]ResourceProviderFactory{
  2244  			"aws": testProviderFuncFixed(p),
  2245  		},
  2246  		Provisioners: map[string]ResourceProvisionerFactory{
  2247  			"shell": testProvisionerFuncFixed(pr),
  2248  		},
  2249  	})
  2250  
  2251  	if _, err := ctx.Plan(); err != nil {
  2252  		t.Fatalf("err: %s", err)
  2253  	}
  2254  
  2255  	state, err := ctx.Apply()
  2256  	if err != nil {
  2257  		t.Fatalf("err: %s", err)
  2258  	}
  2259  
  2260  	actual := strings.TrimSpace(state.String())
  2261  	expected := strings.TrimSpace(testTerraformApplyProvisionerSelfRefStr)
  2262  	if actual != expected {
  2263  		t.Fatalf("bad: \n%s", actual)
  2264  	}
  2265  
  2266  	// Verify apply was invoked
  2267  	if !pr.ApplyCalled {
  2268  		t.Fatalf("provisioner not invoked")
  2269  	}
  2270  }
  2271  
  2272  func TestContext2Apply_provisionerMultiSelfRef(t *testing.T) {
  2273  	var lock sync.Mutex
  2274  	commands := make([]string, 0, 5)
  2275  
  2276  	m := testModule(t, "apply-provisioner-multi-self-ref")
  2277  	p := testProvider("aws")
  2278  	pr := testProvisioner()
  2279  	p.ApplyFn = testApplyFn
  2280  	p.DiffFn = testDiffFn
  2281  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  2282  		lock.Lock()
  2283  		defer lock.Unlock()
  2284  
  2285  		val, ok := c.Config["command"]
  2286  		if !ok {
  2287  			t.Fatalf("bad value for command: %v %#v", val, c)
  2288  		}
  2289  
  2290  		commands = append(commands, val.(string))
  2291  		return nil
  2292  	}
  2293  
  2294  	ctx := testContext2(t, &ContextOpts{
  2295  		Module: m,
  2296  		Providers: map[string]ResourceProviderFactory{
  2297  			"aws": testProviderFuncFixed(p),
  2298  		},
  2299  		Provisioners: map[string]ResourceProvisionerFactory{
  2300  			"shell": testProvisionerFuncFixed(pr),
  2301  		},
  2302  	})
  2303  
  2304  	if _, err := ctx.Plan(); err != nil {
  2305  		t.Fatalf("err: %s", err)
  2306  	}
  2307  
  2308  	state, err := ctx.Apply()
  2309  	if err != nil {
  2310  		t.Fatalf("err: %s", err)
  2311  	}
  2312  
  2313  	actual := strings.TrimSpace(state.String())
  2314  	expected := strings.TrimSpace(testTerraformApplyProvisionerMultiSelfRefStr)
  2315  	if actual != expected {
  2316  		t.Fatalf("bad: \n%s", actual)
  2317  	}
  2318  
  2319  	// Verify apply was invoked
  2320  	if !pr.ApplyCalled {
  2321  		t.Fatalf("provisioner not invoked")
  2322  	}
  2323  
  2324  	// Verify our result
  2325  	sort.Strings(commands)
  2326  	expectedCommands := []string{"number 0", "number 1", "number 2"}
  2327  	if !reflect.DeepEqual(commands, expectedCommands) {
  2328  		t.Fatalf("bad: %#v", commands)
  2329  	}
  2330  }
  2331  
  2332  // Provisioner should NOT run on a diff, only create
  2333  func TestContext2Apply_Provisioner_Diff(t *testing.T) {
  2334  	m := testModule(t, "apply-provisioner-diff")
  2335  	p := testProvider("aws")
  2336  	pr := testProvisioner()
  2337  	p.ApplyFn = testApplyFn
  2338  	p.DiffFn = testDiffFn
  2339  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  2340  		return nil
  2341  	}
  2342  	ctx := testContext2(t, &ContextOpts{
  2343  		Module: m,
  2344  		Providers: map[string]ResourceProviderFactory{
  2345  			"aws": testProviderFuncFixed(p),
  2346  		},
  2347  		Provisioners: map[string]ResourceProvisionerFactory{
  2348  			"shell": testProvisionerFuncFixed(pr),
  2349  		},
  2350  	})
  2351  
  2352  	if _, err := ctx.Plan(); err != nil {
  2353  		t.Fatalf("err: %s", err)
  2354  	}
  2355  
  2356  	state, err := ctx.Apply()
  2357  	if err != nil {
  2358  		t.Fatalf("err: %s", err)
  2359  	}
  2360  
  2361  	actual := strings.TrimSpace(state.String())
  2362  	expected := strings.TrimSpace(testTerraformApplyProvisionerDiffStr)
  2363  	if actual != expected {
  2364  		t.Fatalf("bad: \n%s", actual)
  2365  	}
  2366  
  2367  	// Verify apply was invoked
  2368  	if !pr.ApplyCalled {
  2369  		t.Fatalf("provisioner not invoked")
  2370  	}
  2371  	pr.ApplyCalled = false
  2372  
  2373  	// Change the state to force a diff
  2374  	mod := state.RootModule()
  2375  	mod.Resources["aws_instance.bar"].Primary.Attributes["foo"] = "baz"
  2376  
  2377  	// Re-create context with state
  2378  	ctx = testContext2(t, &ContextOpts{
  2379  		Module: m,
  2380  		Providers: map[string]ResourceProviderFactory{
  2381  			"aws": testProviderFuncFixed(p),
  2382  		},
  2383  		Provisioners: map[string]ResourceProvisionerFactory{
  2384  			"shell": testProvisionerFuncFixed(pr),
  2385  		},
  2386  		State: state,
  2387  	})
  2388  
  2389  	if _, err := ctx.Plan(); err != nil {
  2390  		t.Fatalf("err: %s", err)
  2391  	}
  2392  
  2393  	state2, err := ctx.Apply()
  2394  	if err != nil {
  2395  		t.Fatalf("err: %s", err)
  2396  	}
  2397  
  2398  	actual = strings.TrimSpace(state2.String())
  2399  	if actual != expected {
  2400  		t.Fatalf("bad: \n%s", actual)
  2401  	}
  2402  
  2403  	// Verify apply was NOT invoked
  2404  	if pr.ApplyCalled {
  2405  		t.Fatalf("provisioner invoked")
  2406  	}
  2407  }
  2408  
  2409  func TestContext2Apply_outputDiffVars(t *testing.T) {
  2410  	m := testModule(t, "apply-good")
  2411  	p := testProvider("aws")
  2412  	s := &State{
  2413  		Modules: []*ModuleState{
  2414  			&ModuleState{
  2415  				Path: rootModulePath,
  2416  				Resources: map[string]*ResourceState{
  2417  					"aws_instance.baz": &ResourceState{
  2418  						Type: "aws_instance",
  2419  						Primary: &InstanceState{
  2420  							ID: "bar",
  2421  						},
  2422  					},
  2423  				},
  2424  			},
  2425  		},
  2426  	}
  2427  	ctx := testContext2(t, &ContextOpts{
  2428  		Module: m,
  2429  		Providers: map[string]ResourceProviderFactory{
  2430  			"aws": testProviderFuncFixed(p),
  2431  		},
  2432  		State: s,
  2433  	})
  2434  
  2435  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  2436  		for k, ad := range d.Attributes {
  2437  			if ad.NewComputed {
  2438  				return nil, fmt.Errorf("%s: computed", k)
  2439  			}
  2440  		}
  2441  
  2442  		result := s.MergeDiff(d)
  2443  		result.ID = "foo"
  2444  		return result, nil
  2445  	}
  2446  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  2447  		return &InstanceDiff{
  2448  			Attributes: map[string]*ResourceAttrDiff{
  2449  				"foo": &ResourceAttrDiff{
  2450  					NewComputed: true,
  2451  					Type:        DiffAttrOutput,
  2452  				},
  2453  				"bar": &ResourceAttrDiff{
  2454  					New: "baz",
  2455  				},
  2456  			},
  2457  		}, nil
  2458  	}
  2459  
  2460  	if _, err := ctx.Plan(); err != nil {
  2461  		t.Fatalf("err: %s", err)
  2462  	}
  2463  	if _, err := ctx.Apply(); err != nil {
  2464  		t.Fatalf("err: %s", err)
  2465  	}
  2466  }
  2467  
  2468  func TestContext2Apply_Provisioner_ConnInfo(t *testing.T) {
  2469  	m := testModule(t, "apply-provisioner-conninfo")
  2470  	p := testProvider("aws")
  2471  	pr := testProvisioner()
  2472  
  2473  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  2474  		if s.Ephemeral.ConnInfo == nil {
  2475  			t.Fatalf("ConnInfo not initialized")
  2476  		}
  2477  
  2478  		result, _ := testApplyFn(info, s, d)
  2479  		result.Ephemeral.ConnInfo = map[string]string{
  2480  			"type": "ssh",
  2481  			"host": "127.0.0.1",
  2482  			"port": "22",
  2483  		}
  2484  		return result, nil
  2485  	}
  2486  	p.DiffFn = testDiffFn
  2487  
  2488  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  2489  		conn := rs.Ephemeral.ConnInfo
  2490  		if conn["type"] != "telnet" {
  2491  			t.Fatalf("Bad: %#v", conn)
  2492  		}
  2493  		if conn["host"] != "127.0.0.1" {
  2494  			t.Fatalf("Bad: %#v", conn)
  2495  		}
  2496  		if conn["port"] != "2222" {
  2497  			t.Fatalf("Bad: %#v", conn)
  2498  		}
  2499  		if conn["user"] != "superuser" {
  2500  			t.Fatalf("Bad: %#v", conn)
  2501  		}
  2502  		if conn["pass"] != "test" {
  2503  			t.Fatalf("Bad: %#v", conn)
  2504  		}
  2505  
  2506  		return nil
  2507  	}
  2508  
  2509  	ctx := testContext2(t, &ContextOpts{
  2510  		Module: m,
  2511  		Providers: map[string]ResourceProviderFactory{
  2512  			"aws": testProviderFuncFixed(p),
  2513  		},
  2514  		Provisioners: map[string]ResourceProvisionerFactory{
  2515  			"shell": testProvisionerFuncFixed(pr),
  2516  		},
  2517  		Variables: map[string]string{
  2518  			"value": "1",
  2519  			"pass":  "test",
  2520  		},
  2521  	})
  2522  
  2523  	if _, err := ctx.Plan(); err != nil {
  2524  		t.Fatalf("err: %s", err)
  2525  	}
  2526  
  2527  	state, err := ctx.Apply()
  2528  	if err != nil {
  2529  		t.Fatalf("err: %s", err)
  2530  	}
  2531  
  2532  	actual := strings.TrimSpace(state.String())
  2533  	expected := strings.TrimSpace(testTerraformApplyProvisionerStr)
  2534  	if actual != expected {
  2535  		t.Fatalf("bad: \n%s", actual)
  2536  	}
  2537  
  2538  	// Verify apply was invoked
  2539  	if !pr.ApplyCalled {
  2540  		t.Fatalf("provisioner not invoked")
  2541  	}
  2542  }
  2543  
  2544  func TestContext2Apply_destroy(t *testing.T) {
  2545  	m := testModule(t, "apply-destroy")
  2546  	h := new(HookRecordApplyOrder)
  2547  	p := testProvider("aws")
  2548  	p.ApplyFn = testApplyFn
  2549  	p.DiffFn = testDiffFn
  2550  	ctx := testContext2(t, &ContextOpts{
  2551  		Module: m,
  2552  		Hooks:  []Hook{h},
  2553  		Providers: map[string]ResourceProviderFactory{
  2554  			"aws": testProviderFuncFixed(p),
  2555  		},
  2556  	})
  2557  
  2558  	// First plan and apply a create operation
  2559  	if _, err := ctx.Plan(); err != nil {
  2560  		t.Fatalf("err: %s", err)
  2561  	}
  2562  
  2563  	state, err := ctx.Apply()
  2564  	if err != nil {
  2565  		t.Fatalf("err: %s", err)
  2566  	}
  2567  
  2568  	// Next, plan and apply a destroy operation
  2569  	h.Active = true
  2570  	ctx = testContext2(t, &ContextOpts{
  2571  		Destroy: true,
  2572  		State:   state,
  2573  		Module:  m,
  2574  		Hooks:   []Hook{h},
  2575  		Providers: map[string]ResourceProviderFactory{
  2576  			"aws": testProviderFuncFixed(p),
  2577  		},
  2578  	})
  2579  
  2580  	if _, err := ctx.Plan(); err != nil {
  2581  		t.Fatalf("err: %s", err)
  2582  	}
  2583  
  2584  	state, err = ctx.Apply()
  2585  	if err != nil {
  2586  		t.Fatalf("err: %s", err)
  2587  	}
  2588  
  2589  	// Test that things were destroyed
  2590  	actual := strings.TrimSpace(state.String())
  2591  	expected := strings.TrimSpace(testTerraformApplyDestroyStr)
  2592  	if actual != expected {
  2593  		t.Fatalf("bad: \n%s", actual)
  2594  	}
  2595  
  2596  	// Test that things were destroyed _in the right order_
  2597  	expected2 := []string{"aws_instance.bar", "aws_instance.foo"}
  2598  	actual2 := h.IDs
  2599  	if !reflect.DeepEqual(actual2, expected2) {
  2600  		t.Fatalf("expected: %#v\n\ngot:%#v", expected2, actual2)
  2601  	}
  2602  }
  2603  
  2604  func TestContext2Apply_destroyNestedModule(t *testing.T) {
  2605  	m := testModule(t, "apply-destroy-nested-module")
  2606  	p := testProvider("aws")
  2607  	p.ApplyFn = testApplyFn
  2608  	p.DiffFn = testDiffFn
  2609  
  2610  	s := &State{
  2611  		Modules: []*ModuleState{
  2612  			&ModuleState{
  2613  				Path: []string{"root", "child", "subchild"},
  2614  				Resources: map[string]*ResourceState{
  2615  					"aws_instance.bar": &ResourceState{
  2616  						Type: "aws_instance",
  2617  						Primary: &InstanceState{
  2618  							ID: "bar",
  2619  						},
  2620  					},
  2621  				},
  2622  			},
  2623  		},
  2624  	}
  2625  
  2626  	ctx := testContext2(t, &ContextOpts{
  2627  		Module: m,
  2628  		Providers: map[string]ResourceProviderFactory{
  2629  			"aws": testProviderFuncFixed(p),
  2630  		},
  2631  		State: s,
  2632  	})
  2633  
  2634  	// First plan and apply a create operation
  2635  	if _, err := ctx.Plan(); err != nil {
  2636  		t.Fatalf("err: %s", err)
  2637  	}
  2638  
  2639  	state, err := ctx.Apply()
  2640  	if err != nil {
  2641  		t.Fatalf("err: %s", err)
  2642  	}
  2643  
  2644  	// Test that things were destroyed
  2645  	actual := strings.TrimSpace(state.String())
  2646  	expected := strings.TrimSpace(testTerraformApplyDestroyNestedModuleStr)
  2647  	if actual != expected {
  2648  		t.Fatalf("bad: \n%s", actual)
  2649  	}
  2650  }
  2651  
  2652  func TestContext2Apply_destroyDeeplyNestedModule(t *testing.T) {
  2653  	m := testModule(t, "apply-destroy-deeply-nested-module")
  2654  	p := testProvider("aws")
  2655  	p.ApplyFn = testApplyFn
  2656  	p.DiffFn = testDiffFn
  2657  
  2658  	s := &State{
  2659  		Modules: []*ModuleState{
  2660  			&ModuleState{
  2661  				Path: []string{"root", "child", "subchild", "subsubchild"},
  2662  				Resources: map[string]*ResourceState{
  2663  					"aws_instance.bar": &ResourceState{
  2664  						Type: "aws_instance",
  2665  						Primary: &InstanceState{
  2666  							ID: "bar",
  2667  						},
  2668  					},
  2669  				},
  2670  			},
  2671  		},
  2672  	}
  2673  
  2674  	ctx := testContext2(t, &ContextOpts{
  2675  		Module: m,
  2676  		Providers: map[string]ResourceProviderFactory{
  2677  			"aws": testProviderFuncFixed(p),
  2678  		},
  2679  		State: s,
  2680  	})
  2681  
  2682  	// First plan and apply a create operation
  2683  	if _, err := ctx.Plan(); err != nil {
  2684  		t.Fatalf("err: %s", err)
  2685  	}
  2686  
  2687  	state, err := ctx.Apply()
  2688  	if err != nil {
  2689  		t.Fatalf("err: %s", err)
  2690  	}
  2691  
  2692  	// Test that things were destroyed
  2693  	actual := strings.TrimSpace(state.String())
  2694  	expected := strings.TrimSpace(`
  2695  module.child.subchild.subsubchild:
  2696    <no state>
  2697  	`)
  2698  	if actual != expected {
  2699  		t.Fatalf("bad: \n%s", actual)
  2700  	}
  2701  }
  2702  
  2703  // https://github.com/hashicorp/terraform/issues/5440
  2704  func TestContext2Apply_destroyModuleWithAttrsReferencingResource(t *testing.T) {
  2705  	m := testModule(t, "apply-destroy-module-with-attrs")
  2706  	p := testProvider("aws")
  2707  	p.ApplyFn = testApplyFn
  2708  	p.DiffFn = testDiffFn
  2709  
  2710  	var state *State
  2711  	var err error
  2712  	{
  2713  		ctx := testContext2(t, &ContextOpts{
  2714  			Module: m,
  2715  			Providers: map[string]ResourceProviderFactory{
  2716  				"aws": testProviderFuncFixed(p),
  2717  			},
  2718  		})
  2719  
  2720  		// First plan and apply a create operation
  2721  		if _, err := ctx.Plan(); err != nil {
  2722  			t.Fatalf("plan err: %s", err)
  2723  		}
  2724  
  2725  		state, err = ctx.Apply()
  2726  		if err != nil {
  2727  			t.Fatalf("apply err: %s", err)
  2728  		}
  2729  	}
  2730  
  2731  	h := new(HookRecordApplyOrder)
  2732  	h.Active = true
  2733  
  2734  	{
  2735  		ctx := testContext2(t, &ContextOpts{
  2736  			Destroy: true,
  2737  			Module:  m,
  2738  			State:   state,
  2739  			Hooks:   []Hook{h},
  2740  			Providers: map[string]ResourceProviderFactory{
  2741  				"aws": testProviderFuncFixed(p),
  2742  			},
  2743  			Variables: map[string]string{
  2744  				"key_name": "foobarkey",
  2745  			},
  2746  		})
  2747  
  2748  		// First plan and apply a create operation
  2749  		plan, err := ctx.Plan()
  2750  		if err != nil {
  2751  			t.Fatalf("destroy plan err: %s", err)
  2752  		}
  2753  
  2754  		var buf bytes.Buffer
  2755  		if err := WritePlan(plan, &buf); err != nil {
  2756  			t.Fatalf("plan write err: %s", err)
  2757  		}
  2758  
  2759  		planFromFile, err := ReadPlan(&buf)
  2760  		if err != nil {
  2761  			t.Fatalf("plan read err: %s", err)
  2762  		}
  2763  
  2764  		ctx, err = planFromFile.Context(&ContextOpts{
  2765  			Providers: map[string]ResourceProviderFactory{
  2766  				"aws": testProviderFuncFixed(p),
  2767  			},
  2768  		})
  2769  		if err != nil {
  2770  			t.Fatalf("err: %s", err)
  2771  		}
  2772  
  2773  		state, err = ctx.Apply()
  2774  		if err != nil {
  2775  			t.Fatalf("destroy apply err: %s", err)
  2776  		}
  2777  	}
  2778  
  2779  	//Test that things were destroyed
  2780  	actual := strings.TrimSpace(state.String())
  2781  	expected := strings.TrimSpace(`
  2782  <no state>
  2783  module.child:
  2784    <no state>
  2785  		`)
  2786  	if actual != expected {
  2787  		t.Fatalf("expected: \n%s\n\nbad: \n%s", expected, actual)
  2788  	}
  2789  }
  2790  
  2791  func TestContext2Apply_destroyWithModuleVariableAndCount(t *testing.T) {
  2792  	m := testModule(t, "apply-destroy-mod-var-and-count")
  2793  	p := testProvider("aws")
  2794  	p.ApplyFn = testApplyFn
  2795  	p.DiffFn = testDiffFn
  2796  
  2797  	var state *State
  2798  	var err error
  2799  	{
  2800  		ctx := testContext2(t, &ContextOpts{
  2801  			Module: m,
  2802  			Providers: map[string]ResourceProviderFactory{
  2803  				"aws": testProviderFuncFixed(p),
  2804  			},
  2805  		})
  2806  
  2807  		// First plan and apply a create operation
  2808  		if _, err := ctx.Plan(); err != nil {
  2809  			t.Fatalf("plan err: %s", err)
  2810  		}
  2811  
  2812  		state, err = ctx.Apply()
  2813  		if err != nil {
  2814  			t.Fatalf("apply err: %s", err)
  2815  		}
  2816  	}
  2817  
  2818  	h := new(HookRecordApplyOrder)
  2819  	h.Active = true
  2820  
  2821  	{
  2822  		ctx := testContext2(t, &ContextOpts{
  2823  			Destroy: true,
  2824  			Module:  m,
  2825  			State:   state,
  2826  			Hooks:   []Hook{h},
  2827  			Providers: map[string]ResourceProviderFactory{
  2828  				"aws": testProviderFuncFixed(p),
  2829  			},
  2830  		})
  2831  
  2832  		// First plan and apply a create operation
  2833  		plan, err := ctx.Plan()
  2834  		if err != nil {
  2835  			t.Fatalf("destroy plan err: %s", err)
  2836  		}
  2837  
  2838  		var buf bytes.Buffer
  2839  		if err := WritePlan(plan, &buf); err != nil {
  2840  			t.Fatalf("plan write err: %s", err)
  2841  		}
  2842  
  2843  		planFromFile, err := ReadPlan(&buf)
  2844  		if err != nil {
  2845  			t.Fatalf("plan read err: %s", err)
  2846  		}
  2847  
  2848  		ctx, err = planFromFile.Context(&ContextOpts{
  2849  			Providers: map[string]ResourceProviderFactory{
  2850  				"aws": testProviderFuncFixed(p),
  2851  			},
  2852  		})
  2853  		if err != nil {
  2854  			t.Fatalf("err: %s", err)
  2855  		}
  2856  
  2857  		state, err = ctx.Apply()
  2858  		if err != nil {
  2859  			t.Fatalf("destroy apply err: %s", err)
  2860  		}
  2861  	}
  2862  
  2863  	//Test that things were destroyed
  2864  	actual := strings.TrimSpace(state.String())
  2865  	expected := strings.TrimSpace(`
  2866  <no state>
  2867  module.child:
  2868    <no state>
  2869  		`)
  2870  	if actual != expected {
  2871  		t.Fatalf("expected: \n%s\n\nbad: \n%s", expected, actual)
  2872  	}
  2873  }
  2874  
  2875  func TestContext2Apply_destroyWithModuleVariableAndCountNested(t *testing.T) {
  2876  	m := testModule(t, "apply-destroy-mod-var-and-count-nested")
  2877  	p := testProvider("aws")
  2878  	p.ApplyFn = testApplyFn
  2879  	p.DiffFn = testDiffFn
  2880  
  2881  	var state *State
  2882  	var err error
  2883  	{
  2884  		ctx := testContext2(t, &ContextOpts{
  2885  			Module: m,
  2886  			Providers: map[string]ResourceProviderFactory{
  2887  				"aws": testProviderFuncFixed(p),
  2888  			},
  2889  		})
  2890  
  2891  		// First plan and apply a create operation
  2892  		if _, err := ctx.Plan(); err != nil {
  2893  			t.Fatalf("plan err: %s", err)
  2894  		}
  2895  
  2896  		state, err = ctx.Apply()
  2897  		if err != nil {
  2898  			t.Fatalf("apply err: %s", err)
  2899  		}
  2900  	}
  2901  
  2902  	h := new(HookRecordApplyOrder)
  2903  	h.Active = true
  2904  
  2905  	{
  2906  		ctx := testContext2(t, &ContextOpts{
  2907  			Destroy: true,
  2908  			Module:  m,
  2909  			State:   state,
  2910  			Hooks:   []Hook{h},
  2911  			Providers: map[string]ResourceProviderFactory{
  2912  				"aws": testProviderFuncFixed(p),
  2913  			},
  2914  		})
  2915  
  2916  		// First plan and apply a create operation
  2917  		plan, err := ctx.Plan()
  2918  		if err != nil {
  2919  			t.Fatalf("destroy plan err: %s", err)
  2920  		}
  2921  
  2922  		var buf bytes.Buffer
  2923  		if err := WritePlan(plan, &buf); err != nil {
  2924  			t.Fatalf("plan write err: %s", err)
  2925  		}
  2926  
  2927  		planFromFile, err := ReadPlan(&buf)
  2928  		if err != nil {
  2929  			t.Fatalf("plan read err: %s", err)
  2930  		}
  2931  
  2932  		ctx, err = planFromFile.Context(&ContextOpts{
  2933  			Providers: map[string]ResourceProviderFactory{
  2934  				"aws": testProviderFuncFixed(p),
  2935  			},
  2936  		})
  2937  		if err != nil {
  2938  			t.Fatalf("err: %s", err)
  2939  		}
  2940  
  2941  		state, err = ctx.Apply()
  2942  		if err != nil {
  2943  			t.Fatalf("destroy apply err: %s", err)
  2944  		}
  2945  	}
  2946  
  2947  	//Test that things were destroyed
  2948  	actual := strings.TrimSpace(state.String())
  2949  	expected := strings.TrimSpace(`
  2950  <no state>
  2951  module.child:
  2952    <no state>
  2953  module.child.child2:
  2954    <no state>
  2955  		`)
  2956  	if actual != expected {
  2957  		t.Fatalf("expected: \n%s\n\nbad: \n%s", expected, actual)
  2958  	}
  2959  }
  2960  
  2961  func TestContext2Apply_destroyOutputs(t *testing.T) {
  2962  	m := testModule(t, "apply-destroy-outputs")
  2963  	h := new(HookRecordApplyOrder)
  2964  	p := testProvider("aws")
  2965  	p.ApplyFn = testApplyFn
  2966  	p.DiffFn = testDiffFn
  2967  	ctx := testContext2(t, &ContextOpts{
  2968  		Module: m,
  2969  		Hooks:  []Hook{h},
  2970  		Providers: map[string]ResourceProviderFactory{
  2971  			"aws": testProviderFuncFixed(p),
  2972  		},
  2973  	})
  2974  
  2975  	// First plan and apply a create operation
  2976  	if _, err := ctx.Plan(); err != nil {
  2977  		t.Fatalf("err: %s", err)
  2978  	}
  2979  
  2980  	state, err := ctx.Apply()
  2981  
  2982  	if err != nil {
  2983  		t.Fatalf("err: %s", err)
  2984  	}
  2985  
  2986  	// Next, plan and apply a destroy operation
  2987  	h.Active = true
  2988  	ctx = testContext2(t, &ContextOpts{
  2989  		Destroy: true,
  2990  		State:   state,
  2991  		Module:  m,
  2992  		Hooks:   []Hook{h},
  2993  		Providers: map[string]ResourceProviderFactory{
  2994  			"aws": testProviderFuncFixed(p),
  2995  		},
  2996  	})
  2997  
  2998  	if _, err := ctx.Plan(); err != nil {
  2999  		t.Fatalf("err: %s", err)
  3000  	}
  3001  
  3002  	state, err = ctx.Apply()
  3003  	if err != nil {
  3004  		t.Fatalf("err: %s", err)
  3005  	}
  3006  
  3007  	mod := state.RootModule()
  3008  	if len(mod.Resources) > 0 {
  3009  		t.Fatalf("bad: %#v", mod)
  3010  	}
  3011  }
  3012  
  3013  func TestContext2Apply_destroyOrphan(t *testing.T) {
  3014  	m := testModule(t, "apply-error")
  3015  	p := testProvider("aws")
  3016  	s := &State{
  3017  		Modules: []*ModuleState{
  3018  			&ModuleState{
  3019  				Path: rootModulePath,
  3020  				Resources: map[string]*ResourceState{
  3021  					"aws_instance.baz": &ResourceState{
  3022  						Type: "aws_instance",
  3023  						Primary: &InstanceState{
  3024  							ID: "bar",
  3025  						},
  3026  					},
  3027  				},
  3028  			},
  3029  		},
  3030  	}
  3031  	ctx := testContext2(t, &ContextOpts{
  3032  		Module: m,
  3033  		Providers: map[string]ResourceProviderFactory{
  3034  			"aws": testProviderFuncFixed(p),
  3035  		},
  3036  		State: s,
  3037  	})
  3038  
  3039  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  3040  		if d.Destroy {
  3041  			return nil, nil
  3042  		}
  3043  
  3044  		result := s.MergeDiff(d)
  3045  		result.ID = "foo"
  3046  		return result, nil
  3047  	}
  3048  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  3049  		return &InstanceDiff{
  3050  			Attributes: map[string]*ResourceAttrDiff{
  3051  				"num": &ResourceAttrDiff{
  3052  					New: "bar",
  3053  				},
  3054  			},
  3055  		}, nil
  3056  	}
  3057  
  3058  	if _, err := ctx.Plan(); err != nil {
  3059  		t.Fatalf("err: %s", err)
  3060  	}
  3061  
  3062  	state, err := ctx.Apply()
  3063  	if err != nil {
  3064  		t.Fatalf("err: %s", err)
  3065  	}
  3066  
  3067  	mod := state.RootModule()
  3068  	if _, ok := mod.Resources["aws_instance.baz"]; ok {
  3069  		t.Fatalf("bad: %#v", mod.Resources)
  3070  	}
  3071  }
  3072  
  3073  func TestContext2Apply_destroyTaintedProvisioner(t *testing.T) {
  3074  	m := testModule(t, "apply-destroy-provisioner")
  3075  	p := testProvider("aws")
  3076  	pr := testProvisioner()
  3077  	p.ApplyFn = testApplyFn
  3078  	p.DiffFn = testDiffFn
  3079  
  3080  	called := false
  3081  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  3082  		called = true
  3083  		return nil
  3084  	}
  3085  
  3086  	s := &State{
  3087  		Modules: []*ModuleState{
  3088  			&ModuleState{
  3089  				Path: rootModulePath,
  3090  				Resources: map[string]*ResourceState{
  3091  					"aws_instance.foo": &ResourceState{
  3092  						Type: "aws_instance",
  3093  						Primary: &InstanceState{
  3094  							ID: "bar",
  3095  							Attributes: map[string]string{
  3096  								"id": "bar",
  3097  							},
  3098  							Tainted: true,
  3099  						},
  3100  					},
  3101  				},
  3102  			},
  3103  		},
  3104  	}
  3105  
  3106  	ctx := testContext2(t, &ContextOpts{
  3107  		Module: m,
  3108  		Providers: map[string]ResourceProviderFactory{
  3109  			"aws": testProviderFuncFixed(p),
  3110  		},
  3111  		Provisioners: map[string]ResourceProvisionerFactory{
  3112  			"shell": testProvisionerFuncFixed(pr),
  3113  		},
  3114  		State:   s,
  3115  		Destroy: true,
  3116  	})
  3117  
  3118  	if _, err := ctx.Plan(); err != nil {
  3119  		t.Fatalf("err: %s", err)
  3120  	}
  3121  
  3122  	state, err := ctx.Apply()
  3123  	if err != nil {
  3124  		t.Fatalf("err: %s", err)
  3125  	}
  3126  
  3127  	if called {
  3128  		t.Fatal("provisioner should not be called")
  3129  	}
  3130  
  3131  	actual := strings.TrimSpace(state.String())
  3132  	expected := strings.TrimSpace("<no state>")
  3133  	if actual != expected {
  3134  		t.Fatalf("bad: \n%s", actual)
  3135  	}
  3136  }
  3137  
  3138  func TestContext2Apply_error(t *testing.T) {
  3139  	errored := false
  3140  
  3141  	m := testModule(t, "apply-error")
  3142  	p := testProvider("aws")
  3143  	ctx := testContext2(t, &ContextOpts{
  3144  		Module: m,
  3145  		Providers: map[string]ResourceProviderFactory{
  3146  			"aws": testProviderFuncFixed(p),
  3147  		},
  3148  	})
  3149  
  3150  	p.ApplyFn = func(*InstanceInfo, *InstanceState, *InstanceDiff) (*InstanceState, error) {
  3151  		if errored {
  3152  			state := &InstanceState{
  3153  				ID: "bar",
  3154  			}
  3155  			return state, fmt.Errorf("error")
  3156  		}
  3157  		errored = true
  3158  
  3159  		return &InstanceState{
  3160  			ID: "foo",
  3161  			Attributes: map[string]string{
  3162  				"num": "2",
  3163  			},
  3164  		}, nil
  3165  	}
  3166  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  3167  		return &InstanceDiff{
  3168  			Attributes: map[string]*ResourceAttrDiff{
  3169  				"num": &ResourceAttrDiff{
  3170  					New: "bar",
  3171  				},
  3172  			},
  3173  		}, nil
  3174  	}
  3175  
  3176  	if _, err := ctx.Plan(); err != nil {
  3177  		t.Fatalf("err: %s", err)
  3178  	}
  3179  
  3180  	state, err := ctx.Apply()
  3181  	if err == nil {
  3182  		t.Fatal("should have error")
  3183  	}
  3184  
  3185  	actual := strings.TrimSpace(state.String())
  3186  	expected := strings.TrimSpace(testTerraformApplyErrorStr)
  3187  	if actual != expected {
  3188  		t.Fatalf("bad: \n%s", actual)
  3189  	}
  3190  }
  3191  
  3192  func TestContext2Apply_errorPartial(t *testing.T) {
  3193  	errored := false
  3194  
  3195  	m := testModule(t, "apply-error")
  3196  	p := testProvider("aws")
  3197  	s := &State{
  3198  		Modules: []*ModuleState{
  3199  			&ModuleState{
  3200  				Path: rootModulePath,
  3201  				Resources: map[string]*ResourceState{
  3202  					"aws_instance.bar": &ResourceState{
  3203  						Type: "aws_instance",
  3204  						Primary: &InstanceState{
  3205  							ID: "bar",
  3206  						},
  3207  					},
  3208  				},
  3209  			},
  3210  		},
  3211  	}
  3212  	ctx := testContext2(t, &ContextOpts{
  3213  		Module: m,
  3214  		Providers: map[string]ResourceProviderFactory{
  3215  			"aws": testProviderFuncFixed(p),
  3216  		},
  3217  		State: s,
  3218  	})
  3219  
  3220  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  3221  		if errored {
  3222  			return s, fmt.Errorf("error")
  3223  		}
  3224  		errored = true
  3225  
  3226  		return &InstanceState{
  3227  			ID: "foo",
  3228  			Attributes: map[string]string{
  3229  				"num": "2",
  3230  			},
  3231  		}, nil
  3232  	}
  3233  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  3234  		return &InstanceDiff{
  3235  			Attributes: map[string]*ResourceAttrDiff{
  3236  				"num": &ResourceAttrDiff{
  3237  					New: "bar",
  3238  				},
  3239  			},
  3240  		}, nil
  3241  	}
  3242  
  3243  	if _, err := ctx.Plan(); err != nil {
  3244  		t.Fatalf("err: %s", err)
  3245  	}
  3246  
  3247  	state, err := ctx.Apply()
  3248  	if err == nil {
  3249  		t.Fatal("should have error")
  3250  	}
  3251  
  3252  	mod := state.RootModule()
  3253  	if len(mod.Resources) != 2 {
  3254  		t.Fatalf("bad: %#v", mod.Resources)
  3255  	}
  3256  
  3257  	actual := strings.TrimSpace(state.String())
  3258  	expected := strings.TrimSpace(testTerraformApplyErrorPartialStr)
  3259  	if actual != expected {
  3260  		t.Fatalf("bad: \n%s", actual)
  3261  	}
  3262  }
  3263  
  3264  func TestContext2Apply_hook(t *testing.T) {
  3265  	m := testModule(t, "apply-good")
  3266  	h := new(MockHook)
  3267  	p := testProvider("aws")
  3268  	p.ApplyFn = testApplyFn
  3269  	p.DiffFn = testDiffFn
  3270  	ctx := testContext2(t, &ContextOpts{
  3271  		Module: m,
  3272  		Hooks:  []Hook{h},
  3273  		Providers: map[string]ResourceProviderFactory{
  3274  			"aws": testProviderFuncFixed(p),
  3275  		},
  3276  	})
  3277  
  3278  	if _, err := ctx.Plan(); err != nil {
  3279  		t.Fatalf("err: %s", err)
  3280  	}
  3281  
  3282  	if _, err := ctx.Apply(); err != nil {
  3283  		t.Fatalf("err: %s", err)
  3284  	}
  3285  
  3286  	if !h.PreApplyCalled {
  3287  		t.Fatal("should be called")
  3288  	}
  3289  	if !h.PostApplyCalled {
  3290  		t.Fatal("should be called")
  3291  	}
  3292  	if !h.PostStateUpdateCalled {
  3293  		t.Fatalf("should call post state update")
  3294  	}
  3295  }
  3296  
  3297  func TestContext2Apply_hookOrphan(t *testing.T) {
  3298  	m := testModule(t, "apply-blank")
  3299  	h := new(MockHook)
  3300  	p := testProvider("aws")
  3301  	p.ApplyFn = testApplyFn
  3302  	p.DiffFn = testDiffFn
  3303  
  3304  	state := &State{
  3305  		Modules: []*ModuleState{
  3306  			&ModuleState{
  3307  				Path: rootModulePath,
  3308  				Resources: map[string]*ResourceState{
  3309  					"aws_instance.bar": &ResourceState{
  3310  						Type: "aws_instance",
  3311  						Primary: &InstanceState{
  3312  							ID: "bar",
  3313  						},
  3314  					},
  3315  				},
  3316  			},
  3317  		},
  3318  	}
  3319  
  3320  	ctx := testContext2(t, &ContextOpts{
  3321  		Module: m,
  3322  		State:  state,
  3323  		Hooks:  []Hook{h},
  3324  		Providers: map[string]ResourceProviderFactory{
  3325  			"aws": testProviderFuncFixed(p),
  3326  		},
  3327  	})
  3328  
  3329  	if _, err := ctx.Plan(); err != nil {
  3330  		t.Fatalf("err: %s", err)
  3331  	}
  3332  
  3333  	if _, err := ctx.Apply(); err != nil {
  3334  		t.Fatalf("err: %s", err)
  3335  	}
  3336  
  3337  	if !h.PreApplyCalled {
  3338  		t.Fatal("should be called")
  3339  	}
  3340  	if !h.PostApplyCalled {
  3341  		t.Fatal("should be called")
  3342  	}
  3343  	if !h.PostStateUpdateCalled {
  3344  		t.Fatalf("should call post state update")
  3345  	}
  3346  }
  3347  
  3348  func TestContext2Apply_idAttr(t *testing.T) {
  3349  	m := testModule(t, "apply-idattr")
  3350  	p := testProvider("aws")
  3351  	ctx := testContext2(t, &ContextOpts{
  3352  		Module: m,
  3353  		Providers: map[string]ResourceProviderFactory{
  3354  			"aws": testProviderFuncFixed(p),
  3355  		},
  3356  	})
  3357  
  3358  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  3359  		result := s.MergeDiff(d)
  3360  		result.ID = "foo"
  3361  		result.Attributes = map[string]string{
  3362  			"id": "bar",
  3363  		}
  3364  
  3365  		return result, nil
  3366  	}
  3367  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  3368  		return &InstanceDiff{
  3369  			Attributes: map[string]*ResourceAttrDiff{
  3370  				"num": &ResourceAttrDiff{
  3371  					New: "bar",
  3372  				},
  3373  			},
  3374  		}, nil
  3375  	}
  3376  
  3377  	if _, err := ctx.Plan(); err != nil {
  3378  		t.Fatalf("err: %s", err)
  3379  	}
  3380  
  3381  	state, err := ctx.Apply()
  3382  	if err != nil {
  3383  		t.Fatalf("err: %s", err)
  3384  	}
  3385  
  3386  	mod := state.RootModule()
  3387  	rs, ok := mod.Resources["aws_instance.foo"]
  3388  	if !ok {
  3389  		t.Fatal("not in state")
  3390  	}
  3391  	if rs.Primary.ID != "foo" {
  3392  		t.Fatalf("bad: %#v", rs.Primary.ID)
  3393  	}
  3394  	if rs.Primary.Attributes["id"] != "foo" {
  3395  		t.Fatalf("bad: %#v", rs.Primary.Attributes)
  3396  	}
  3397  }
  3398  
  3399  func TestContext2Apply_output(t *testing.T) {
  3400  	m := testModule(t, "apply-output")
  3401  	p := testProvider("aws")
  3402  	p.ApplyFn = testApplyFn
  3403  	p.DiffFn = testDiffFn
  3404  	ctx := testContext2(t, &ContextOpts{
  3405  		Module: m,
  3406  		Providers: map[string]ResourceProviderFactory{
  3407  			"aws": testProviderFuncFixed(p),
  3408  		},
  3409  	})
  3410  
  3411  	if _, err := ctx.Plan(); err != nil {
  3412  		t.Fatalf("err: %s", err)
  3413  	}
  3414  
  3415  	state, err := ctx.Apply()
  3416  	if err != nil {
  3417  		t.Fatalf("err: %s", err)
  3418  	}
  3419  
  3420  	actual := strings.TrimSpace(state.String())
  3421  	expected := strings.TrimSpace(testTerraformApplyOutputStr)
  3422  	if actual != expected {
  3423  		t.Fatalf("bad: \n%s", actual)
  3424  	}
  3425  }
  3426  
  3427  func TestContext2Apply_outputInvalid(t *testing.T) {
  3428  	m := testModule(t, "apply-output-invalid")
  3429  	p := testProvider("aws")
  3430  	p.ApplyFn = testApplyFn
  3431  	p.DiffFn = testDiffFn
  3432  	ctx := testContext2(t, &ContextOpts{
  3433  		Module: m,
  3434  		Providers: map[string]ResourceProviderFactory{
  3435  			"aws": testProviderFuncFixed(p),
  3436  		},
  3437  	})
  3438  
  3439  	_, err := ctx.Plan()
  3440  	if err == nil {
  3441  		t.Fatalf("err: %s", err)
  3442  	}
  3443  	if !strings.Contains(err.Error(), "is not a valid type") {
  3444  		t.Fatalf("err: %s", err)
  3445  	}
  3446  }
  3447  
  3448  func TestContext2Apply_outputAdd(t *testing.T) {
  3449  	m1 := testModule(t, "apply-output-add-before")
  3450  	p1 := testProvider("aws")
  3451  	p1.ApplyFn = testApplyFn
  3452  	p1.DiffFn = testDiffFn
  3453  	ctx1 := testContext2(t, &ContextOpts{
  3454  		Module: m1,
  3455  		Providers: map[string]ResourceProviderFactory{
  3456  			"aws": testProviderFuncFixed(p1),
  3457  		},
  3458  	})
  3459  
  3460  	if _, err := ctx1.Plan(); err != nil {
  3461  		t.Fatalf("err: %s", err)
  3462  	}
  3463  
  3464  	state1, err := ctx1.Apply()
  3465  	if err != nil {
  3466  		t.Fatalf("err: %s", err)
  3467  	}
  3468  
  3469  	m2 := testModule(t, "apply-output-add-after")
  3470  	p2 := testProvider("aws")
  3471  	p2.ApplyFn = testApplyFn
  3472  	p2.DiffFn = testDiffFn
  3473  	ctx2 := testContext2(t, &ContextOpts{
  3474  		Module: m2,
  3475  		Providers: map[string]ResourceProviderFactory{
  3476  			"aws": testProviderFuncFixed(p2),
  3477  		},
  3478  		State: state1,
  3479  	})
  3480  
  3481  	if _, err := ctx2.Plan(); err != nil {
  3482  		t.Fatalf("err: %s", err)
  3483  	}
  3484  
  3485  	state2, err := ctx2.Apply()
  3486  	if err != nil {
  3487  		t.Fatalf("err: %s", err)
  3488  	}
  3489  
  3490  	actual := strings.TrimSpace(state2.String())
  3491  	expected := strings.TrimSpace(testTerraformApplyOutputAddStr)
  3492  	if actual != expected {
  3493  		t.Fatalf("bad: \n%s", actual)
  3494  	}
  3495  }
  3496  
  3497  func TestContext2Apply_outputList(t *testing.T) {
  3498  	m := testModule(t, "apply-output-list")
  3499  	p := testProvider("aws")
  3500  	p.ApplyFn = testApplyFn
  3501  	p.DiffFn = testDiffFn
  3502  	ctx := testContext2(t, &ContextOpts{
  3503  		Module: m,
  3504  		Providers: map[string]ResourceProviderFactory{
  3505  			"aws": testProviderFuncFixed(p),
  3506  		},
  3507  	})
  3508  
  3509  	if _, err := ctx.Plan(); err != nil {
  3510  		t.Fatalf("err: %s", err)
  3511  	}
  3512  
  3513  	state, err := ctx.Apply()
  3514  	if err != nil {
  3515  		t.Fatalf("err: %s", err)
  3516  	}
  3517  
  3518  	actual := strings.TrimSpace(state.String())
  3519  	expected := strings.TrimSpace(testTerraformApplyOutputListStr)
  3520  	if actual != expected {
  3521  		t.Fatalf("expected: \n%s\n\nbad: \n%s", expected, actual)
  3522  	}
  3523  }
  3524  
  3525  func TestContext2Apply_outputMulti(t *testing.T) {
  3526  	m := testModule(t, "apply-output-multi")
  3527  	p := testProvider("aws")
  3528  	p.ApplyFn = testApplyFn
  3529  	p.DiffFn = testDiffFn
  3530  	ctx := testContext2(t, &ContextOpts{
  3531  		Module: m,
  3532  		Providers: map[string]ResourceProviderFactory{
  3533  			"aws": testProviderFuncFixed(p),
  3534  		},
  3535  	})
  3536  
  3537  	if _, err := ctx.Plan(); err != nil {
  3538  		t.Fatalf("err: %s", err)
  3539  	}
  3540  
  3541  	state, err := ctx.Apply()
  3542  	if err != nil {
  3543  		t.Fatalf("err: %s", err)
  3544  	}
  3545  
  3546  	actual := strings.TrimSpace(state.String())
  3547  	expected := strings.TrimSpace(testTerraformApplyOutputMultiStr)
  3548  	if actual != expected {
  3549  		t.Fatalf("bad: \n%s", actual)
  3550  	}
  3551  }
  3552  
  3553  func TestContext2Apply_outputMultiIndex(t *testing.T) {
  3554  	m := testModule(t, "apply-output-multi-index")
  3555  	p := testProvider("aws")
  3556  	p.ApplyFn = testApplyFn
  3557  	p.DiffFn = testDiffFn
  3558  	ctx := testContext2(t, &ContextOpts{
  3559  		Module: m,
  3560  		Providers: map[string]ResourceProviderFactory{
  3561  			"aws": testProviderFuncFixed(p),
  3562  		},
  3563  	})
  3564  
  3565  	if _, err := ctx.Plan(); err != nil {
  3566  		t.Fatalf("err: %s", err)
  3567  	}
  3568  
  3569  	state, err := ctx.Apply()
  3570  	if err != nil {
  3571  		t.Fatalf("err: %s", err)
  3572  	}
  3573  
  3574  	actual := strings.TrimSpace(state.String())
  3575  	expected := strings.TrimSpace(testTerraformApplyOutputMultiIndexStr)
  3576  	if actual != expected {
  3577  		t.Fatalf("bad: \n%s", actual)
  3578  	}
  3579  }
  3580  
  3581  func TestContext2Apply_taint(t *testing.T) {
  3582  	m := testModule(t, "apply-taint")
  3583  	p := testProvider("aws")
  3584  
  3585  	// destroyCount tests against regression of
  3586  	// https://github.com/hashicorp/terraform/issues/1056
  3587  	var destroyCount = int32(0)
  3588  	var once sync.Once
  3589  	simulateProviderDelay := func() {
  3590  		time.Sleep(10 * time.Millisecond)
  3591  	}
  3592  
  3593  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  3594  		once.Do(simulateProviderDelay)
  3595  		if d.Destroy {
  3596  			atomic.AddInt32(&destroyCount, 1)
  3597  		}
  3598  		return testApplyFn(info, s, d)
  3599  	}
  3600  	p.DiffFn = testDiffFn
  3601  	s := &State{
  3602  		Modules: []*ModuleState{
  3603  			&ModuleState{
  3604  				Path: rootModulePath,
  3605  				Resources: map[string]*ResourceState{
  3606  					"aws_instance.bar": &ResourceState{
  3607  						Type: "aws_instance",
  3608  						Primary: &InstanceState{
  3609  							ID: "baz",
  3610  							Attributes: map[string]string{
  3611  								"num":  "2",
  3612  								"type": "aws_instance",
  3613  							},
  3614  							Tainted: true,
  3615  						},
  3616  					},
  3617  				},
  3618  			},
  3619  		},
  3620  	}
  3621  	ctx := testContext2(t, &ContextOpts{
  3622  		Module: m,
  3623  		Providers: map[string]ResourceProviderFactory{
  3624  			"aws": testProviderFuncFixed(p),
  3625  		},
  3626  		State: s,
  3627  	})
  3628  
  3629  	if _, err := ctx.Plan(); err != nil {
  3630  		t.Fatalf("err: %s", err)
  3631  	}
  3632  
  3633  	state, err := ctx.Apply()
  3634  	if err != nil {
  3635  		t.Fatalf("err: %s", err)
  3636  	}
  3637  
  3638  	actual := strings.TrimSpace(state.String())
  3639  	expected := strings.TrimSpace(testTerraformApplyTaintStr)
  3640  	if actual != expected {
  3641  		t.Fatalf("bad:\n%s", actual)
  3642  	}
  3643  
  3644  	if destroyCount != 1 {
  3645  		t.Fatalf("Expected 1 destroy, got %d", destroyCount)
  3646  	}
  3647  }
  3648  
  3649  func TestContext2Apply_taintDep(t *testing.T) {
  3650  	m := testModule(t, "apply-taint-dep")
  3651  	p := testProvider("aws")
  3652  	p.ApplyFn = testApplyFn
  3653  	p.DiffFn = testDiffFn
  3654  	s := &State{
  3655  		Modules: []*ModuleState{
  3656  			&ModuleState{
  3657  				Path: rootModulePath,
  3658  				Resources: map[string]*ResourceState{
  3659  					"aws_instance.foo": &ResourceState{
  3660  						Type: "aws_instance",
  3661  						Primary: &InstanceState{
  3662  							ID: "baz",
  3663  							Attributes: map[string]string{
  3664  								"num":  "2",
  3665  								"type": "aws_instance",
  3666  							},
  3667  							Tainted: true,
  3668  						},
  3669  					},
  3670  					"aws_instance.bar": &ResourceState{
  3671  						Type: "aws_instance",
  3672  						Primary: &InstanceState{
  3673  							ID: "bar",
  3674  							Attributes: map[string]string{
  3675  								"foo":  "baz",
  3676  								"num":  "2",
  3677  								"type": "aws_instance",
  3678  							},
  3679  						},
  3680  					},
  3681  				},
  3682  			},
  3683  		},
  3684  	}
  3685  	ctx := testContext2(t, &ContextOpts{
  3686  		Module: m,
  3687  		Providers: map[string]ResourceProviderFactory{
  3688  			"aws": testProviderFuncFixed(p),
  3689  		},
  3690  		State: s,
  3691  	})
  3692  
  3693  	if p, err := ctx.Plan(); err != nil {
  3694  		t.Fatalf("err: %s", err)
  3695  	} else {
  3696  		t.Logf("plan: %s", p)
  3697  	}
  3698  
  3699  	state, err := ctx.Apply()
  3700  	if err != nil {
  3701  		t.Fatalf("err: %s", err)
  3702  	}
  3703  
  3704  	actual := strings.TrimSpace(state.String())
  3705  	expected := strings.TrimSpace(testTerraformApplyTaintDepStr)
  3706  	if actual != expected {
  3707  		t.Fatalf("bad:\n%s", actual)
  3708  	}
  3709  }
  3710  
  3711  func TestContext2Apply_taintDepRequiresNew(t *testing.T) {
  3712  	m := testModule(t, "apply-taint-dep-requires-new")
  3713  	p := testProvider("aws")
  3714  	p.ApplyFn = testApplyFn
  3715  	p.DiffFn = testDiffFn
  3716  	s := &State{
  3717  		Modules: []*ModuleState{
  3718  			&ModuleState{
  3719  				Path: rootModulePath,
  3720  				Resources: map[string]*ResourceState{
  3721  					"aws_instance.foo": &ResourceState{
  3722  						Type: "aws_instance",
  3723  						Primary: &InstanceState{
  3724  							ID: "baz",
  3725  							Attributes: map[string]string{
  3726  								"num":  "2",
  3727  								"type": "aws_instance",
  3728  							},
  3729  							Tainted: true,
  3730  						},
  3731  					},
  3732  					"aws_instance.bar": &ResourceState{
  3733  						Type: "aws_instance",
  3734  						Primary: &InstanceState{
  3735  							ID: "bar",
  3736  							Attributes: map[string]string{
  3737  								"foo":  "baz",
  3738  								"num":  "2",
  3739  								"type": "aws_instance",
  3740  							},
  3741  						},
  3742  					},
  3743  				},
  3744  			},
  3745  		},
  3746  	}
  3747  	ctx := testContext2(t, &ContextOpts{
  3748  		Module: m,
  3749  		Providers: map[string]ResourceProviderFactory{
  3750  			"aws": testProviderFuncFixed(p),
  3751  		},
  3752  		State: s,
  3753  	})
  3754  
  3755  	if p, err := ctx.Plan(); err != nil {
  3756  		t.Fatalf("err: %s", err)
  3757  	} else {
  3758  		t.Logf("plan: %s", p)
  3759  	}
  3760  
  3761  	state, err := ctx.Apply()
  3762  	if err != nil {
  3763  		t.Fatalf("err: %s", err)
  3764  	}
  3765  
  3766  	actual := strings.TrimSpace(state.String())
  3767  	expected := strings.TrimSpace(testTerraformApplyTaintDepRequireNewStr)
  3768  	if actual != expected {
  3769  		t.Fatalf("bad:\n%s", actual)
  3770  	}
  3771  }
  3772  
  3773  func TestContext2Apply_targeted(t *testing.T) {
  3774  	m := testModule(t, "apply-targeted")
  3775  	p := testProvider("aws")
  3776  	p.ApplyFn = testApplyFn
  3777  	p.DiffFn = testDiffFn
  3778  	ctx := testContext2(t, &ContextOpts{
  3779  		Module: m,
  3780  		Providers: map[string]ResourceProviderFactory{
  3781  			"aws": testProviderFuncFixed(p),
  3782  		},
  3783  		Targets: []string{"aws_instance.foo"},
  3784  	})
  3785  
  3786  	if _, err := ctx.Plan(); err != nil {
  3787  		t.Fatalf("err: %s", err)
  3788  	}
  3789  
  3790  	state, err := ctx.Apply()
  3791  	if err != nil {
  3792  		t.Fatalf("err: %s", err)
  3793  	}
  3794  
  3795  	mod := state.RootModule()
  3796  	if len(mod.Resources) != 1 {
  3797  		t.Fatalf("expected 1 resource, got: %#v", mod.Resources)
  3798  	}
  3799  
  3800  	checkStateString(t, state, `
  3801  aws_instance.foo:
  3802    ID = foo
  3803    num = 2
  3804    type = aws_instance
  3805  	`)
  3806  }
  3807  
  3808  func TestContext2Apply_targetedCount(t *testing.T) {
  3809  	m := testModule(t, "apply-targeted-count")
  3810  	p := testProvider("aws")
  3811  	p.ApplyFn = testApplyFn
  3812  	p.DiffFn = testDiffFn
  3813  	ctx := testContext2(t, &ContextOpts{
  3814  		Module: m,
  3815  		Providers: map[string]ResourceProviderFactory{
  3816  			"aws": testProviderFuncFixed(p),
  3817  		},
  3818  		Targets: []string{"aws_instance.foo"},
  3819  	})
  3820  
  3821  	if _, err := ctx.Plan(); err != nil {
  3822  		t.Fatalf("err: %s", err)
  3823  	}
  3824  
  3825  	state, err := ctx.Apply()
  3826  	if err != nil {
  3827  		t.Fatalf("err: %s", err)
  3828  	}
  3829  
  3830  	checkStateString(t, state, `
  3831  aws_instance.foo.0:
  3832    ID = foo
  3833  aws_instance.foo.1:
  3834    ID = foo
  3835  aws_instance.foo.2:
  3836    ID = foo
  3837  	`)
  3838  }
  3839  
  3840  func TestContext2Apply_targetedCountIndex(t *testing.T) {
  3841  	m := testModule(t, "apply-targeted-count")
  3842  	p := testProvider("aws")
  3843  	p.ApplyFn = testApplyFn
  3844  	p.DiffFn = testDiffFn
  3845  	ctx := testContext2(t, &ContextOpts{
  3846  		Module: m,
  3847  		Providers: map[string]ResourceProviderFactory{
  3848  			"aws": testProviderFuncFixed(p),
  3849  		},
  3850  		Targets: []string{"aws_instance.foo[1]"},
  3851  	})
  3852  
  3853  	if _, err := ctx.Plan(); err != nil {
  3854  		t.Fatalf("err: %s", err)
  3855  	}
  3856  
  3857  	state, err := ctx.Apply()
  3858  	if err != nil {
  3859  		t.Fatalf("err: %s", err)
  3860  	}
  3861  
  3862  	checkStateString(t, state, `
  3863  aws_instance.foo.1:
  3864    ID = foo
  3865  	`)
  3866  }
  3867  
  3868  func TestContext2Apply_targetedDestroy(t *testing.T) {
  3869  	m := testModule(t, "apply-targeted")
  3870  	p := testProvider("aws")
  3871  	p.ApplyFn = testApplyFn
  3872  	p.DiffFn = testDiffFn
  3873  	ctx := testContext2(t, &ContextOpts{
  3874  		Module: m,
  3875  		Providers: map[string]ResourceProviderFactory{
  3876  			"aws": testProviderFuncFixed(p),
  3877  		},
  3878  		State: &State{
  3879  			Modules: []*ModuleState{
  3880  				&ModuleState{
  3881  					Path: rootModulePath,
  3882  					Resources: map[string]*ResourceState{
  3883  						"aws_instance.foo": resourceState("aws_instance", "i-bcd345"),
  3884  						"aws_instance.bar": resourceState("aws_instance", "i-abc123"),
  3885  					},
  3886  				},
  3887  			},
  3888  		},
  3889  		Targets: []string{"aws_instance.foo"},
  3890  		Destroy: true,
  3891  	})
  3892  
  3893  	if _, err := ctx.Plan(); err != nil {
  3894  		t.Fatalf("err: %s", err)
  3895  	}
  3896  
  3897  	state, err := ctx.Apply()
  3898  	if err != nil {
  3899  		t.Fatalf("err: %s", err)
  3900  	}
  3901  
  3902  	mod := state.RootModule()
  3903  	if len(mod.Resources) != 1 {
  3904  		t.Fatalf("expected 1 resource, got: %#v", mod.Resources)
  3905  	}
  3906  
  3907  	checkStateString(t, state, `
  3908  aws_instance.bar:
  3909    ID = i-abc123
  3910  	`)
  3911  }
  3912  
  3913  // https://github.com/hashicorp/terraform/issues/4462
  3914  func TestContext2Apply_targetedDestroyModule(t *testing.T) {
  3915  	m := testModule(t, "apply-targeted-module")
  3916  	p := testProvider("aws")
  3917  	p.ApplyFn = testApplyFn
  3918  	p.DiffFn = testDiffFn
  3919  	ctx := testContext2(t, &ContextOpts{
  3920  		Module: m,
  3921  		Providers: map[string]ResourceProviderFactory{
  3922  			"aws": testProviderFuncFixed(p),
  3923  		},
  3924  		State: &State{
  3925  			Modules: []*ModuleState{
  3926  				&ModuleState{
  3927  					Path: rootModulePath,
  3928  					Resources: map[string]*ResourceState{
  3929  						"aws_instance.foo": resourceState("aws_instance", "i-bcd345"),
  3930  						"aws_instance.bar": resourceState("aws_instance", "i-abc123"),
  3931  					},
  3932  				},
  3933  				&ModuleState{
  3934  					Path: []string{"root", "child"},
  3935  					Resources: map[string]*ResourceState{
  3936  						"aws_instance.foo": resourceState("aws_instance", "i-bcd345"),
  3937  						"aws_instance.bar": resourceState("aws_instance", "i-abc123"),
  3938  					},
  3939  				},
  3940  			},
  3941  		},
  3942  		Targets: []string{"module.child.aws_instance.foo"},
  3943  		Destroy: true,
  3944  	})
  3945  
  3946  	if _, err := ctx.Plan(); err != nil {
  3947  		t.Fatalf("err: %s", err)
  3948  	}
  3949  
  3950  	state, err := ctx.Apply()
  3951  	if err != nil {
  3952  		t.Fatalf("err: %s", err)
  3953  	}
  3954  
  3955  	checkStateString(t, state, `
  3956  aws_instance.bar:
  3957    ID = i-abc123
  3958  aws_instance.foo:
  3959    ID = i-bcd345
  3960  
  3961  module.child:
  3962    aws_instance.bar:
  3963      ID = i-abc123
  3964  	`)
  3965  }
  3966  
  3967  func TestContext2Apply_targetedDestroyCountIndex(t *testing.T) {
  3968  	m := testModule(t, "apply-targeted-count")
  3969  	p := testProvider("aws")
  3970  	p.ApplyFn = testApplyFn
  3971  	p.DiffFn = testDiffFn
  3972  	ctx := testContext2(t, &ContextOpts{
  3973  		Module: m,
  3974  		Providers: map[string]ResourceProviderFactory{
  3975  			"aws": testProviderFuncFixed(p),
  3976  		},
  3977  		State: &State{
  3978  			Modules: []*ModuleState{
  3979  				&ModuleState{
  3980  					Path: rootModulePath,
  3981  					Resources: map[string]*ResourceState{
  3982  						"aws_instance.foo.0": resourceState("aws_instance", "i-bcd345"),
  3983  						"aws_instance.foo.1": resourceState("aws_instance", "i-bcd345"),
  3984  						"aws_instance.foo.2": resourceState("aws_instance", "i-bcd345"),
  3985  						"aws_instance.bar.0": resourceState("aws_instance", "i-abc123"),
  3986  						"aws_instance.bar.1": resourceState("aws_instance", "i-abc123"),
  3987  						"aws_instance.bar.2": resourceState("aws_instance", "i-abc123"),
  3988  					},
  3989  				},
  3990  			},
  3991  		},
  3992  		Targets: []string{
  3993  			"aws_instance.foo[2]",
  3994  			"aws_instance.bar[1]",
  3995  		},
  3996  		Destroy: true,
  3997  	})
  3998  
  3999  	if _, err := ctx.Plan(); err != nil {
  4000  		t.Fatalf("err: %s", err)
  4001  	}
  4002  
  4003  	state, err := ctx.Apply()
  4004  	if err != nil {
  4005  		t.Fatalf("err: %s", err)
  4006  	}
  4007  
  4008  	checkStateString(t, state, `
  4009  aws_instance.bar.0:
  4010    ID = i-abc123
  4011  aws_instance.bar.2:
  4012    ID = i-abc123
  4013  aws_instance.foo.0:
  4014    ID = i-bcd345
  4015  aws_instance.foo.1:
  4016    ID = i-bcd345
  4017  	`)
  4018  }
  4019  
  4020  func TestContext2Apply_targetedModule(t *testing.T) {
  4021  	m := testModule(t, "apply-targeted-module")
  4022  	p := testProvider("aws")
  4023  	p.ApplyFn = testApplyFn
  4024  	p.DiffFn = testDiffFn
  4025  	ctx := testContext2(t, &ContextOpts{
  4026  		Module: m,
  4027  		Providers: map[string]ResourceProviderFactory{
  4028  			"aws": testProviderFuncFixed(p),
  4029  		},
  4030  		Targets: []string{"module.child"},
  4031  	})
  4032  
  4033  	if _, err := ctx.Plan(); err != nil {
  4034  		t.Fatalf("err: %s", err)
  4035  	}
  4036  
  4037  	state, err := ctx.Apply()
  4038  	if err != nil {
  4039  		t.Fatalf("err: %s", err)
  4040  	}
  4041  
  4042  	mod := state.ModuleByPath([]string{"root", "child"})
  4043  	if mod == nil {
  4044  		t.Fatalf("no child module found in the state!\n\n%#v", state)
  4045  	}
  4046  	if len(mod.Resources) != 2 {
  4047  		t.Fatalf("expected 2 resources, got: %#v", mod.Resources)
  4048  	}
  4049  
  4050  	checkStateString(t, state, `
  4051  <no state>
  4052  module.child:
  4053    aws_instance.bar:
  4054      ID = foo
  4055      num = 2
  4056      type = aws_instance
  4057    aws_instance.foo:
  4058      ID = foo
  4059      num = 2
  4060      type = aws_instance
  4061  	`)
  4062  }
  4063  
  4064  // GH-1858
  4065  func TestContext2Apply_targetedModuleDep(t *testing.T) {
  4066  	m := testModule(t, "apply-targeted-module-dep")
  4067  	p := testProvider("aws")
  4068  	p.ApplyFn = testApplyFn
  4069  	p.DiffFn = testDiffFn
  4070  	ctx := testContext2(t, &ContextOpts{
  4071  		Module: m,
  4072  		Providers: map[string]ResourceProviderFactory{
  4073  			"aws": testProviderFuncFixed(p),
  4074  		},
  4075  		Targets: []string{"aws_instance.foo"},
  4076  	})
  4077  
  4078  	if _, err := ctx.Plan(); err != nil {
  4079  		t.Fatalf("err: %s", err)
  4080  	}
  4081  
  4082  	state, err := ctx.Apply()
  4083  	if err != nil {
  4084  		t.Fatalf("err: %s", err)
  4085  	}
  4086  
  4087  	checkStateString(t, state, `
  4088  aws_instance.foo:
  4089    ID = foo
  4090    foo = foo
  4091    type = aws_instance
  4092  
  4093    Dependencies:
  4094      module.child
  4095  
  4096  module.child:
  4097    aws_instance.mod:
  4098      ID = foo
  4099  
  4100    Outputs:
  4101  
  4102    output = foo
  4103  	`)
  4104  }
  4105  
  4106  func TestContext2Apply_targetedModuleResource(t *testing.T) {
  4107  	m := testModule(t, "apply-targeted-module-resource")
  4108  	p := testProvider("aws")
  4109  	p.ApplyFn = testApplyFn
  4110  	p.DiffFn = testDiffFn
  4111  	ctx := testContext2(t, &ContextOpts{
  4112  		Module: m,
  4113  		Providers: map[string]ResourceProviderFactory{
  4114  			"aws": testProviderFuncFixed(p),
  4115  		},
  4116  		Targets: []string{"module.child.aws_instance.foo"},
  4117  	})
  4118  
  4119  	if _, err := ctx.Plan(); err != nil {
  4120  		t.Fatalf("err: %s", err)
  4121  	}
  4122  
  4123  	state, err := ctx.Apply()
  4124  	if err != nil {
  4125  		t.Fatalf("err: %s", err)
  4126  	}
  4127  
  4128  	mod := state.ModuleByPath([]string{"root", "child"})
  4129  	if len(mod.Resources) != 1 {
  4130  		t.Fatalf("expected 1 resource, got: %#v", mod.Resources)
  4131  	}
  4132  
  4133  	checkStateString(t, state, `
  4134  <no state>
  4135  module.child:
  4136    aws_instance.foo:
  4137      ID = foo
  4138      num = 2
  4139      type = aws_instance
  4140  	`)
  4141  }
  4142  
  4143  func TestContext2Apply_unknownAttribute(t *testing.T) {
  4144  	m := testModule(t, "apply-unknown")
  4145  	p := testProvider("aws")
  4146  	p.ApplyFn = testApplyFn
  4147  	p.DiffFn = testDiffFn
  4148  	ctx := testContext2(t, &ContextOpts{
  4149  		Module: m,
  4150  		Providers: map[string]ResourceProviderFactory{
  4151  			"aws": testProviderFuncFixed(p),
  4152  		},
  4153  	})
  4154  
  4155  	if _, err := ctx.Plan(); err != nil {
  4156  		t.Fatalf("err: %s", err)
  4157  	}
  4158  
  4159  	state, err := ctx.Apply()
  4160  	if err == nil {
  4161  		t.Fatal("should error")
  4162  	}
  4163  
  4164  	actual := strings.TrimSpace(state.String())
  4165  	expected := strings.TrimSpace(testTerraformApplyUnknownAttrStr)
  4166  	if actual != expected {
  4167  		t.Fatalf("bad: \n%s", actual)
  4168  	}
  4169  }
  4170  
  4171  func TestContext2Apply_unknownAttributeInterpolate(t *testing.T) {
  4172  	m := testModule(t, "apply-unknown-interpolate")
  4173  	p := testProvider("aws")
  4174  	p.ApplyFn = testApplyFn
  4175  	p.DiffFn = testDiffFn
  4176  	ctx := testContext2(t, &ContextOpts{
  4177  		Module: m,
  4178  		Providers: map[string]ResourceProviderFactory{
  4179  			"aws": testProviderFuncFixed(p),
  4180  		},
  4181  	})
  4182  
  4183  	if _, err := ctx.Plan(); err == nil {
  4184  		t.Fatal("should error")
  4185  	}
  4186  }
  4187  
  4188  func TestContext2Apply_vars(t *testing.T) {
  4189  	m := testModule(t, "apply-vars")
  4190  	p := testProvider("aws")
  4191  	p.ApplyFn = testApplyFn
  4192  	p.DiffFn = testDiffFn
  4193  	ctx := testContext2(t, &ContextOpts{
  4194  		Module: m,
  4195  		Providers: map[string]ResourceProviderFactory{
  4196  			"aws": testProviderFuncFixed(p),
  4197  		},
  4198  		Variables: map[string]string{
  4199  			"foo":            "us-west-2",
  4200  			"amis.us-east-1": "override",
  4201  		},
  4202  	})
  4203  
  4204  	w, e := ctx.Validate()
  4205  	if len(w) > 0 {
  4206  		t.Fatalf("bad: %#v", w)
  4207  	}
  4208  	if len(e) > 0 {
  4209  		t.Fatalf("bad: %s", e)
  4210  	}
  4211  
  4212  	if _, err := ctx.Plan(); err != nil {
  4213  		t.Fatalf("err: %s", err)
  4214  	}
  4215  
  4216  	state, err := ctx.Apply()
  4217  	if err != nil {
  4218  		t.Fatalf("err: %s", err)
  4219  	}
  4220  
  4221  	actual := strings.TrimSpace(state.String())
  4222  	expected := strings.TrimSpace(testTerraformApplyVarsStr)
  4223  	if actual != expected {
  4224  		t.Fatalf("expected: %s\n got:\n%s", expected, actual)
  4225  	}
  4226  }
  4227  
  4228  func TestContext2Apply_varsEnv(t *testing.T) {
  4229  	// Set the env var
  4230  	old := tempEnv(t, "TF_VAR_ami", "baz")
  4231  	defer os.Setenv("TF_VAR_ami", old)
  4232  
  4233  	m := testModule(t, "apply-vars-env")
  4234  	p := testProvider("aws")
  4235  	p.ApplyFn = testApplyFn
  4236  	p.DiffFn = testDiffFn
  4237  	ctx := testContext2(t, &ContextOpts{
  4238  		Module: m,
  4239  		Providers: map[string]ResourceProviderFactory{
  4240  			"aws": testProviderFuncFixed(p),
  4241  		},
  4242  	})
  4243  
  4244  	w, e := ctx.Validate()
  4245  	if len(w) > 0 {
  4246  		t.Fatalf("bad: %#v", w)
  4247  	}
  4248  	if len(e) > 0 {
  4249  		t.Fatalf("bad: %s", e)
  4250  	}
  4251  
  4252  	if _, err := ctx.Plan(); err != nil {
  4253  		t.Fatalf("err: %s", err)
  4254  	}
  4255  
  4256  	state, err := ctx.Apply()
  4257  	if err != nil {
  4258  		t.Fatalf("err: %s", err)
  4259  	}
  4260  
  4261  	actual := strings.TrimSpace(state.String())
  4262  	expected := strings.TrimSpace(testTerraformApplyVarsEnvStr)
  4263  	if actual != expected {
  4264  		t.Fatalf("bad: \n%s", actual)
  4265  	}
  4266  }
  4267  
  4268  func TestContext2Apply_createBefore_depends(t *testing.T) {
  4269  	m := testModule(t, "apply-depends-create-before")
  4270  	h := new(HookRecordApplyOrder)
  4271  	p := testProvider("aws")
  4272  	p.ApplyFn = testApplyFn
  4273  	p.DiffFn = testDiffFn
  4274  	state := &State{
  4275  		Modules: []*ModuleState{
  4276  			&ModuleState{
  4277  				Path: rootModulePath,
  4278  				Resources: map[string]*ResourceState{
  4279  					"aws_instance.web": &ResourceState{
  4280  						Type: "aws_instance",
  4281  						Primary: &InstanceState{
  4282  							ID: "bar",
  4283  							Attributes: map[string]string{
  4284  								"require_new": "ami-old",
  4285  							},
  4286  						},
  4287  					},
  4288  					"aws_instance.lb": &ResourceState{
  4289  						Type: "aws_instance",
  4290  						Primary: &InstanceState{
  4291  							ID: "baz",
  4292  							Attributes: map[string]string{
  4293  								"instance": "bar",
  4294  							},
  4295  						},
  4296  					},
  4297  				},
  4298  			},
  4299  		},
  4300  	}
  4301  	ctx := testContext2(t, &ContextOpts{
  4302  		Module: m,
  4303  		Hooks:  []Hook{h},
  4304  		Providers: map[string]ResourceProviderFactory{
  4305  			"aws": testProviderFuncFixed(p),
  4306  		},
  4307  		State: state,
  4308  	})
  4309  
  4310  	if _, err := ctx.Plan(); err != nil {
  4311  		t.Fatalf("err: %s", err)
  4312  	}
  4313  
  4314  	h.Active = true
  4315  	state, err := ctx.Apply()
  4316  	if err != nil {
  4317  		t.Fatalf("err: %s", err)
  4318  	}
  4319  
  4320  	mod := state.RootModule()
  4321  	if len(mod.Resources) < 2 {
  4322  		t.Fatalf("bad: %#v", mod.Resources)
  4323  	}
  4324  
  4325  	actual := strings.TrimSpace(state.String())
  4326  	expected := strings.TrimSpace(testTerraformApplyDependsCreateBeforeStr)
  4327  	if actual != expected {
  4328  		t.Fatalf("bad: \n%s\n%s", actual, expected)
  4329  	}
  4330  
  4331  	// Test that things were managed _in the right order_
  4332  	order := h.States
  4333  	diffs := h.Diffs
  4334  	if order[0].ID != "" || diffs[0].Destroy {
  4335  		t.Fatalf("should create new instance first: %#v", order)
  4336  	}
  4337  
  4338  	if order[1].ID != "baz" {
  4339  		t.Fatalf("update must happen after create: %#v", order)
  4340  	}
  4341  
  4342  	if order[2].ID != "bar" || !diffs[2].Destroy {
  4343  		t.Fatalf("destroy must happen after update: %#v", order)
  4344  	}
  4345  }
  4346  
  4347  func TestContext2Apply_singleDestroy(t *testing.T) {
  4348  	m := testModule(t, "apply-depends-create-before")
  4349  	h := new(HookRecordApplyOrder)
  4350  	p := testProvider("aws")
  4351  
  4352  	invokeCount := 0
  4353  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  4354  		invokeCount++
  4355  		switch invokeCount {
  4356  		case 1:
  4357  			if d.Destroy {
  4358  				t.Fatalf("should not destroy")
  4359  			}
  4360  			if s.ID != "" {
  4361  				t.Fatalf("should not have ID")
  4362  			}
  4363  		case 2:
  4364  			if d.Destroy {
  4365  				t.Fatalf("should not destroy")
  4366  			}
  4367  			if s.ID != "baz" {
  4368  				t.Fatalf("should have id")
  4369  			}
  4370  		case 3:
  4371  			if !d.Destroy {
  4372  				t.Fatalf("should destroy")
  4373  			}
  4374  			if s.ID == "" {
  4375  				t.Fatalf("should have ID")
  4376  			}
  4377  		default:
  4378  			t.Fatalf("bad invoke count %d", invokeCount)
  4379  		}
  4380  		return testApplyFn(info, s, d)
  4381  	}
  4382  	p.DiffFn = testDiffFn
  4383  	state := &State{
  4384  		Modules: []*ModuleState{
  4385  			&ModuleState{
  4386  				Path: rootModulePath,
  4387  				Resources: map[string]*ResourceState{
  4388  					"aws_instance.web": &ResourceState{
  4389  						Type: "aws_instance",
  4390  						Primary: &InstanceState{
  4391  							ID: "bar",
  4392  							Attributes: map[string]string{
  4393  								"require_new": "ami-old",
  4394  							},
  4395  						},
  4396  					},
  4397  					"aws_instance.lb": &ResourceState{
  4398  						Type: "aws_instance",
  4399  						Primary: &InstanceState{
  4400  							ID: "baz",
  4401  							Attributes: map[string]string{
  4402  								"instance": "bar",
  4403  							},
  4404  						},
  4405  					},
  4406  				},
  4407  			},
  4408  		},
  4409  	}
  4410  	ctx := testContext2(t, &ContextOpts{
  4411  		Module: m,
  4412  		Hooks:  []Hook{h},
  4413  		Providers: map[string]ResourceProviderFactory{
  4414  			"aws": testProviderFuncFixed(p),
  4415  		},
  4416  		State: state,
  4417  	})
  4418  
  4419  	if _, err := ctx.Plan(); err != nil {
  4420  		t.Fatalf("err: %s", err)
  4421  	}
  4422  
  4423  	h.Active = true
  4424  	state, err := ctx.Apply()
  4425  	if err != nil {
  4426  		t.Fatalf("err: %s", err)
  4427  	}
  4428  
  4429  	if invokeCount != 3 {
  4430  		t.Fatalf("bad: %d", invokeCount)
  4431  	}
  4432  }
  4433  
  4434  // GH-5254
  4435  func TestContext2Apply_issue5254(t *testing.T) {
  4436  	// Create a provider. We use "template" here just to match the repro
  4437  	// we got from the issue itself.
  4438  	p := testProvider("template")
  4439  	p.ResourcesReturn = append(p.ResourcesReturn, ResourceType{
  4440  		Name: "template_file",
  4441  	})
  4442  
  4443  	p.ApplyFn = testApplyFn
  4444  	p.DiffFn = testDiffFn
  4445  
  4446  	// Apply cleanly step 0
  4447  	ctx := testContext2(t, &ContextOpts{
  4448  		Module: testModule(t, "issue-5254/step-0"),
  4449  		Providers: map[string]ResourceProviderFactory{
  4450  			"template": testProviderFuncFixed(p),
  4451  		},
  4452  	})
  4453  
  4454  	plan, err := ctx.Plan()
  4455  	if err != nil {
  4456  		t.Fatalf("err: %s", err)
  4457  	}
  4458  
  4459  	state, err := ctx.Apply()
  4460  	if err != nil {
  4461  		t.Fatalf("err: %s", err)
  4462  	}
  4463  
  4464  	// Application success. Now make the modification and store a plan
  4465  	ctx = testContext2(t, &ContextOpts{
  4466  		Module: testModule(t, "issue-5254/step-1"),
  4467  		State:  state,
  4468  		Providers: map[string]ResourceProviderFactory{
  4469  			"template": testProviderFuncFixed(p),
  4470  		},
  4471  	})
  4472  
  4473  	plan, err = ctx.Plan()
  4474  	if err != nil {
  4475  		t.Fatalf("err: %s", err)
  4476  	}
  4477  
  4478  	// Write / Read plan to simulate running it through a Plan file
  4479  	var buf bytes.Buffer
  4480  	if err := WritePlan(plan, &buf); err != nil {
  4481  		t.Fatalf("err: %s", err)
  4482  	}
  4483  
  4484  	planFromFile, err := ReadPlan(&buf)
  4485  	if err != nil {
  4486  		t.Fatalf("err: %s", err)
  4487  	}
  4488  
  4489  	ctx, err = planFromFile.Context(&ContextOpts{
  4490  		Providers: map[string]ResourceProviderFactory{
  4491  			"template": testProviderFuncFixed(p),
  4492  		},
  4493  	})
  4494  	if err != nil {
  4495  		t.Fatalf("err: %s", err)
  4496  	}
  4497  
  4498  	state, err = ctx.Apply()
  4499  	if err != nil {
  4500  		t.Fatalf("err: %s", err)
  4501  	}
  4502  
  4503  	actual := strings.TrimSpace(state.String())
  4504  	expected := strings.TrimSpace(`
  4505  template_file.child:
  4506    ID = foo
  4507    template = Hi
  4508    type = template_file
  4509  
  4510    Dependencies:
  4511      template_file.parent
  4512  template_file.parent:
  4513    ID = foo
  4514    template = Hi
  4515    type = template_file
  4516  		`)
  4517  	if actual != expected {
  4518  		t.Fatalf("expected state: \n%s\ngot: \n%s", expected, actual)
  4519  	}
  4520  }
  4521  
  4522  func TestContext2Apply_targetedWithTaintedInState(t *testing.T) {
  4523  	p := testProvider("aws")
  4524  	p.DiffFn = testDiffFn
  4525  	p.ApplyFn = testApplyFn
  4526  	ctx := testContext2(t, &ContextOpts{
  4527  		Module: testModule(t, "apply-tainted-targets"),
  4528  		Providers: map[string]ResourceProviderFactory{
  4529  			"aws": testProviderFuncFixed(p),
  4530  		},
  4531  		Targets: []string{"aws_instance.iambeingadded"},
  4532  		State: &State{
  4533  			Modules: []*ModuleState{
  4534  				&ModuleState{
  4535  					Path: rootModulePath,
  4536  					Resources: map[string]*ResourceState{
  4537  						"aws_instance.ifailedprovisioners": &ResourceState{
  4538  							Primary: &InstanceState{
  4539  								ID:      "ifailedprovisioners",
  4540  								Tainted: true,
  4541  							},
  4542  						},
  4543  					},
  4544  				},
  4545  			},
  4546  		},
  4547  	})
  4548  
  4549  	plan, err := ctx.Plan()
  4550  	if err != nil {
  4551  		t.Fatalf("err: %s", err)
  4552  	}
  4553  
  4554  	// Write / Read plan to simulate running it through a Plan file
  4555  	var buf bytes.Buffer
  4556  	if err := WritePlan(plan, &buf); err != nil {
  4557  		t.Fatalf("err: %s", err)
  4558  	}
  4559  
  4560  	planFromFile, err := ReadPlan(&buf)
  4561  	if err != nil {
  4562  		t.Fatalf("err: %s", err)
  4563  	}
  4564  
  4565  	ctx, err = planFromFile.Context(&ContextOpts{
  4566  		Module: testModule(t, "apply-tainted-targets"),
  4567  		Providers: map[string]ResourceProviderFactory{
  4568  			"aws": testProviderFuncFixed(p),
  4569  		},
  4570  	})
  4571  	if err != nil {
  4572  		t.Fatalf("err: %s", err)
  4573  	}
  4574  
  4575  	state, err := ctx.Apply()
  4576  	if err != nil {
  4577  		t.Fatalf("err: %s", err)
  4578  	}
  4579  
  4580  	actual := strings.TrimSpace(state.String())
  4581  	expected := strings.TrimSpace(`
  4582  aws_instance.iambeingadded:
  4583    ID = foo
  4584  aws_instance.ifailedprovisioners: (tainted)
  4585    ID = ifailedprovisioners
  4586  		`)
  4587  	if actual != expected {
  4588  		t.Fatalf("expected state: \n%s\ngot: \n%s", expected, actual)
  4589  	}
  4590  }
  4591  
  4592  // Higher level test exposing the bug this covers in
  4593  // TestResource_ignoreChangesRequired
  4594  func TestContext2Apply_ignoreChangesCreate(t *testing.T) {
  4595  	m := testModule(t, "apply-ignore-changes-create")
  4596  	p := testProvider("aws")
  4597  	p.ApplyFn = testApplyFn
  4598  	p.DiffFn = testDiffFn
  4599  	ctx := testContext2(t, &ContextOpts{
  4600  		Module: m,
  4601  		Providers: map[string]ResourceProviderFactory{
  4602  			"aws": testProviderFuncFixed(p),
  4603  		},
  4604  	})
  4605  
  4606  	if p, err := ctx.Plan(); err != nil {
  4607  		t.Fatalf("err: %s", err)
  4608  	} else {
  4609  		t.Logf(p.String())
  4610  	}
  4611  
  4612  	state, err := ctx.Apply()
  4613  	if err != nil {
  4614  		t.Fatalf("err: %s", err)
  4615  	}
  4616  
  4617  	mod := state.RootModule()
  4618  	if len(mod.Resources) != 1 {
  4619  		t.Fatalf("bad: %s", state)
  4620  	}
  4621  
  4622  	actual := strings.TrimSpace(state.String())
  4623  	// Expect no changes from original state
  4624  	expected := strings.TrimSpace(`
  4625  aws_instance.foo:
  4626    ID = foo
  4627    required_field = set
  4628    type = aws_instance
  4629  `)
  4630  	if actual != expected {
  4631  		t.Fatalf("bad: \n%s", actual)
  4632  	}
  4633  }