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