github.com/adrian-bl/terraform@v0.7.0-rc2.0.20160705220747-de0a34fc3517/terraform/context_apply_test.go (about)

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