github.com/tomaszheflik/terraform@v0.7.3-0.20160827060421-32f990b41594/terraform/context_apply_test.go (about)

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