github.com/ojongerius/terraform@v0.7.1-0.20160811111335-97fcd5f4cc90/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]interface{}{"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]interface{}{
  1138  			"images": []map[string]interface{}{
  1139  				map[string]interface{}{
  1140  					"us-west-2": "overridden",
  1141  				},
  1142  			},
  1143  		},
  1144  	})
  1145  
  1146  	if _, err := ctx.Plan(); err != nil {
  1147  		t.Fatalf("err: %s", err)
  1148  	}
  1149  
  1150  	state, err := ctx.Apply()
  1151  	if err != nil {
  1152  		t.Fatalf("err: %s", err)
  1153  	}
  1154  
  1155  	actual := strings.TrimSpace(state.String())
  1156  	expected := strings.TrimSpace(`
  1157  aws_instance.bar:
  1158    ID = foo
  1159    ami = overridden
  1160    type = aws_instance
  1161  aws_instance.foo:
  1162    ID = foo
  1163    ami = image-1234
  1164    type = aws_instance
  1165  	`)
  1166  	if actual != expected {
  1167  		t.Fatalf("got: \n%s\nexpected: \n%s", actual, expected)
  1168  	}
  1169  }
  1170  
  1171  func TestContext2Apply_module(t *testing.T) {
  1172  	m := testModule(t, "apply-module")
  1173  	p := testProvider("aws")
  1174  	p.ApplyFn = testApplyFn
  1175  	p.DiffFn = testDiffFn
  1176  	ctx := testContext2(t, &ContextOpts{
  1177  		Module: m,
  1178  		Providers: map[string]ResourceProviderFactory{
  1179  			"aws": testProviderFuncFixed(p),
  1180  		},
  1181  	})
  1182  
  1183  	if _, err := ctx.Plan(); err != nil {
  1184  		t.Fatalf("err: %s", err)
  1185  	}
  1186  
  1187  	state, err := ctx.Apply()
  1188  	if err != nil {
  1189  		t.Fatalf("err: %s", err)
  1190  	}
  1191  
  1192  	actual := strings.TrimSpace(state.String())
  1193  	expected := strings.TrimSpace(testTerraformApplyModuleStr)
  1194  	if actual != expected {
  1195  		t.Fatalf("bad: \n%s", actual)
  1196  	}
  1197  }
  1198  
  1199  func TestContext2Apply_moduleDestroyOrder(t *testing.T) {
  1200  	m := testModule(t, "apply-module-destroy-order")
  1201  	p := testProvider("aws")
  1202  	p.DiffFn = testDiffFn
  1203  
  1204  	// Create a custom apply function to track the order they were destroyed
  1205  	var order []string
  1206  	var orderLock sync.Mutex
  1207  	p.ApplyFn = func(
  1208  		info *InstanceInfo,
  1209  		is *InstanceState,
  1210  		id *InstanceDiff) (*InstanceState, error) {
  1211  		orderLock.Lock()
  1212  		defer orderLock.Unlock()
  1213  
  1214  		order = append(order, is.ID)
  1215  		return nil, nil
  1216  	}
  1217  
  1218  	state := &State{
  1219  		Modules: []*ModuleState{
  1220  			&ModuleState{
  1221  				Path: rootModulePath,
  1222  				Resources: map[string]*ResourceState{
  1223  					"aws_instance.b": &ResourceState{
  1224  						Type: "aws_instance",
  1225  						Primary: &InstanceState{
  1226  							ID: "b",
  1227  						},
  1228  					},
  1229  				},
  1230  			},
  1231  
  1232  			&ModuleState{
  1233  				Path: []string{"root", "child"},
  1234  				Resources: map[string]*ResourceState{
  1235  					"aws_instance.a": &ResourceState{
  1236  						Type: "aws_instance",
  1237  						Primary: &InstanceState{
  1238  							ID: "a",
  1239  						},
  1240  					},
  1241  				},
  1242  				Outputs: map[string]*OutputState{
  1243  					"a_output": &OutputState{
  1244  						Type:      "string",
  1245  						Sensitive: false,
  1246  						Value:     "a",
  1247  					},
  1248  				},
  1249  			},
  1250  		},
  1251  	}
  1252  
  1253  	ctx := testContext2(t, &ContextOpts{
  1254  		Module: m,
  1255  		Providers: map[string]ResourceProviderFactory{
  1256  			"aws": testProviderFuncFixed(p),
  1257  		},
  1258  		State:   state,
  1259  		Destroy: true,
  1260  	})
  1261  
  1262  	if _, err := ctx.Plan(); err != nil {
  1263  		t.Fatalf("err: %s", err)
  1264  	}
  1265  
  1266  	state, err := ctx.Apply()
  1267  	if err != nil {
  1268  		t.Fatalf("err: %s", err)
  1269  	}
  1270  
  1271  	expected := []string{"b", "a"}
  1272  	if !reflect.DeepEqual(order, expected) {
  1273  		t.Fatalf("bad: %#v", order)
  1274  	}
  1275  
  1276  	{
  1277  		actual := strings.TrimSpace(state.String())
  1278  		expected := strings.TrimSpace(testTerraformApplyModuleDestroyOrderStr)
  1279  		if actual != expected {
  1280  			t.Fatalf("bad: \n%s", actual)
  1281  		}
  1282  	}
  1283  }
  1284  
  1285  func TestContext2Apply_moduleOrphanProvider(t *testing.T) {
  1286  	m := testModule(t, "apply-module-orphan-provider-inherit")
  1287  	p := testProvider("aws")
  1288  	p.ApplyFn = testApplyFn
  1289  	p.DiffFn = testDiffFn
  1290  
  1291  	p.ConfigureFn = func(c *ResourceConfig) error {
  1292  		if _, ok := c.Get("value"); !ok {
  1293  			return fmt.Errorf("value is not found")
  1294  		}
  1295  
  1296  		return nil
  1297  	}
  1298  
  1299  	// Create a state with an orphan module
  1300  	state := &State{
  1301  		Modules: []*ModuleState{
  1302  			&ModuleState{
  1303  				Path: []string{"root", "child"},
  1304  				Resources: map[string]*ResourceState{
  1305  					"aws_instance.bar": &ResourceState{
  1306  						Type: "aws_instance",
  1307  						Primary: &InstanceState{
  1308  							ID: "bar",
  1309  						},
  1310  					},
  1311  				},
  1312  			},
  1313  		},
  1314  	}
  1315  
  1316  	ctx := testContext2(t, &ContextOpts{
  1317  		Module: m,
  1318  		State:  state,
  1319  		Providers: map[string]ResourceProviderFactory{
  1320  			"aws": testProviderFuncFixed(p),
  1321  		},
  1322  	})
  1323  
  1324  	if _, err := ctx.Plan(); err != nil {
  1325  		t.Fatalf("err: %s", err)
  1326  	}
  1327  
  1328  	if _, err := ctx.Apply(); err != nil {
  1329  		t.Fatalf("err: %s", err)
  1330  	}
  1331  }
  1332  
  1333  func TestContext2Apply_moduleGrandchildProvider(t *testing.T) {
  1334  	m := testModule(t, "apply-module-grandchild-provider-inherit")
  1335  	p := testProvider("aws")
  1336  	p.ApplyFn = testApplyFn
  1337  	p.DiffFn = testDiffFn
  1338  
  1339  	var callLock sync.Mutex
  1340  	called := false
  1341  	p.ConfigureFn = func(c *ResourceConfig) error {
  1342  		if _, ok := c.Get("value"); !ok {
  1343  			return fmt.Errorf("value is not found")
  1344  		}
  1345  		callLock.Lock()
  1346  		called = true
  1347  		callLock.Unlock()
  1348  
  1349  		return nil
  1350  	}
  1351  
  1352  	ctx := testContext2(t, &ContextOpts{
  1353  		Module: m,
  1354  		Providers: map[string]ResourceProviderFactory{
  1355  			"aws": testProviderFuncFixed(p),
  1356  		},
  1357  	})
  1358  
  1359  	if _, err := ctx.Plan(); err != nil {
  1360  		t.Fatalf("err: %s", err)
  1361  	}
  1362  
  1363  	if _, err := ctx.Apply(); err != nil {
  1364  		t.Fatalf("err: %s", err)
  1365  	}
  1366  
  1367  	callLock.Lock()
  1368  	defer callLock.Unlock()
  1369  	if called != true {
  1370  		t.Fatalf("err: configure never called")
  1371  	}
  1372  }
  1373  
  1374  // This tests an issue where all the providers in a module but not
  1375  // in the root weren't being added to the root properly. In this test
  1376  // case: aws is explicitly added to root, but "test" should be added to.
  1377  // With the bug, it wasn't.
  1378  func TestContext2Apply_moduleOnlyProvider(t *testing.T) {
  1379  	m := testModule(t, "apply-module-only-provider")
  1380  	p := testProvider("aws")
  1381  	p.ApplyFn = testApplyFn
  1382  	p.DiffFn = testDiffFn
  1383  	pTest := testProvider("test")
  1384  	pTest.ApplyFn = testApplyFn
  1385  	pTest.DiffFn = testDiffFn
  1386  
  1387  	ctx := testContext2(t, &ContextOpts{
  1388  		Module: m,
  1389  		Providers: map[string]ResourceProviderFactory{
  1390  			"aws":  testProviderFuncFixed(p),
  1391  			"test": testProviderFuncFixed(pTest),
  1392  		},
  1393  	})
  1394  
  1395  	if _, err := ctx.Plan(); err != nil {
  1396  		t.Fatalf("err: %s", err)
  1397  	}
  1398  
  1399  	state, err := ctx.Apply()
  1400  	if err != nil {
  1401  		t.Fatalf("err: %s", err)
  1402  	}
  1403  
  1404  	actual := strings.TrimSpace(state.String())
  1405  	expected := strings.TrimSpace(testTerraformApplyModuleOnlyProviderStr)
  1406  	if actual != expected {
  1407  		t.Fatalf("bad: \n%s", actual)
  1408  	}
  1409  }
  1410  
  1411  func TestContext2Apply_moduleProviderAlias(t *testing.T) {
  1412  	m := testModule(t, "apply-module-provider-alias")
  1413  	p := testProvider("aws")
  1414  	p.ApplyFn = testApplyFn
  1415  	p.DiffFn = testDiffFn
  1416  	ctx := testContext2(t, &ContextOpts{
  1417  		Module: m,
  1418  		Providers: map[string]ResourceProviderFactory{
  1419  			"aws": testProviderFuncFixed(p),
  1420  		},
  1421  	})
  1422  
  1423  	if _, err := ctx.Plan(); err != nil {
  1424  		t.Fatalf("err: %s", err)
  1425  	}
  1426  
  1427  	state, err := ctx.Apply()
  1428  	if err != nil {
  1429  		t.Fatalf("err: %s", err)
  1430  	}
  1431  
  1432  	actual := strings.TrimSpace(state.String())
  1433  	expected := strings.TrimSpace(testTerraformApplyModuleProviderAliasStr)
  1434  	if actual != expected {
  1435  		t.Fatalf("bad: \n%s", actual)
  1436  	}
  1437  }
  1438  
  1439  func TestContext2Apply_moduleProviderAliasTargets(t *testing.T) {
  1440  	m := testModule(t, "apply-module-provider-alias")
  1441  	p := testProvider("aws")
  1442  	p.ApplyFn = testApplyFn
  1443  	p.DiffFn = testDiffFn
  1444  	ctx := testContext2(t, &ContextOpts{
  1445  		Module: m,
  1446  		Providers: map[string]ResourceProviderFactory{
  1447  			"aws": testProviderFuncFixed(p),
  1448  		},
  1449  		Targets: []string{"no.thing"},
  1450  	})
  1451  
  1452  	if _, err := ctx.Plan(); err != nil {
  1453  		t.Fatalf("err: %s", err)
  1454  	}
  1455  
  1456  	state, err := ctx.Apply()
  1457  	if err != nil {
  1458  		t.Fatalf("err: %s", err)
  1459  	}
  1460  
  1461  	actual := strings.TrimSpace(state.String())
  1462  	expected := strings.TrimSpace(`
  1463  <no state>
  1464  	`)
  1465  	if actual != expected {
  1466  		t.Fatalf("bad: \n%s", actual)
  1467  	}
  1468  }
  1469  
  1470  func TestContext2Apply_moduleProviderCloseNested(t *testing.T) {
  1471  	m := testModule(t, "apply-module-provider-close-nested")
  1472  	p := testProvider("aws")
  1473  	p.ApplyFn = testApplyFn
  1474  	p.DiffFn = testDiffFn
  1475  	ctx := testContext2(t, &ContextOpts{
  1476  		Module: m,
  1477  		Providers: map[string]ResourceProviderFactory{
  1478  			"aws": testProviderFuncFixed(p),
  1479  		},
  1480  		State: &State{
  1481  			Modules: []*ModuleState{
  1482  				&ModuleState{
  1483  					Path: []string{"root", "child", "subchild"},
  1484  					Resources: map[string]*ResourceState{
  1485  						"aws_instance.foo": &ResourceState{
  1486  							Type: "aws_instance",
  1487  							Primary: &InstanceState{
  1488  								ID: "bar",
  1489  							},
  1490  						},
  1491  					},
  1492  				},
  1493  			},
  1494  		},
  1495  		Destroy: true,
  1496  	})
  1497  
  1498  	if _, err := ctx.Plan(); err != nil {
  1499  		t.Fatalf("err: %s", err)
  1500  	}
  1501  
  1502  	if _, err := ctx.Apply(); err != nil {
  1503  		t.Fatalf("err: %s", err)
  1504  	}
  1505  }
  1506  
  1507  func TestContext2Apply_moduleVarResourceCount(t *testing.T) {
  1508  	m := testModule(t, "apply-module-var-resource-count")
  1509  	p := testProvider("aws")
  1510  	p.ApplyFn = testApplyFn
  1511  	p.DiffFn = testDiffFn
  1512  	ctx := testContext2(t, &ContextOpts{
  1513  		Module: m,
  1514  		Providers: map[string]ResourceProviderFactory{
  1515  			"aws": testProviderFuncFixed(p),
  1516  		},
  1517  		Variables: map[string]interface{}{
  1518  			"count": "2",
  1519  		},
  1520  		Destroy: true,
  1521  	})
  1522  
  1523  	if _, err := ctx.Plan(); err != nil {
  1524  		t.Fatalf("err: %s", err)
  1525  	}
  1526  
  1527  	if _, err := ctx.Apply(); err != nil {
  1528  		t.Fatalf("err: %s", err)
  1529  	}
  1530  
  1531  	ctx = testContext2(t, &ContextOpts{
  1532  		Module: m,
  1533  		Providers: map[string]ResourceProviderFactory{
  1534  			"aws": testProviderFuncFixed(p),
  1535  		},
  1536  		Variables: map[string]interface{}{
  1537  			"count": "5",
  1538  		},
  1539  	})
  1540  
  1541  	if _, err := ctx.Plan(); err != nil {
  1542  		t.Fatalf("err: %s", err)
  1543  	}
  1544  
  1545  	if _, err := ctx.Apply(); err != nil {
  1546  		t.Fatalf("err: %s", err)
  1547  	}
  1548  }
  1549  
  1550  // GH-819
  1551  func TestContext2Apply_moduleBool(t *testing.T) {
  1552  	m := testModule(t, "apply-module-bool")
  1553  	p := testProvider("aws")
  1554  	p.ApplyFn = testApplyFn
  1555  	p.DiffFn = testDiffFn
  1556  	ctx := testContext2(t, &ContextOpts{
  1557  		Module: m,
  1558  		Providers: map[string]ResourceProviderFactory{
  1559  			"aws": testProviderFuncFixed(p),
  1560  		},
  1561  	})
  1562  
  1563  	if _, err := ctx.Plan(); err != nil {
  1564  		t.Fatalf("err: %s", err)
  1565  	}
  1566  
  1567  	state, err := ctx.Apply()
  1568  	if err != nil {
  1569  		t.Fatalf("err: %s", err)
  1570  	}
  1571  
  1572  	actual := strings.TrimSpace(state.String())
  1573  	expected := strings.TrimSpace(testTerraformApplyModuleBoolStr)
  1574  	if actual != expected {
  1575  		t.Fatalf("bad: \n%s", actual)
  1576  	}
  1577  }
  1578  
  1579  func TestContext2Apply_multiProvider(t *testing.T) {
  1580  	m := testModule(t, "apply-multi-provider")
  1581  	p := testProvider("aws")
  1582  	p.ApplyFn = testApplyFn
  1583  	p.DiffFn = testDiffFn
  1584  
  1585  	pDO := testProvider("do")
  1586  	pDO.ApplyFn = testApplyFn
  1587  	pDO.DiffFn = testDiffFn
  1588  
  1589  	ctx := testContext2(t, &ContextOpts{
  1590  		Module: m,
  1591  		Providers: map[string]ResourceProviderFactory{
  1592  			"aws": testProviderFuncFixed(p),
  1593  			"do":  testProviderFuncFixed(pDO),
  1594  		},
  1595  	})
  1596  
  1597  	if _, err := ctx.Plan(); err != nil {
  1598  		t.Fatalf("err: %s", err)
  1599  	}
  1600  
  1601  	state, err := ctx.Apply()
  1602  	if err != nil {
  1603  		t.Fatalf("err: %s", err)
  1604  	}
  1605  
  1606  	mod := state.RootModule()
  1607  	if len(mod.Resources) < 2 {
  1608  		t.Fatalf("bad: %#v", mod.Resources)
  1609  	}
  1610  
  1611  	actual := strings.TrimSpace(state.String())
  1612  	expected := strings.TrimSpace(testTerraformApplyMultiProviderStr)
  1613  	if actual != expected {
  1614  		t.Fatalf("bad: \n%s", actual)
  1615  	}
  1616  }
  1617  
  1618  func TestContext2Apply_multiVar(t *testing.T) {
  1619  	m := testModule(t, "apply-multi-var")
  1620  	p := testProvider("aws")
  1621  	p.ApplyFn = testApplyFn
  1622  	p.DiffFn = testDiffFn
  1623  
  1624  	// First, apply with a count of 3
  1625  	ctx := testContext2(t, &ContextOpts{
  1626  		Module: m,
  1627  		Providers: map[string]ResourceProviderFactory{
  1628  			"aws": testProviderFuncFixed(p),
  1629  		},
  1630  		Variables: map[string]interface{}{
  1631  			"count": "3",
  1632  		},
  1633  	})
  1634  
  1635  	if _, err := ctx.Plan(); err != nil {
  1636  		t.Fatalf("err: %s", err)
  1637  	}
  1638  
  1639  	state, err := ctx.Apply()
  1640  	if err != nil {
  1641  		t.Fatalf("err: %s", err)
  1642  	}
  1643  
  1644  	actual := state.RootModule().Outputs["output"]
  1645  	expected := "bar0,bar1,bar2"
  1646  	if actual.Value != expected {
  1647  		t.Fatalf("bad: \n%s", actual)
  1648  	}
  1649  
  1650  	// Apply again, reduce the count to 1
  1651  	{
  1652  		ctx := testContext2(t, &ContextOpts{
  1653  			Module: m,
  1654  			State:  state,
  1655  			Providers: map[string]ResourceProviderFactory{
  1656  				"aws": testProviderFuncFixed(p),
  1657  			},
  1658  			Variables: map[string]interface{}{
  1659  				"count": "1",
  1660  			},
  1661  		})
  1662  
  1663  		if _, err := ctx.Plan(); err != nil {
  1664  			t.Fatalf("err: %s", err)
  1665  		}
  1666  
  1667  		state, err := ctx.Apply()
  1668  		if err != nil {
  1669  			t.Fatalf("err: %s", err)
  1670  		}
  1671  
  1672  		actual := state.RootModule().Outputs["output"]
  1673  		expected := "bar0"
  1674  		if actual.Value != expected {
  1675  			t.Fatalf("bad: \n%s", actual)
  1676  		}
  1677  	}
  1678  }
  1679  
  1680  func TestContext2Apply_nilDiff(t *testing.T) {
  1681  	m := testModule(t, "apply-good")
  1682  	p := testProvider("aws")
  1683  	p.ApplyFn = testApplyFn
  1684  	p.DiffFn = testDiffFn
  1685  	ctx := testContext2(t, &ContextOpts{
  1686  		Module: m,
  1687  		Providers: map[string]ResourceProviderFactory{
  1688  			"aws": testProviderFuncFixed(p),
  1689  		},
  1690  	})
  1691  
  1692  	if _, err := ctx.Plan(); err != nil {
  1693  		t.Fatalf("err: %s", err)
  1694  	}
  1695  
  1696  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  1697  		return nil, nil
  1698  	}
  1699  
  1700  	if _, err := ctx.Apply(); err == nil {
  1701  		t.Fatal("should error")
  1702  	}
  1703  }
  1704  
  1705  func TestContext2Apply_outputOrphan(t *testing.T) {
  1706  	m := testModule(t, "apply-output-orphan")
  1707  	p := testProvider("aws")
  1708  	p.ApplyFn = testApplyFn
  1709  	p.DiffFn = testDiffFn
  1710  
  1711  	state := &State{
  1712  		Modules: []*ModuleState{
  1713  			&ModuleState{
  1714  				Path: rootModulePath,
  1715  				Outputs: map[string]*OutputState{
  1716  					"foo": &OutputState{
  1717  						Type:      "string",
  1718  						Sensitive: false,
  1719  						Value:     "bar",
  1720  					},
  1721  					"bar": &OutputState{
  1722  						Type:      "string",
  1723  						Sensitive: false,
  1724  						Value:     "baz",
  1725  					},
  1726  				},
  1727  			},
  1728  		},
  1729  	}
  1730  
  1731  	ctx := testContext2(t, &ContextOpts{
  1732  		Module: m,
  1733  		Providers: map[string]ResourceProviderFactory{
  1734  			"aws": testProviderFuncFixed(p),
  1735  		},
  1736  		State: state,
  1737  	})
  1738  
  1739  	if _, err := ctx.Plan(); err != nil {
  1740  		t.Fatalf("err: %s", err)
  1741  	}
  1742  
  1743  	state, err := ctx.Apply()
  1744  	if err != nil {
  1745  		t.Fatalf("err: %s", err)
  1746  	}
  1747  
  1748  	actual := strings.TrimSpace(state.String())
  1749  	expected := strings.TrimSpace(testTerraformApplyOutputOrphanStr)
  1750  	if actual != expected {
  1751  		t.Fatalf("bad: \n%s", actual)
  1752  	}
  1753  }
  1754  
  1755  func TestContext2Apply_providerComputedVar(t *testing.T) {
  1756  	m := testModule(t, "apply-provider-computed")
  1757  	p := testProvider("aws")
  1758  	p.ApplyFn = testApplyFn
  1759  	p.DiffFn = testDiffFn
  1760  
  1761  	pTest := testProvider("test")
  1762  	pTest.ApplyFn = testApplyFn
  1763  	pTest.DiffFn = testDiffFn
  1764  
  1765  	ctx := testContext2(t, &ContextOpts{
  1766  		Module: m,
  1767  		Providers: map[string]ResourceProviderFactory{
  1768  			"aws":  testProviderFuncFixed(p),
  1769  			"test": testProviderFuncFixed(pTest),
  1770  		},
  1771  	})
  1772  
  1773  	p.ConfigureFn = func(c *ResourceConfig) error {
  1774  		if c.IsComputed("value") {
  1775  			return fmt.Errorf("value is computed")
  1776  		}
  1777  
  1778  		v, ok := c.Get("value")
  1779  		if !ok {
  1780  			return fmt.Errorf("value is not found")
  1781  		}
  1782  		if v != "yes" {
  1783  			return fmt.Errorf("value is not 'yes': %v", v)
  1784  		}
  1785  
  1786  		return nil
  1787  	}
  1788  
  1789  	if _, err := ctx.Plan(); err != nil {
  1790  		t.Fatalf("err: %s", err)
  1791  	}
  1792  
  1793  	if _, err := ctx.Apply(); err != nil {
  1794  		t.Fatalf("err: %s", err)
  1795  	}
  1796  }
  1797  
  1798  func TestContext2Apply_Provisioner_compute(t *testing.T) {
  1799  	m := testModule(t, "apply-provisioner-compute")
  1800  	p := testProvider("aws")
  1801  	pr := testProvisioner()
  1802  	p.ApplyFn = testApplyFn
  1803  	p.DiffFn = testDiffFn
  1804  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  1805  		val, ok := c.Config["foo"]
  1806  		if !ok || val != "computed_dynamical" {
  1807  			t.Fatalf("bad value for foo: %v %#v", val, c)
  1808  		}
  1809  
  1810  		return nil
  1811  	}
  1812  	ctx := testContext2(t, &ContextOpts{
  1813  		Module: m,
  1814  		Providers: map[string]ResourceProviderFactory{
  1815  			"aws": testProviderFuncFixed(p),
  1816  		},
  1817  		Provisioners: map[string]ResourceProvisionerFactory{
  1818  			"shell": testProvisionerFuncFixed(pr),
  1819  		},
  1820  		Variables: map[string]interface{}{
  1821  			"value": "1",
  1822  		},
  1823  	})
  1824  
  1825  	if _, err := ctx.Plan(); err != nil {
  1826  		t.Fatalf("err: %s", err)
  1827  	}
  1828  
  1829  	state, err := ctx.Apply()
  1830  	if err != nil {
  1831  		t.Fatalf("err: %s", err)
  1832  	}
  1833  
  1834  	actual := strings.TrimSpace(state.String())
  1835  	expected := strings.TrimSpace(testTerraformApplyProvisionerStr)
  1836  	if actual != expected {
  1837  		t.Fatalf("bad: \n%s", actual)
  1838  	}
  1839  
  1840  	// Verify apply was invoked
  1841  	if !pr.ApplyCalled {
  1842  		t.Fatalf("provisioner not invoked")
  1843  	}
  1844  }
  1845  
  1846  func TestContext2Apply_provisionerCreateFail(t *testing.T) {
  1847  	m := testModule(t, "apply-provisioner-fail-create")
  1848  	p := testProvider("aws")
  1849  	pr := testProvisioner()
  1850  	p.DiffFn = testDiffFn
  1851  
  1852  	p.ApplyFn = func(
  1853  		info *InstanceInfo,
  1854  		is *InstanceState,
  1855  		id *InstanceDiff) (*InstanceState, error) {
  1856  		is.ID = "foo"
  1857  		return is, fmt.Errorf("error")
  1858  	}
  1859  
  1860  	ctx := testContext2(t, &ContextOpts{
  1861  		Module: m,
  1862  		Providers: map[string]ResourceProviderFactory{
  1863  			"aws": testProviderFuncFixed(p),
  1864  		},
  1865  		Provisioners: map[string]ResourceProvisionerFactory{
  1866  			"shell": testProvisionerFuncFixed(pr),
  1867  		},
  1868  	})
  1869  
  1870  	if _, err := ctx.Plan(); err != nil {
  1871  		t.Fatalf("err: %s", err)
  1872  	}
  1873  
  1874  	state, err := ctx.Apply()
  1875  	if err == nil {
  1876  		t.Fatal("should error")
  1877  	}
  1878  
  1879  	actual := strings.TrimSpace(state.String())
  1880  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailCreateStr)
  1881  	if actual != expected {
  1882  		t.Fatalf("bad: \n%s", actual)
  1883  	}
  1884  }
  1885  
  1886  func TestContext2Apply_provisionerCreateFailNoId(t *testing.T) {
  1887  	m := testModule(t, "apply-provisioner-fail-create")
  1888  	p := testProvider("aws")
  1889  	pr := testProvisioner()
  1890  	p.DiffFn = testDiffFn
  1891  
  1892  	p.ApplyFn = func(
  1893  		info *InstanceInfo,
  1894  		is *InstanceState,
  1895  		id *InstanceDiff) (*InstanceState, error) {
  1896  		return nil, fmt.Errorf("error")
  1897  	}
  1898  
  1899  	ctx := testContext2(t, &ContextOpts{
  1900  		Module: m,
  1901  		Providers: map[string]ResourceProviderFactory{
  1902  			"aws": testProviderFuncFixed(p),
  1903  		},
  1904  		Provisioners: map[string]ResourceProvisionerFactory{
  1905  			"shell": testProvisionerFuncFixed(pr),
  1906  		},
  1907  	})
  1908  
  1909  	if _, err := ctx.Plan(); err != nil {
  1910  		t.Fatalf("err: %s", err)
  1911  	}
  1912  
  1913  	state, err := ctx.Apply()
  1914  	if err == nil {
  1915  		t.Fatal("should error")
  1916  	}
  1917  
  1918  	actual := strings.TrimSpace(state.String())
  1919  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailCreateNoIdStr)
  1920  	if actual != expected {
  1921  		t.Fatalf("bad: \n%s", actual)
  1922  	}
  1923  }
  1924  
  1925  func TestContext2Apply_provisionerFail(t *testing.T) {
  1926  	m := testModule(t, "apply-provisioner-fail")
  1927  	p := testProvider("aws")
  1928  	pr := testProvisioner()
  1929  	p.ApplyFn = testApplyFn
  1930  	p.DiffFn = testDiffFn
  1931  
  1932  	pr.ApplyFn = func(*InstanceState, *ResourceConfig) error {
  1933  		return fmt.Errorf("EXPLOSION")
  1934  	}
  1935  
  1936  	ctx := testContext2(t, &ContextOpts{
  1937  		Module: m,
  1938  		Providers: map[string]ResourceProviderFactory{
  1939  			"aws": testProviderFuncFixed(p),
  1940  		},
  1941  		Provisioners: map[string]ResourceProvisionerFactory{
  1942  			"shell": testProvisionerFuncFixed(pr),
  1943  		},
  1944  		Variables: map[string]interface{}{
  1945  			"value": "1",
  1946  		},
  1947  	})
  1948  
  1949  	if _, err := ctx.Plan(); err != nil {
  1950  		t.Fatalf("err: %s", err)
  1951  	}
  1952  
  1953  	state, err := ctx.Apply()
  1954  	if err == nil {
  1955  		t.Fatal("should error")
  1956  	}
  1957  
  1958  	actual := strings.TrimSpace(state.String())
  1959  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailStr)
  1960  	if actual != expected {
  1961  		t.Fatalf("bad: \n%s", actual)
  1962  	}
  1963  }
  1964  
  1965  func TestContext2Apply_provisionerFail_createBeforeDestroy(t *testing.T) {
  1966  	m := testModule(t, "apply-provisioner-fail-create-before")
  1967  	p := testProvider("aws")
  1968  	pr := testProvisioner()
  1969  	p.ApplyFn = testApplyFn
  1970  	p.DiffFn = testDiffFn
  1971  	pr.ApplyFn = func(*InstanceState, *ResourceConfig) error {
  1972  		return fmt.Errorf("EXPLOSION")
  1973  	}
  1974  
  1975  	state := &State{
  1976  		Modules: []*ModuleState{
  1977  			&ModuleState{
  1978  				Path: rootModulePath,
  1979  				Resources: map[string]*ResourceState{
  1980  					"aws_instance.bar": &ResourceState{
  1981  						Type: "aws_instance",
  1982  						Primary: &InstanceState{
  1983  							ID: "bar",
  1984  							Attributes: map[string]string{
  1985  								"require_new": "abc",
  1986  							},
  1987  						},
  1988  					},
  1989  				},
  1990  			},
  1991  		},
  1992  	}
  1993  	ctx := testContext2(t, &ContextOpts{
  1994  		Module: m,
  1995  		Providers: map[string]ResourceProviderFactory{
  1996  			"aws": testProviderFuncFixed(p),
  1997  		},
  1998  		Provisioners: map[string]ResourceProvisionerFactory{
  1999  			"shell": testProvisionerFuncFixed(pr),
  2000  		},
  2001  		State: state,
  2002  	})
  2003  
  2004  	if _, err := ctx.Plan(); err != nil {
  2005  		t.Fatalf("err: %s", err)
  2006  	}
  2007  
  2008  	state, err := ctx.Apply()
  2009  	if err == nil {
  2010  		t.Fatal("should error")
  2011  	}
  2012  
  2013  	actual := strings.TrimSpace(state.String())
  2014  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailCreateBeforeDestroyStr)
  2015  	if actual != expected {
  2016  		t.Fatalf("bad: \n%s", actual)
  2017  	}
  2018  }
  2019  
  2020  func TestContext2Apply_error_createBeforeDestroy(t *testing.T) {
  2021  	m := testModule(t, "apply-error-create-before")
  2022  	p := testProvider("aws")
  2023  	state := &State{
  2024  		Modules: []*ModuleState{
  2025  			&ModuleState{
  2026  				Path: rootModulePath,
  2027  				Resources: map[string]*ResourceState{
  2028  					"aws_instance.bar": &ResourceState{
  2029  						Type: "aws_instance",
  2030  						Primary: &InstanceState{
  2031  							ID: "bar",
  2032  							Attributes: map[string]string{
  2033  								"require_new": "abc",
  2034  							},
  2035  						},
  2036  					},
  2037  				},
  2038  			},
  2039  		},
  2040  	}
  2041  	ctx := testContext2(t, &ContextOpts{
  2042  		Module: m,
  2043  		Providers: map[string]ResourceProviderFactory{
  2044  			"aws": testProviderFuncFixed(p),
  2045  		},
  2046  		State: state,
  2047  	})
  2048  	p.ApplyFn = func(info *InstanceInfo, is *InstanceState, id *InstanceDiff) (*InstanceState, error) {
  2049  		return nil, fmt.Errorf("error")
  2050  	}
  2051  	p.DiffFn = testDiffFn
  2052  
  2053  	if _, err := ctx.Plan(); err != nil {
  2054  		t.Fatalf("err: %s", err)
  2055  	}
  2056  
  2057  	state, err := ctx.Apply()
  2058  	if err == nil {
  2059  		t.Fatal("should have error")
  2060  	}
  2061  
  2062  	actual := strings.TrimSpace(state.String())
  2063  	expected := strings.TrimSpace(testTerraformApplyErrorCreateBeforeDestroyStr)
  2064  	if actual != expected {
  2065  		t.Fatalf("bad: \n%s\n\nExpected:\n\n%s", actual, expected)
  2066  	}
  2067  }
  2068  
  2069  func TestContext2Apply_errorDestroy_createBeforeDestroy(t *testing.T) {
  2070  	m := testModule(t, "apply-error-create-before")
  2071  	p := testProvider("aws")
  2072  	state := &State{
  2073  		Modules: []*ModuleState{
  2074  			&ModuleState{
  2075  				Path: rootModulePath,
  2076  				Resources: map[string]*ResourceState{
  2077  					"aws_instance.bar": &ResourceState{
  2078  						Type: "aws_instance",
  2079  						Primary: &InstanceState{
  2080  							ID: "bar",
  2081  							Attributes: map[string]string{
  2082  								"require_new": "abc",
  2083  							},
  2084  						},
  2085  					},
  2086  				},
  2087  			},
  2088  		},
  2089  	}
  2090  	ctx := testContext2(t, &ContextOpts{
  2091  		Module: m,
  2092  		Providers: map[string]ResourceProviderFactory{
  2093  			"aws": testProviderFuncFixed(p),
  2094  		},
  2095  		State: state,
  2096  	})
  2097  	p.ApplyFn = func(info *InstanceInfo, is *InstanceState, id *InstanceDiff) (*InstanceState, error) {
  2098  		// Fail the destroy!
  2099  		if id.Destroy {
  2100  			return is, fmt.Errorf("error")
  2101  		}
  2102  
  2103  		// Create should work
  2104  		is = &InstanceState{
  2105  			ID: "foo",
  2106  		}
  2107  		return is, nil
  2108  	}
  2109  	p.DiffFn = testDiffFn
  2110  
  2111  	if _, err := ctx.Plan(); err != nil {
  2112  		t.Fatalf("err: %s", err)
  2113  	}
  2114  
  2115  	state, err := ctx.Apply()
  2116  	if err == nil {
  2117  		t.Fatal("should have error")
  2118  	}
  2119  
  2120  	actual := strings.TrimSpace(state.String())
  2121  	expected := strings.TrimSpace(testTerraformApplyErrorDestroyCreateBeforeDestroyStr)
  2122  	if actual != expected {
  2123  		t.Fatalf("bad: actual:\n%s\n\nexpected:\n%s", actual, expected)
  2124  	}
  2125  }
  2126  
  2127  func TestContext2Apply_multiDepose_createBeforeDestroy(t *testing.T) {
  2128  	m := testModule(t, "apply-multi-depose-create-before-destroy")
  2129  	p := testProvider("aws")
  2130  	p.DiffFn = testDiffFn
  2131  	ps := map[string]ResourceProviderFactory{"aws": testProviderFuncFixed(p)}
  2132  	state := &State{
  2133  		Modules: []*ModuleState{
  2134  			&ModuleState{
  2135  				Path: rootModulePath,
  2136  				Resources: map[string]*ResourceState{
  2137  					"aws_instance.web": &ResourceState{
  2138  						Type:    "aws_instance",
  2139  						Primary: &InstanceState{ID: "foo"},
  2140  					},
  2141  				},
  2142  			},
  2143  		},
  2144  	}
  2145  
  2146  	ctx := testContext2(t, &ContextOpts{
  2147  		Module:    m,
  2148  		Providers: ps,
  2149  		State:     state,
  2150  	})
  2151  	createdInstanceId := "bar"
  2152  	// Create works
  2153  	createFunc := func(is *InstanceState) (*InstanceState, error) {
  2154  		return &InstanceState{ID: createdInstanceId}, nil
  2155  	}
  2156  	// Destroy starts broken
  2157  	destroyFunc := func(is *InstanceState) (*InstanceState, error) {
  2158  		return is, fmt.Errorf("destroy failed")
  2159  	}
  2160  	p.ApplyFn = func(info *InstanceInfo, is *InstanceState, id *InstanceDiff) (*InstanceState, error) {
  2161  		if id.Destroy {
  2162  			return destroyFunc(is)
  2163  		} else {
  2164  			return createFunc(is)
  2165  		}
  2166  	}
  2167  
  2168  	if _, err := ctx.Plan(); err != nil {
  2169  		t.Fatalf("err: %s", err)
  2170  	}
  2171  
  2172  	// Destroy is broken, so even though CBD successfully replaces the instance,
  2173  	// we'll have to save the Deposed instance to destroy later
  2174  	state, err := ctx.Apply()
  2175  	if err == nil {
  2176  		t.Fatal("should have error")
  2177  	}
  2178  
  2179  	checkStateString(t, state, `
  2180  aws_instance.web: (1 deposed)
  2181    ID = bar
  2182    Deposed ID 1 = foo
  2183  	`)
  2184  
  2185  	createdInstanceId = "baz"
  2186  	ctx = testContext2(t, &ContextOpts{
  2187  		Module:    m,
  2188  		Providers: ps,
  2189  		State:     state,
  2190  	})
  2191  
  2192  	if _, err := ctx.Plan(); err != nil {
  2193  		t.Fatalf("err: %s", err)
  2194  	}
  2195  
  2196  	// We're replacing the primary instance once again. Destroy is _still_
  2197  	// broken, so the Deposed list gets longer
  2198  	state, err = ctx.Apply()
  2199  	if err == nil {
  2200  		t.Fatal("should have error")
  2201  	}
  2202  
  2203  	checkStateString(t, state, `
  2204  aws_instance.web: (2 deposed)
  2205    ID = baz
  2206    Deposed ID 1 = foo
  2207    Deposed ID 2 = bar
  2208  	`)
  2209  
  2210  	// Destroy partially fixed!
  2211  	destroyFunc = func(is *InstanceState) (*InstanceState, error) {
  2212  		if is.ID == "foo" || is.ID == "baz" {
  2213  			return nil, nil
  2214  		} else {
  2215  			return is, fmt.Errorf("destroy partially failed")
  2216  		}
  2217  	}
  2218  
  2219  	createdInstanceId = "qux"
  2220  	if _, err := ctx.Plan(); err != nil {
  2221  		t.Fatalf("err: %s", err)
  2222  	}
  2223  	state, err = ctx.Apply()
  2224  	// Expect error because 1/2 of Deposed destroys failed
  2225  	if err == nil {
  2226  		t.Fatal("should have error")
  2227  	}
  2228  
  2229  	// foo and baz are now gone, bar sticks around
  2230  	checkStateString(t, state, `
  2231  aws_instance.web: (1 deposed)
  2232    ID = qux
  2233    Deposed ID 1 = bar
  2234  	`)
  2235  
  2236  	// Destroy working fully!
  2237  	destroyFunc = func(is *InstanceState) (*InstanceState, error) {
  2238  		return nil, nil
  2239  	}
  2240  
  2241  	createdInstanceId = "quux"
  2242  	if _, err := ctx.Plan(); err != nil {
  2243  		t.Fatalf("err: %s", err)
  2244  	}
  2245  	state, err = ctx.Apply()
  2246  	if err != nil {
  2247  		t.Fatal("should not have error:", err)
  2248  	}
  2249  
  2250  	// And finally the state is clean
  2251  	checkStateString(t, state, `
  2252  aws_instance.web:
  2253    ID = quux
  2254  	`)
  2255  }
  2256  
  2257  func TestContext2Apply_provisionerResourceRef(t *testing.T) {
  2258  	m := testModule(t, "apply-provisioner-resource-ref")
  2259  	p := testProvider("aws")
  2260  	pr := testProvisioner()
  2261  	p.ApplyFn = testApplyFn
  2262  	p.DiffFn = testDiffFn
  2263  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  2264  		val, ok := c.Config["foo"]
  2265  		if !ok || val != "2" {
  2266  			t.Fatalf("bad value for foo: %v %#v", val, c)
  2267  		}
  2268  
  2269  		return nil
  2270  	}
  2271  
  2272  	ctx := testContext2(t, &ContextOpts{
  2273  		Module: m,
  2274  		Providers: map[string]ResourceProviderFactory{
  2275  			"aws": testProviderFuncFixed(p),
  2276  		},
  2277  		Provisioners: map[string]ResourceProvisionerFactory{
  2278  			"shell": testProvisionerFuncFixed(pr),
  2279  		},
  2280  	})
  2281  
  2282  	if _, err := ctx.Plan(); err != nil {
  2283  		t.Fatalf("err: %s", err)
  2284  	}
  2285  
  2286  	state, err := ctx.Apply()
  2287  	if err != nil {
  2288  		t.Fatalf("err: %s", err)
  2289  	}
  2290  
  2291  	actual := strings.TrimSpace(state.String())
  2292  	expected := strings.TrimSpace(testTerraformApplyProvisionerResourceRefStr)
  2293  	if actual != expected {
  2294  		t.Fatalf("bad: \n%s", actual)
  2295  	}
  2296  
  2297  	// Verify apply was invoked
  2298  	if !pr.ApplyCalled {
  2299  		t.Fatalf("provisioner not invoked")
  2300  	}
  2301  }
  2302  
  2303  func TestContext2Apply_provisionerSelfRef(t *testing.T) {
  2304  	m := testModule(t, "apply-provisioner-self-ref")
  2305  	p := testProvider("aws")
  2306  	pr := testProvisioner()
  2307  	p.ApplyFn = testApplyFn
  2308  	p.DiffFn = testDiffFn
  2309  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  2310  		val, ok := c.Config["command"]
  2311  		if !ok || val != "bar" {
  2312  			t.Fatalf("bad value for command: %v %#v", val, c)
  2313  		}
  2314  
  2315  		return nil
  2316  	}
  2317  
  2318  	ctx := testContext2(t, &ContextOpts{
  2319  		Module: m,
  2320  		Providers: map[string]ResourceProviderFactory{
  2321  			"aws": testProviderFuncFixed(p),
  2322  		},
  2323  		Provisioners: map[string]ResourceProvisionerFactory{
  2324  			"shell": testProvisionerFuncFixed(pr),
  2325  		},
  2326  	})
  2327  
  2328  	if _, err := ctx.Plan(); err != nil {
  2329  		t.Fatalf("err: %s", err)
  2330  	}
  2331  
  2332  	state, err := ctx.Apply()
  2333  	if err != nil {
  2334  		t.Fatalf("err: %s", err)
  2335  	}
  2336  
  2337  	actual := strings.TrimSpace(state.String())
  2338  	expected := strings.TrimSpace(testTerraformApplyProvisionerSelfRefStr)
  2339  	if actual != expected {
  2340  		t.Fatalf("bad: \n%s", actual)
  2341  	}
  2342  
  2343  	// Verify apply was invoked
  2344  	if !pr.ApplyCalled {
  2345  		t.Fatalf("provisioner not invoked")
  2346  	}
  2347  }
  2348  
  2349  func TestContext2Apply_provisionerMultiSelfRef(t *testing.T) {
  2350  	var lock sync.Mutex
  2351  	commands := make([]string, 0, 5)
  2352  
  2353  	m := testModule(t, "apply-provisioner-multi-self-ref")
  2354  	p := testProvider("aws")
  2355  	pr := testProvisioner()
  2356  	p.ApplyFn = testApplyFn
  2357  	p.DiffFn = testDiffFn
  2358  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  2359  		lock.Lock()
  2360  		defer lock.Unlock()
  2361  
  2362  		val, ok := c.Config["command"]
  2363  		if !ok {
  2364  			t.Fatalf("bad value for command: %v %#v", val, c)
  2365  		}
  2366  
  2367  		commands = append(commands, val.(string))
  2368  		return nil
  2369  	}
  2370  
  2371  	ctx := testContext2(t, &ContextOpts{
  2372  		Module: m,
  2373  		Providers: map[string]ResourceProviderFactory{
  2374  			"aws": testProviderFuncFixed(p),
  2375  		},
  2376  		Provisioners: map[string]ResourceProvisionerFactory{
  2377  			"shell": testProvisionerFuncFixed(pr),
  2378  		},
  2379  	})
  2380  
  2381  	if _, err := ctx.Plan(); err != nil {
  2382  		t.Fatalf("err: %s", err)
  2383  	}
  2384  
  2385  	state, err := ctx.Apply()
  2386  	if err != nil {
  2387  		t.Fatalf("err: %s", err)
  2388  	}
  2389  
  2390  	actual := strings.TrimSpace(state.String())
  2391  	expected := strings.TrimSpace(testTerraformApplyProvisionerMultiSelfRefStr)
  2392  	if actual != expected {
  2393  		t.Fatalf("bad: \n%s", actual)
  2394  	}
  2395  
  2396  	// Verify apply was invoked
  2397  	if !pr.ApplyCalled {
  2398  		t.Fatalf("provisioner not invoked")
  2399  	}
  2400  
  2401  	// Verify our result
  2402  	sort.Strings(commands)
  2403  	expectedCommands := []string{"number 0", "number 1", "number 2"}
  2404  	if !reflect.DeepEqual(commands, expectedCommands) {
  2405  		t.Fatalf("bad: %#v", commands)
  2406  	}
  2407  }
  2408  
  2409  // Provisioner should NOT run on a diff, only create
  2410  func TestContext2Apply_Provisioner_Diff(t *testing.T) {
  2411  	m := testModule(t, "apply-provisioner-diff")
  2412  	p := testProvider("aws")
  2413  	pr := testProvisioner()
  2414  	p.ApplyFn = testApplyFn
  2415  	p.DiffFn = testDiffFn
  2416  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  2417  		return nil
  2418  	}
  2419  	ctx := testContext2(t, &ContextOpts{
  2420  		Module: m,
  2421  		Providers: map[string]ResourceProviderFactory{
  2422  			"aws": testProviderFuncFixed(p),
  2423  		},
  2424  		Provisioners: map[string]ResourceProvisionerFactory{
  2425  			"shell": testProvisionerFuncFixed(pr),
  2426  		},
  2427  	})
  2428  
  2429  	if _, err := ctx.Plan(); err != nil {
  2430  		t.Fatalf("err: %s", err)
  2431  	}
  2432  
  2433  	state, err := ctx.Apply()
  2434  	if err != nil {
  2435  		t.Fatalf("err: %s", err)
  2436  	}
  2437  
  2438  	actual := strings.TrimSpace(state.String())
  2439  	expected := strings.TrimSpace(testTerraformApplyProvisionerDiffStr)
  2440  	if actual != expected {
  2441  		t.Fatalf("bad: \n%s", actual)
  2442  	}
  2443  
  2444  	// Verify apply was invoked
  2445  	if !pr.ApplyCalled {
  2446  		t.Fatalf("provisioner not invoked")
  2447  	}
  2448  	pr.ApplyCalled = false
  2449  
  2450  	// Change the state to force a diff
  2451  	mod := state.RootModule()
  2452  	mod.Resources["aws_instance.bar"].Primary.Attributes["foo"] = "baz"
  2453  
  2454  	// Re-create context with state
  2455  	ctx = testContext2(t, &ContextOpts{
  2456  		Module: m,
  2457  		Providers: map[string]ResourceProviderFactory{
  2458  			"aws": testProviderFuncFixed(p),
  2459  		},
  2460  		Provisioners: map[string]ResourceProvisionerFactory{
  2461  			"shell": testProvisionerFuncFixed(pr),
  2462  		},
  2463  		State: state,
  2464  	})
  2465  
  2466  	if _, err := ctx.Plan(); err != nil {
  2467  		t.Fatalf("err: %s", err)
  2468  	}
  2469  
  2470  	state2, err := ctx.Apply()
  2471  	if err != nil {
  2472  		t.Fatalf("err: %s", err)
  2473  	}
  2474  
  2475  	actual = strings.TrimSpace(state2.String())
  2476  	if actual != expected {
  2477  		t.Fatalf("bad: \n%s", actual)
  2478  	}
  2479  
  2480  	// Verify apply was NOT invoked
  2481  	if pr.ApplyCalled {
  2482  		t.Fatalf("provisioner invoked")
  2483  	}
  2484  }
  2485  
  2486  func TestContext2Apply_outputDiffVars(t *testing.T) {
  2487  	m := testModule(t, "apply-good")
  2488  	p := testProvider("aws")
  2489  	s := &State{
  2490  		Modules: []*ModuleState{
  2491  			&ModuleState{
  2492  				Path: rootModulePath,
  2493  				Resources: map[string]*ResourceState{
  2494  					"aws_instance.baz": &ResourceState{
  2495  						Type: "aws_instance",
  2496  						Primary: &InstanceState{
  2497  							ID: "bar",
  2498  						},
  2499  					},
  2500  				},
  2501  			},
  2502  		},
  2503  	}
  2504  	ctx := testContext2(t, &ContextOpts{
  2505  		Module: m,
  2506  		Providers: map[string]ResourceProviderFactory{
  2507  			"aws": testProviderFuncFixed(p),
  2508  		},
  2509  		State: s,
  2510  	})
  2511  
  2512  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  2513  		for k, ad := range d.Attributes {
  2514  			if ad.NewComputed {
  2515  				return nil, fmt.Errorf("%s: computed", k)
  2516  			}
  2517  		}
  2518  
  2519  		result := s.MergeDiff(d)
  2520  		result.ID = "foo"
  2521  		return result, nil
  2522  	}
  2523  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  2524  		return &InstanceDiff{
  2525  			Attributes: map[string]*ResourceAttrDiff{
  2526  				"foo": &ResourceAttrDiff{
  2527  					NewComputed: true,
  2528  					Type:        DiffAttrOutput,
  2529  				},
  2530  				"bar": &ResourceAttrDiff{
  2531  					New: "baz",
  2532  				},
  2533  			},
  2534  		}, nil
  2535  	}
  2536  
  2537  	if _, err := ctx.Plan(); err != nil {
  2538  		t.Fatalf("err: %s", err)
  2539  	}
  2540  	if _, err := ctx.Apply(); err != nil {
  2541  		t.Fatalf("err: %s", err)
  2542  	}
  2543  }
  2544  
  2545  func TestContext2Apply_Provisioner_ConnInfo(t *testing.T) {
  2546  	m := testModule(t, "apply-provisioner-conninfo")
  2547  	p := testProvider("aws")
  2548  	pr := testProvisioner()
  2549  
  2550  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  2551  		if s.Ephemeral.ConnInfo == nil {
  2552  			t.Fatalf("ConnInfo not initialized")
  2553  		}
  2554  
  2555  		result, _ := testApplyFn(info, s, d)
  2556  		result.Ephemeral.ConnInfo = map[string]string{
  2557  			"type": "ssh",
  2558  			"host": "127.0.0.1",
  2559  			"port": "22",
  2560  		}
  2561  		return result, nil
  2562  	}
  2563  	p.DiffFn = testDiffFn
  2564  
  2565  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  2566  		conn := rs.Ephemeral.ConnInfo
  2567  		if conn["type"] != "telnet" {
  2568  			t.Fatalf("Bad: %#v", conn)
  2569  		}
  2570  		if conn["host"] != "127.0.0.1" {
  2571  			t.Fatalf("Bad: %#v", conn)
  2572  		}
  2573  		if conn["port"] != "2222" {
  2574  			t.Fatalf("Bad: %#v", conn)
  2575  		}
  2576  		if conn["user"] != "superuser" {
  2577  			t.Fatalf("Bad: %#v", conn)
  2578  		}
  2579  		if conn["pass"] != "test" {
  2580  			t.Fatalf("Bad: %#v", conn)
  2581  		}
  2582  
  2583  		return nil
  2584  	}
  2585  
  2586  	ctx := testContext2(t, &ContextOpts{
  2587  		Module: m,
  2588  		Providers: map[string]ResourceProviderFactory{
  2589  			"aws": testProviderFuncFixed(p),
  2590  		},
  2591  		Provisioners: map[string]ResourceProvisionerFactory{
  2592  			"shell": testProvisionerFuncFixed(pr),
  2593  		},
  2594  		Variables: map[string]interface{}{
  2595  			"value": "1",
  2596  			"pass":  "test",
  2597  		},
  2598  	})
  2599  
  2600  	if _, err := ctx.Plan(); err != nil {
  2601  		t.Fatalf("err: %s", err)
  2602  	}
  2603  
  2604  	state, err := ctx.Apply()
  2605  	if err != nil {
  2606  		t.Fatalf("err: %s", err)
  2607  	}
  2608  
  2609  	actual := strings.TrimSpace(state.String())
  2610  	expected := strings.TrimSpace(testTerraformApplyProvisionerStr)
  2611  	if actual != expected {
  2612  		t.Fatalf("bad: \n%s", actual)
  2613  	}
  2614  
  2615  	// Verify apply was invoked
  2616  	if !pr.ApplyCalled {
  2617  		t.Fatalf("provisioner not invoked")
  2618  	}
  2619  }
  2620  
  2621  func TestContext2Apply_destroy(t *testing.T) {
  2622  	m := testModule(t, "apply-destroy")
  2623  	h := new(HookRecordApplyOrder)
  2624  	p := testProvider("aws")
  2625  	p.ApplyFn = testApplyFn
  2626  	p.DiffFn = testDiffFn
  2627  	ctx := testContext2(t, &ContextOpts{
  2628  		Module: m,
  2629  		Hooks:  []Hook{h},
  2630  		Providers: map[string]ResourceProviderFactory{
  2631  			"aws": testProviderFuncFixed(p),
  2632  		},
  2633  	})
  2634  
  2635  	// First plan and apply a create operation
  2636  	if _, err := ctx.Plan(); err != nil {
  2637  		t.Fatalf("err: %s", err)
  2638  	}
  2639  
  2640  	state, err := ctx.Apply()
  2641  	if err != nil {
  2642  		t.Fatalf("err: %s", err)
  2643  	}
  2644  
  2645  	// Next, plan and apply a destroy operation
  2646  	h.Active = true
  2647  	ctx = testContext2(t, &ContextOpts{
  2648  		Destroy: true,
  2649  		State:   state,
  2650  		Module:  m,
  2651  		Hooks:   []Hook{h},
  2652  		Providers: map[string]ResourceProviderFactory{
  2653  			"aws": testProviderFuncFixed(p),
  2654  		},
  2655  	})
  2656  
  2657  	if _, err := ctx.Plan(); err != nil {
  2658  		t.Fatalf("err: %s", err)
  2659  	}
  2660  
  2661  	state, err = ctx.Apply()
  2662  	if err != nil {
  2663  		t.Fatalf("err: %s", err)
  2664  	}
  2665  
  2666  	// Test that things were destroyed
  2667  	actual := strings.TrimSpace(state.String())
  2668  	expected := strings.TrimSpace(testTerraformApplyDestroyStr)
  2669  	if actual != expected {
  2670  		t.Fatalf("bad: \n%s", actual)
  2671  	}
  2672  
  2673  	// Test that things were destroyed _in the right order_
  2674  	expected2 := []string{"aws_instance.bar", "aws_instance.foo"}
  2675  	actual2 := h.IDs
  2676  	if !reflect.DeepEqual(actual2, expected2) {
  2677  		t.Fatalf("expected: %#v\n\ngot:%#v", expected2, actual2)
  2678  	}
  2679  }
  2680  
  2681  func TestContext2Apply_destroyNestedModule(t *testing.T) {
  2682  	m := testModule(t, "apply-destroy-nested-module")
  2683  	p := testProvider("aws")
  2684  	p.ApplyFn = testApplyFn
  2685  	p.DiffFn = testDiffFn
  2686  
  2687  	s := &State{
  2688  		Modules: []*ModuleState{
  2689  			&ModuleState{
  2690  				Path: []string{"root", "child", "subchild"},
  2691  				Resources: map[string]*ResourceState{
  2692  					"aws_instance.bar": &ResourceState{
  2693  						Type: "aws_instance",
  2694  						Primary: &InstanceState{
  2695  							ID: "bar",
  2696  						},
  2697  					},
  2698  				},
  2699  			},
  2700  		},
  2701  	}
  2702  
  2703  	ctx := testContext2(t, &ContextOpts{
  2704  		Module: m,
  2705  		Providers: map[string]ResourceProviderFactory{
  2706  			"aws": testProviderFuncFixed(p),
  2707  		},
  2708  		State: s,
  2709  	})
  2710  
  2711  	// First plan and apply a create operation
  2712  	if _, err := ctx.Plan(); err != nil {
  2713  		t.Fatalf("err: %s", err)
  2714  	}
  2715  
  2716  	state, err := ctx.Apply()
  2717  	if err != nil {
  2718  		t.Fatalf("err: %s", err)
  2719  	}
  2720  
  2721  	// Test that things were destroyed
  2722  	actual := strings.TrimSpace(state.String())
  2723  	expected := strings.TrimSpace(testTerraformApplyDestroyNestedModuleStr)
  2724  	if actual != expected {
  2725  		t.Fatalf("bad: \n%s", actual)
  2726  	}
  2727  }
  2728  
  2729  func TestContext2Apply_destroyDeeplyNestedModule(t *testing.T) {
  2730  	m := testModule(t, "apply-destroy-deeply-nested-module")
  2731  	p := testProvider("aws")
  2732  	p.ApplyFn = testApplyFn
  2733  	p.DiffFn = testDiffFn
  2734  
  2735  	s := &State{
  2736  		Modules: []*ModuleState{
  2737  			&ModuleState{
  2738  				Path: []string{"root", "child", "subchild", "subsubchild"},
  2739  				Resources: map[string]*ResourceState{
  2740  					"aws_instance.bar": &ResourceState{
  2741  						Type: "aws_instance",
  2742  						Primary: &InstanceState{
  2743  							ID: "bar",
  2744  						},
  2745  					},
  2746  				},
  2747  			},
  2748  		},
  2749  	}
  2750  
  2751  	ctx := testContext2(t, &ContextOpts{
  2752  		Module: m,
  2753  		Providers: map[string]ResourceProviderFactory{
  2754  			"aws": testProviderFuncFixed(p),
  2755  		},
  2756  		State: s,
  2757  	})
  2758  
  2759  	// First plan and apply a create operation
  2760  	if _, err := ctx.Plan(); err != nil {
  2761  		t.Fatalf("err: %s", err)
  2762  	}
  2763  
  2764  	state, err := ctx.Apply()
  2765  	if err != nil {
  2766  		t.Fatalf("err: %s", err)
  2767  	}
  2768  
  2769  	// Test that things were destroyed
  2770  	actual := strings.TrimSpace(state.String())
  2771  	expected := strings.TrimSpace(`
  2772  module.child.subchild.subsubchild:
  2773    <no state>
  2774  	`)
  2775  	if actual != expected {
  2776  		t.Fatalf("bad: \n%s", actual)
  2777  	}
  2778  }
  2779  
  2780  // https://github.com/hashicorp/terraform/issues/5440
  2781  func TestContext2Apply_destroyModuleWithAttrsReferencingResource(t *testing.T) {
  2782  	m := testModule(t, "apply-destroy-module-with-attrs")
  2783  	p := testProvider("aws")
  2784  	p.ApplyFn = testApplyFn
  2785  	p.DiffFn = testDiffFn
  2786  
  2787  	var state *State
  2788  	var err error
  2789  	{
  2790  		ctx := testContext2(t, &ContextOpts{
  2791  			Module: m,
  2792  			Providers: map[string]ResourceProviderFactory{
  2793  				"aws": testProviderFuncFixed(p),
  2794  			},
  2795  		})
  2796  
  2797  		// First plan and apply a create operation
  2798  		if _, err := ctx.Plan(); err != nil {
  2799  			t.Fatalf("plan err: %s", err)
  2800  		}
  2801  
  2802  		state, err = ctx.Apply()
  2803  		if err != nil {
  2804  			t.Fatalf("apply err: %s", err)
  2805  		}
  2806  	}
  2807  
  2808  	h := new(HookRecordApplyOrder)
  2809  	h.Active = true
  2810  
  2811  	{
  2812  		ctx := testContext2(t, &ContextOpts{
  2813  			Destroy: true,
  2814  			Module:  m,
  2815  			State:   state,
  2816  			Hooks:   []Hook{h},
  2817  			Providers: map[string]ResourceProviderFactory{
  2818  				"aws": testProviderFuncFixed(p),
  2819  			},
  2820  			Variables: map[string]interface{}{
  2821  				"key_name": "foobarkey",
  2822  			},
  2823  		})
  2824  
  2825  		// First plan and apply a create operation
  2826  		plan, err := ctx.Plan()
  2827  		if err != nil {
  2828  			t.Fatalf("destroy plan err: %s", err)
  2829  		}
  2830  
  2831  		var buf bytes.Buffer
  2832  		if err := WritePlan(plan, &buf); err != nil {
  2833  			t.Fatalf("plan write err: %s", err)
  2834  		}
  2835  
  2836  		planFromFile, err := ReadPlan(&buf)
  2837  		if err != nil {
  2838  			t.Fatalf("plan read err: %s", err)
  2839  		}
  2840  
  2841  		ctx, err = planFromFile.Context(&ContextOpts{
  2842  			Providers: map[string]ResourceProviderFactory{
  2843  				"aws": testProviderFuncFixed(p),
  2844  			},
  2845  		})
  2846  		if err != nil {
  2847  			t.Fatalf("err: %s", err)
  2848  		}
  2849  
  2850  		state, err = ctx.Apply()
  2851  		if err != nil {
  2852  			t.Fatalf("destroy apply err: %s", err)
  2853  		}
  2854  	}
  2855  
  2856  	//Test that things were destroyed
  2857  	actual := strings.TrimSpace(state.String())
  2858  	expected := strings.TrimSpace(`
  2859  <no state>
  2860  module.child:
  2861    <no state>
  2862  		`)
  2863  	if actual != expected {
  2864  		t.Fatalf("expected: \n%s\n\nbad: \n%s", expected, actual)
  2865  	}
  2866  }
  2867  
  2868  func TestContext2Apply_destroyWithModuleVariableAndCount(t *testing.T) {
  2869  	m := testModule(t, "apply-destroy-mod-var-and-count")
  2870  	p := testProvider("aws")
  2871  	p.ApplyFn = testApplyFn
  2872  	p.DiffFn = testDiffFn
  2873  
  2874  	var state *State
  2875  	var err error
  2876  	{
  2877  		ctx := testContext2(t, &ContextOpts{
  2878  			Module: m,
  2879  			Providers: map[string]ResourceProviderFactory{
  2880  				"aws": testProviderFuncFixed(p),
  2881  			},
  2882  		})
  2883  
  2884  		// First plan and apply a create operation
  2885  		if _, err := ctx.Plan(); err != nil {
  2886  			t.Fatalf("plan err: %s", err)
  2887  		}
  2888  
  2889  		state, err = ctx.Apply()
  2890  		if err != nil {
  2891  			t.Fatalf("apply err: %s", err)
  2892  		}
  2893  	}
  2894  
  2895  	h := new(HookRecordApplyOrder)
  2896  	h.Active = true
  2897  
  2898  	{
  2899  		ctx := testContext2(t, &ContextOpts{
  2900  			Destroy: true,
  2901  			Module:  m,
  2902  			State:   state,
  2903  			Hooks:   []Hook{h},
  2904  			Providers: map[string]ResourceProviderFactory{
  2905  				"aws": testProviderFuncFixed(p),
  2906  			},
  2907  		})
  2908  
  2909  		// First plan and apply a create operation
  2910  		plan, err := ctx.Plan()
  2911  		if err != nil {
  2912  			t.Fatalf("destroy plan err: %s", err)
  2913  		}
  2914  
  2915  		var buf bytes.Buffer
  2916  		if err := WritePlan(plan, &buf); err != nil {
  2917  			t.Fatalf("plan write err: %s", err)
  2918  		}
  2919  
  2920  		planFromFile, err := ReadPlan(&buf)
  2921  		if err != nil {
  2922  			t.Fatalf("plan read err: %s", err)
  2923  		}
  2924  
  2925  		ctx, err = planFromFile.Context(&ContextOpts{
  2926  			Providers: map[string]ResourceProviderFactory{
  2927  				"aws": testProviderFuncFixed(p),
  2928  			},
  2929  		})
  2930  		if err != nil {
  2931  			t.Fatalf("err: %s", err)
  2932  		}
  2933  
  2934  		state, err = ctx.Apply()
  2935  		if err != nil {
  2936  			t.Fatalf("destroy apply err: %s", err)
  2937  		}
  2938  	}
  2939  
  2940  	//Test that things were destroyed
  2941  	actual := strings.TrimSpace(state.String())
  2942  	expected := strings.TrimSpace(`
  2943  <no state>
  2944  module.child:
  2945    <no state>
  2946  		`)
  2947  	if actual != expected {
  2948  		t.Fatalf("expected: \n%s\n\nbad: \n%s", expected, actual)
  2949  	}
  2950  }
  2951  
  2952  func TestContext2Apply_destroyWithModuleVariableAndCountNested(t *testing.T) {
  2953  	m := testModule(t, "apply-destroy-mod-var-and-count-nested")
  2954  	p := testProvider("aws")
  2955  	p.ApplyFn = testApplyFn
  2956  	p.DiffFn = testDiffFn
  2957  
  2958  	var state *State
  2959  	var err error
  2960  	{
  2961  		ctx := testContext2(t, &ContextOpts{
  2962  			Module: m,
  2963  			Providers: map[string]ResourceProviderFactory{
  2964  				"aws": testProviderFuncFixed(p),
  2965  			},
  2966  		})
  2967  
  2968  		// First plan and apply a create operation
  2969  		if _, err := ctx.Plan(); err != nil {
  2970  			t.Fatalf("plan err: %s", err)
  2971  		}
  2972  
  2973  		state, err = ctx.Apply()
  2974  		if err != nil {
  2975  			t.Fatalf("apply err: %s", err)
  2976  		}
  2977  	}
  2978  
  2979  	h := new(HookRecordApplyOrder)
  2980  	h.Active = true
  2981  
  2982  	{
  2983  		ctx := testContext2(t, &ContextOpts{
  2984  			Destroy: true,
  2985  			Module:  m,
  2986  			State:   state,
  2987  			Hooks:   []Hook{h},
  2988  			Providers: map[string]ResourceProviderFactory{
  2989  				"aws": testProviderFuncFixed(p),
  2990  			},
  2991  		})
  2992  
  2993  		// First plan and apply a create operation
  2994  		plan, err := ctx.Plan()
  2995  		if err != nil {
  2996  			t.Fatalf("destroy plan err: %s", err)
  2997  		}
  2998  
  2999  		var buf bytes.Buffer
  3000  		if err := WritePlan(plan, &buf); err != nil {
  3001  			t.Fatalf("plan write err: %s", err)
  3002  		}
  3003  
  3004  		planFromFile, err := ReadPlan(&buf)
  3005  		if err != nil {
  3006  			t.Fatalf("plan read err: %s", err)
  3007  		}
  3008  
  3009  		ctx, err = planFromFile.Context(&ContextOpts{
  3010  			Providers: map[string]ResourceProviderFactory{
  3011  				"aws": testProviderFuncFixed(p),
  3012  			},
  3013  		})
  3014  		if err != nil {
  3015  			t.Fatalf("err: %s", err)
  3016  		}
  3017  
  3018  		state, err = ctx.Apply()
  3019  		if err != nil {
  3020  			t.Fatalf("destroy apply err: %s", err)
  3021  		}
  3022  	}
  3023  
  3024  	//Test that things were destroyed
  3025  	actual := strings.TrimSpace(state.String())
  3026  	expected := strings.TrimSpace(`
  3027  <no state>
  3028  module.child:
  3029    <no state>
  3030  module.child.child2:
  3031    <no state>
  3032  		`)
  3033  	if actual != expected {
  3034  		t.Fatalf("expected: \n%s\n\nbad: \n%s", expected, actual)
  3035  	}
  3036  }
  3037  
  3038  func TestContext2Apply_destroyOutputs(t *testing.T) {
  3039  	m := testModule(t, "apply-destroy-outputs")
  3040  	h := new(HookRecordApplyOrder)
  3041  	p := testProvider("aws")
  3042  	p.ApplyFn = testApplyFn
  3043  	p.DiffFn = testDiffFn
  3044  	ctx := testContext2(t, &ContextOpts{
  3045  		Module: m,
  3046  		Hooks:  []Hook{h},
  3047  		Providers: map[string]ResourceProviderFactory{
  3048  			"aws": testProviderFuncFixed(p),
  3049  		},
  3050  	})
  3051  
  3052  	// First plan and apply a create operation
  3053  	if _, err := ctx.Plan(); err != nil {
  3054  		t.Fatalf("err: %s", err)
  3055  	}
  3056  
  3057  	state, err := ctx.Apply()
  3058  
  3059  	if err != nil {
  3060  		t.Fatalf("err: %s", err)
  3061  	}
  3062  
  3063  	// Next, plan and apply a destroy operation
  3064  	h.Active = true
  3065  	ctx = testContext2(t, &ContextOpts{
  3066  		Destroy: true,
  3067  		State:   state,
  3068  		Module:  m,
  3069  		Hooks:   []Hook{h},
  3070  		Providers: map[string]ResourceProviderFactory{
  3071  			"aws": testProviderFuncFixed(p),
  3072  		},
  3073  	})
  3074  
  3075  	if _, err := ctx.Plan(); err != nil {
  3076  		t.Fatalf("err: %s", err)
  3077  	}
  3078  
  3079  	state, err = ctx.Apply()
  3080  	if err != nil {
  3081  		t.Fatalf("err: %s", err)
  3082  	}
  3083  
  3084  	mod := state.RootModule()
  3085  	if len(mod.Resources) > 0 {
  3086  		t.Fatalf("bad: %#v", mod)
  3087  	}
  3088  }
  3089  
  3090  func TestContext2Apply_destroyOrphan(t *testing.T) {
  3091  	m := testModule(t, "apply-error")
  3092  	p := testProvider("aws")
  3093  	s := &State{
  3094  		Modules: []*ModuleState{
  3095  			&ModuleState{
  3096  				Path: rootModulePath,
  3097  				Resources: map[string]*ResourceState{
  3098  					"aws_instance.baz": &ResourceState{
  3099  						Type: "aws_instance",
  3100  						Primary: &InstanceState{
  3101  							ID: "bar",
  3102  						},
  3103  					},
  3104  				},
  3105  			},
  3106  		},
  3107  	}
  3108  	ctx := testContext2(t, &ContextOpts{
  3109  		Module: m,
  3110  		Providers: map[string]ResourceProviderFactory{
  3111  			"aws": testProviderFuncFixed(p),
  3112  		},
  3113  		State: s,
  3114  	})
  3115  
  3116  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  3117  		if d.Destroy {
  3118  			return nil, nil
  3119  		}
  3120  
  3121  		result := s.MergeDiff(d)
  3122  		result.ID = "foo"
  3123  		return result, nil
  3124  	}
  3125  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  3126  		return &InstanceDiff{
  3127  			Attributes: map[string]*ResourceAttrDiff{
  3128  				"num": &ResourceAttrDiff{
  3129  					New: "bar",
  3130  				},
  3131  			},
  3132  		}, nil
  3133  	}
  3134  
  3135  	if _, err := ctx.Plan(); err != nil {
  3136  		t.Fatalf("err: %s", err)
  3137  	}
  3138  
  3139  	state, err := ctx.Apply()
  3140  	if err != nil {
  3141  		t.Fatalf("err: %s", err)
  3142  	}
  3143  
  3144  	mod := state.RootModule()
  3145  	if _, ok := mod.Resources["aws_instance.baz"]; ok {
  3146  		t.Fatalf("bad: %#v", mod.Resources)
  3147  	}
  3148  }
  3149  
  3150  func TestContext2Apply_destroyTaintedProvisioner(t *testing.T) {
  3151  	m := testModule(t, "apply-destroy-provisioner")
  3152  	p := testProvider("aws")
  3153  	pr := testProvisioner()
  3154  	p.ApplyFn = testApplyFn
  3155  	p.DiffFn = testDiffFn
  3156  
  3157  	called := false
  3158  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  3159  		called = true
  3160  		return nil
  3161  	}
  3162  
  3163  	s := &State{
  3164  		Modules: []*ModuleState{
  3165  			&ModuleState{
  3166  				Path: rootModulePath,
  3167  				Resources: map[string]*ResourceState{
  3168  					"aws_instance.foo": &ResourceState{
  3169  						Type: "aws_instance",
  3170  						Primary: &InstanceState{
  3171  							ID: "bar",
  3172  							Attributes: map[string]string{
  3173  								"id": "bar",
  3174  							},
  3175  							Tainted: true,
  3176  						},
  3177  					},
  3178  				},
  3179  			},
  3180  		},
  3181  	}
  3182  
  3183  	ctx := testContext2(t, &ContextOpts{
  3184  		Module: m,
  3185  		Providers: map[string]ResourceProviderFactory{
  3186  			"aws": testProviderFuncFixed(p),
  3187  		},
  3188  		Provisioners: map[string]ResourceProvisionerFactory{
  3189  			"shell": testProvisionerFuncFixed(pr),
  3190  		},
  3191  		State:   s,
  3192  		Destroy: true,
  3193  	})
  3194  
  3195  	if _, err := ctx.Plan(); err != nil {
  3196  		t.Fatalf("err: %s", err)
  3197  	}
  3198  
  3199  	state, err := ctx.Apply()
  3200  	if err != nil {
  3201  		t.Fatalf("err: %s", err)
  3202  	}
  3203  
  3204  	if called {
  3205  		t.Fatal("provisioner should not be called")
  3206  	}
  3207  
  3208  	actual := strings.TrimSpace(state.String())
  3209  	expected := strings.TrimSpace("<no state>")
  3210  	if actual != expected {
  3211  		t.Fatalf("bad: \n%s", actual)
  3212  	}
  3213  }
  3214  
  3215  func TestContext2Apply_error(t *testing.T) {
  3216  	errored := false
  3217  
  3218  	m := testModule(t, "apply-error")
  3219  	p := testProvider("aws")
  3220  	ctx := testContext2(t, &ContextOpts{
  3221  		Module: m,
  3222  		Providers: map[string]ResourceProviderFactory{
  3223  			"aws": testProviderFuncFixed(p),
  3224  		},
  3225  	})
  3226  
  3227  	p.ApplyFn = func(*InstanceInfo, *InstanceState, *InstanceDiff) (*InstanceState, error) {
  3228  		if errored {
  3229  			state := &InstanceState{
  3230  				ID: "bar",
  3231  			}
  3232  			return state, fmt.Errorf("error")
  3233  		}
  3234  		errored = true
  3235  
  3236  		return &InstanceState{
  3237  			ID: "foo",
  3238  			Attributes: map[string]string{
  3239  				"num": "2",
  3240  			},
  3241  		}, nil
  3242  	}
  3243  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  3244  		return &InstanceDiff{
  3245  			Attributes: map[string]*ResourceAttrDiff{
  3246  				"num": &ResourceAttrDiff{
  3247  					New: "bar",
  3248  				},
  3249  			},
  3250  		}, nil
  3251  	}
  3252  
  3253  	if _, err := ctx.Plan(); err != nil {
  3254  		t.Fatalf("err: %s", err)
  3255  	}
  3256  
  3257  	state, err := ctx.Apply()
  3258  	if err == nil {
  3259  		t.Fatal("should have error")
  3260  	}
  3261  
  3262  	actual := strings.TrimSpace(state.String())
  3263  	expected := strings.TrimSpace(testTerraformApplyErrorStr)
  3264  	if actual != expected {
  3265  		t.Fatalf("bad: \n%s", actual)
  3266  	}
  3267  }
  3268  
  3269  func TestContext2Apply_errorPartial(t *testing.T) {
  3270  	errored := false
  3271  
  3272  	m := testModule(t, "apply-error")
  3273  	p := testProvider("aws")
  3274  	s := &State{
  3275  		Modules: []*ModuleState{
  3276  			&ModuleState{
  3277  				Path: rootModulePath,
  3278  				Resources: map[string]*ResourceState{
  3279  					"aws_instance.bar": &ResourceState{
  3280  						Type: "aws_instance",
  3281  						Primary: &InstanceState{
  3282  							ID: "bar",
  3283  						},
  3284  					},
  3285  				},
  3286  			},
  3287  		},
  3288  	}
  3289  	ctx := testContext2(t, &ContextOpts{
  3290  		Module: m,
  3291  		Providers: map[string]ResourceProviderFactory{
  3292  			"aws": testProviderFuncFixed(p),
  3293  		},
  3294  		State: s,
  3295  	})
  3296  
  3297  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  3298  		if errored {
  3299  			return s, fmt.Errorf("error")
  3300  		}
  3301  		errored = true
  3302  
  3303  		return &InstanceState{
  3304  			ID: "foo",
  3305  			Attributes: map[string]string{
  3306  				"num": "2",
  3307  			},
  3308  		}, nil
  3309  	}
  3310  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  3311  		return &InstanceDiff{
  3312  			Attributes: map[string]*ResourceAttrDiff{
  3313  				"num": &ResourceAttrDiff{
  3314  					New: "bar",
  3315  				},
  3316  			},
  3317  		}, nil
  3318  	}
  3319  
  3320  	if _, err := ctx.Plan(); err != nil {
  3321  		t.Fatalf("err: %s", err)
  3322  	}
  3323  
  3324  	state, err := ctx.Apply()
  3325  	if err == nil {
  3326  		t.Fatal("should have error")
  3327  	}
  3328  
  3329  	mod := state.RootModule()
  3330  	if len(mod.Resources) != 2 {
  3331  		t.Fatalf("bad: %#v", mod.Resources)
  3332  	}
  3333  
  3334  	actual := strings.TrimSpace(state.String())
  3335  	expected := strings.TrimSpace(testTerraformApplyErrorPartialStr)
  3336  	if actual != expected {
  3337  		t.Fatalf("bad: \n%s", actual)
  3338  	}
  3339  }
  3340  
  3341  func TestContext2Apply_hook(t *testing.T) {
  3342  	m := testModule(t, "apply-good")
  3343  	h := new(MockHook)
  3344  	p := testProvider("aws")
  3345  	p.ApplyFn = testApplyFn
  3346  	p.DiffFn = testDiffFn
  3347  	ctx := testContext2(t, &ContextOpts{
  3348  		Module: m,
  3349  		Hooks:  []Hook{h},
  3350  		Providers: map[string]ResourceProviderFactory{
  3351  			"aws": testProviderFuncFixed(p),
  3352  		},
  3353  	})
  3354  
  3355  	if _, err := ctx.Plan(); err != nil {
  3356  		t.Fatalf("err: %s", err)
  3357  	}
  3358  
  3359  	if _, err := ctx.Apply(); err != nil {
  3360  		t.Fatalf("err: %s", err)
  3361  	}
  3362  
  3363  	if !h.PreApplyCalled {
  3364  		t.Fatal("should be called")
  3365  	}
  3366  	if !h.PostApplyCalled {
  3367  		t.Fatal("should be called")
  3368  	}
  3369  	if !h.PostStateUpdateCalled {
  3370  		t.Fatalf("should call post state update")
  3371  	}
  3372  }
  3373  
  3374  func TestContext2Apply_hookOrphan(t *testing.T) {
  3375  	m := testModule(t, "apply-blank")
  3376  	h := new(MockHook)
  3377  	p := testProvider("aws")
  3378  	p.ApplyFn = testApplyFn
  3379  	p.DiffFn = testDiffFn
  3380  
  3381  	state := &State{
  3382  		Modules: []*ModuleState{
  3383  			&ModuleState{
  3384  				Path: rootModulePath,
  3385  				Resources: map[string]*ResourceState{
  3386  					"aws_instance.bar": &ResourceState{
  3387  						Type: "aws_instance",
  3388  						Primary: &InstanceState{
  3389  							ID: "bar",
  3390  						},
  3391  					},
  3392  				},
  3393  			},
  3394  		},
  3395  	}
  3396  
  3397  	ctx := testContext2(t, &ContextOpts{
  3398  		Module: m,
  3399  		State:  state,
  3400  		Hooks:  []Hook{h},
  3401  		Providers: map[string]ResourceProviderFactory{
  3402  			"aws": testProviderFuncFixed(p),
  3403  		},
  3404  	})
  3405  
  3406  	if _, err := ctx.Plan(); err != nil {
  3407  		t.Fatalf("err: %s", err)
  3408  	}
  3409  
  3410  	if _, err := ctx.Apply(); err != nil {
  3411  		t.Fatalf("err: %s", err)
  3412  	}
  3413  
  3414  	if !h.PreApplyCalled {
  3415  		t.Fatal("should be called")
  3416  	}
  3417  	if !h.PostApplyCalled {
  3418  		t.Fatal("should be called")
  3419  	}
  3420  	if !h.PostStateUpdateCalled {
  3421  		t.Fatalf("should call post state update")
  3422  	}
  3423  }
  3424  
  3425  func TestContext2Apply_idAttr(t *testing.T) {
  3426  	m := testModule(t, "apply-idattr")
  3427  	p := testProvider("aws")
  3428  	ctx := testContext2(t, &ContextOpts{
  3429  		Module: m,
  3430  		Providers: map[string]ResourceProviderFactory{
  3431  			"aws": testProviderFuncFixed(p),
  3432  		},
  3433  	})
  3434  
  3435  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  3436  		result := s.MergeDiff(d)
  3437  		result.ID = "foo"
  3438  		result.Attributes = map[string]string{
  3439  			"id": "bar",
  3440  		}
  3441  
  3442  		return result, nil
  3443  	}
  3444  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  3445  		return &InstanceDiff{
  3446  			Attributes: map[string]*ResourceAttrDiff{
  3447  				"num": &ResourceAttrDiff{
  3448  					New: "bar",
  3449  				},
  3450  			},
  3451  		}, nil
  3452  	}
  3453  
  3454  	if _, err := ctx.Plan(); err != nil {
  3455  		t.Fatalf("err: %s", err)
  3456  	}
  3457  
  3458  	state, err := ctx.Apply()
  3459  	if err != nil {
  3460  		t.Fatalf("err: %s", err)
  3461  	}
  3462  
  3463  	mod := state.RootModule()
  3464  	rs, ok := mod.Resources["aws_instance.foo"]
  3465  	if !ok {
  3466  		t.Fatal("not in state")
  3467  	}
  3468  	if rs.Primary.ID != "foo" {
  3469  		t.Fatalf("bad: %#v", rs.Primary.ID)
  3470  	}
  3471  	if rs.Primary.Attributes["id"] != "foo" {
  3472  		t.Fatalf("bad: %#v", rs.Primary.Attributes)
  3473  	}
  3474  }
  3475  
  3476  func TestContext2Apply_output(t *testing.T) {
  3477  	m := testModule(t, "apply-output")
  3478  	p := testProvider("aws")
  3479  	p.ApplyFn = testApplyFn
  3480  	p.DiffFn = testDiffFn
  3481  	ctx := testContext2(t, &ContextOpts{
  3482  		Module: m,
  3483  		Providers: map[string]ResourceProviderFactory{
  3484  			"aws": testProviderFuncFixed(p),
  3485  		},
  3486  	})
  3487  
  3488  	if _, err := ctx.Plan(); err != nil {
  3489  		t.Fatalf("err: %s", err)
  3490  	}
  3491  
  3492  	state, err := ctx.Apply()
  3493  	if err != nil {
  3494  		t.Fatalf("err: %s", err)
  3495  	}
  3496  
  3497  	actual := strings.TrimSpace(state.String())
  3498  	expected := strings.TrimSpace(testTerraformApplyOutputStr)
  3499  	if actual != expected {
  3500  		t.Fatalf("bad: \n%s", actual)
  3501  	}
  3502  }
  3503  
  3504  func TestContext2Apply_outputInvalid(t *testing.T) {
  3505  	m := testModule(t, "apply-output-invalid")
  3506  	p := testProvider("aws")
  3507  	p.ApplyFn = testApplyFn
  3508  	p.DiffFn = testDiffFn
  3509  	ctx := testContext2(t, &ContextOpts{
  3510  		Module: m,
  3511  		Providers: map[string]ResourceProviderFactory{
  3512  			"aws": testProviderFuncFixed(p),
  3513  		},
  3514  	})
  3515  
  3516  	_, err := ctx.Plan()
  3517  	if err == nil {
  3518  		t.Fatalf("err: %s", err)
  3519  	}
  3520  	if !strings.Contains(err.Error(), "is not a valid type") {
  3521  		t.Fatalf("err: %s", err)
  3522  	}
  3523  }
  3524  
  3525  func TestContext2Apply_outputAdd(t *testing.T) {
  3526  	m1 := testModule(t, "apply-output-add-before")
  3527  	p1 := testProvider("aws")
  3528  	p1.ApplyFn = testApplyFn
  3529  	p1.DiffFn = testDiffFn
  3530  	ctx1 := testContext2(t, &ContextOpts{
  3531  		Module: m1,
  3532  		Providers: map[string]ResourceProviderFactory{
  3533  			"aws": testProviderFuncFixed(p1),
  3534  		},
  3535  	})
  3536  
  3537  	if _, err := ctx1.Plan(); err != nil {
  3538  		t.Fatalf("err: %s", err)
  3539  	}
  3540  
  3541  	state1, err := ctx1.Apply()
  3542  	if err != nil {
  3543  		t.Fatalf("err: %s", err)
  3544  	}
  3545  
  3546  	m2 := testModule(t, "apply-output-add-after")
  3547  	p2 := testProvider("aws")
  3548  	p2.ApplyFn = testApplyFn
  3549  	p2.DiffFn = testDiffFn
  3550  	ctx2 := testContext2(t, &ContextOpts{
  3551  		Module: m2,
  3552  		Providers: map[string]ResourceProviderFactory{
  3553  			"aws": testProviderFuncFixed(p2),
  3554  		},
  3555  		State: state1,
  3556  	})
  3557  
  3558  	if _, err := ctx2.Plan(); err != nil {
  3559  		t.Fatalf("err: %s", err)
  3560  	}
  3561  
  3562  	state2, err := ctx2.Apply()
  3563  	if err != nil {
  3564  		t.Fatalf("err: %s", err)
  3565  	}
  3566  
  3567  	actual := strings.TrimSpace(state2.String())
  3568  	expected := strings.TrimSpace(testTerraformApplyOutputAddStr)
  3569  	if actual != expected {
  3570  		t.Fatalf("bad: \n%s", actual)
  3571  	}
  3572  }
  3573  
  3574  func TestContext2Apply_outputList(t *testing.T) {
  3575  	m := testModule(t, "apply-output-list")
  3576  	p := testProvider("aws")
  3577  	p.ApplyFn = testApplyFn
  3578  	p.DiffFn = testDiffFn
  3579  	ctx := testContext2(t, &ContextOpts{
  3580  		Module: m,
  3581  		Providers: map[string]ResourceProviderFactory{
  3582  			"aws": testProviderFuncFixed(p),
  3583  		},
  3584  	})
  3585  
  3586  	if _, err := ctx.Plan(); err != nil {
  3587  		t.Fatalf("err: %s", err)
  3588  	}
  3589  
  3590  	state, err := ctx.Apply()
  3591  	if err != nil {
  3592  		t.Fatalf("err: %s", err)
  3593  	}
  3594  
  3595  	actual := strings.TrimSpace(state.String())
  3596  	expected := strings.TrimSpace(testTerraformApplyOutputListStr)
  3597  	if actual != expected {
  3598  		t.Fatalf("expected: \n%s\n\nbad: \n%s", expected, actual)
  3599  	}
  3600  }
  3601  
  3602  func TestContext2Apply_outputMulti(t *testing.T) {
  3603  	m := testModule(t, "apply-output-multi")
  3604  	p := testProvider("aws")
  3605  	p.ApplyFn = testApplyFn
  3606  	p.DiffFn = testDiffFn
  3607  	ctx := testContext2(t, &ContextOpts{
  3608  		Module: m,
  3609  		Providers: map[string]ResourceProviderFactory{
  3610  			"aws": testProviderFuncFixed(p),
  3611  		},
  3612  	})
  3613  
  3614  	if _, err := ctx.Plan(); err != nil {
  3615  		t.Fatalf("err: %s", err)
  3616  	}
  3617  
  3618  	state, err := ctx.Apply()
  3619  	if err != nil {
  3620  		t.Fatalf("err: %s", err)
  3621  	}
  3622  
  3623  	actual := strings.TrimSpace(state.String())
  3624  	expected := strings.TrimSpace(testTerraformApplyOutputMultiStr)
  3625  	if actual != expected {
  3626  		t.Fatalf("bad: \n%s", actual)
  3627  	}
  3628  }
  3629  
  3630  func TestContext2Apply_outputMultiIndex(t *testing.T) {
  3631  	m := testModule(t, "apply-output-multi-index")
  3632  	p := testProvider("aws")
  3633  	p.ApplyFn = testApplyFn
  3634  	p.DiffFn = testDiffFn
  3635  	ctx := testContext2(t, &ContextOpts{
  3636  		Module: m,
  3637  		Providers: map[string]ResourceProviderFactory{
  3638  			"aws": testProviderFuncFixed(p),
  3639  		},
  3640  	})
  3641  
  3642  	if _, err := ctx.Plan(); err != nil {
  3643  		t.Fatalf("err: %s", err)
  3644  	}
  3645  
  3646  	state, err := ctx.Apply()
  3647  	if err != nil {
  3648  		t.Fatalf("err: %s", err)
  3649  	}
  3650  
  3651  	actual := strings.TrimSpace(state.String())
  3652  	expected := strings.TrimSpace(testTerraformApplyOutputMultiIndexStr)
  3653  	if actual != expected {
  3654  		t.Fatalf("bad: \n%s", actual)
  3655  	}
  3656  }
  3657  
  3658  func TestContext2Apply_taint(t *testing.T) {
  3659  	m := testModule(t, "apply-taint")
  3660  	p := testProvider("aws")
  3661  
  3662  	// destroyCount tests against regression of
  3663  	// https://github.com/hashicorp/terraform/issues/1056
  3664  	var destroyCount = int32(0)
  3665  	var once sync.Once
  3666  	simulateProviderDelay := func() {
  3667  		time.Sleep(10 * time.Millisecond)
  3668  	}
  3669  
  3670  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  3671  		once.Do(simulateProviderDelay)
  3672  		if d.Destroy {
  3673  			atomic.AddInt32(&destroyCount, 1)
  3674  		}
  3675  		return testApplyFn(info, s, d)
  3676  	}
  3677  	p.DiffFn = testDiffFn
  3678  	s := &State{
  3679  		Modules: []*ModuleState{
  3680  			&ModuleState{
  3681  				Path: rootModulePath,
  3682  				Resources: map[string]*ResourceState{
  3683  					"aws_instance.bar": &ResourceState{
  3684  						Type: "aws_instance",
  3685  						Primary: &InstanceState{
  3686  							ID: "baz",
  3687  							Attributes: map[string]string{
  3688  								"num":  "2",
  3689  								"type": "aws_instance",
  3690  							},
  3691  							Tainted: true,
  3692  						},
  3693  					},
  3694  				},
  3695  			},
  3696  		},
  3697  	}
  3698  	ctx := testContext2(t, &ContextOpts{
  3699  		Module: m,
  3700  		Providers: map[string]ResourceProviderFactory{
  3701  			"aws": testProviderFuncFixed(p),
  3702  		},
  3703  		State: s,
  3704  	})
  3705  
  3706  	if _, err := ctx.Plan(); err != nil {
  3707  		t.Fatalf("err: %s", err)
  3708  	}
  3709  
  3710  	state, err := ctx.Apply()
  3711  	if err != nil {
  3712  		t.Fatalf("err: %s", err)
  3713  	}
  3714  
  3715  	actual := strings.TrimSpace(state.String())
  3716  	expected := strings.TrimSpace(testTerraformApplyTaintStr)
  3717  	if actual != expected {
  3718  		t.Fatalf("bad:\n%s", actual)
  3719  	}
  3720  
  3721  	if destroyCount != 1 {
  3722  		t.Fatalf("Expected 1 destroy, got %d", destroyCount)
  3723  	}
  3724  }
  3725  
  3726  func TestContext2Apply_taintDep(t *testing.T) {
  3727  	m := testModule(t, "apply-taint-dep")
  3728  	p := testProvider("aws")
  3729  	p.ApplyFn = testApplyFn
  3730  	p.DiffFn = testDiffFn
  3731  	s := &State{
  3732  		Modules: []*ModuleState{
  3733  			&ModuleState{
  3734  				Path: rootModulePath,
  3735  				Resources: map[string]*ResourceState{
  3736  					"aws_instance.foo": &ResourceState{
  3737  						Type: "aws_instance",
  3738  						Primary: &InstanceState{
  3739  							ID: "baz",
  3740  							Attributes: map[string]string{
  3741  								"num":  "2",
  3742  								"type": "aws_instance",
  3743  							},
  3744  							Tainted: true,
  3745  						},
  3746  					},
  3747  					"aws_instance.bar": &ResourceState{
  3748  						Type: "aws_instance",
  3749  						Primary: &InstanceState{
  3750  							ID: "bar",
  3751  							Attributes: map[string]string{
  3752  								"foo":  "baz",
  3753  								"num":  "2",
  3754  								"type": "aws_instance",
  3755  							},
  3756  						},
  3757  					},
  3758  				},
  3759  			},
  3760  		},
  3761  	}
  3762  	ctx := testContext2(t, &ContextOpts{
  3763  		Module: m,
  3764  		Providers: map[string]ResourceProviderFactory{
  3765  			"aws": testProviderFuncFixed(p),
  3766  		},
  3767  		State: s,
  3768  	})
  3769  
  3770  	if p, err := ctx.Plan(); err != nil {
  3771  		t.Fatalf("err: %s", err)
  3772  	} else {
  3773  		t.Logf("plan: %s", p)
  3774  	}
  3775  
  3776  	state, err := ctx.Apply()
  3777  	if err != nil {
  3778  		t.Fatalf("err: %s", err)
  3779  	}
  3780  
  3781  	actual := strings.TrimSpace(state.String())
  3782  	expected := strings.TrimSpace(testTerraformApplyTaintDepStr)
  3783  	if actual != expected {
  3784  		t.Fatalf("bad:\n%s", actual)
  3785  	}
  3786  }
  3787  
  3788  func TestContext2Apply_taintDepRequiresNew(t *testing.T) {
  3789  	m := testModule(t, "apply-taint-dep-requires-new")
  3790  	p := testProvider("aws")
  3791  	p.ApplyFn = testApplyFn
  3792  	p.DiffFn = testDiffFn
  3793  	s := &State{
  3794  		Modules: []*ModuleState{
  3795  			&ModuleState{
  3796  				Path: rootModulePath,
  3797  				Resources: map[string]*ResourceState{
  3798  					"aws_instance.foo": &ResourceState{
  3799  						Type: "aws_instance",
  3800  						Primary: &InstanceState{
  3801  							ID: "baz",
  3802  							Attributes: map[string]string{
  3803  								"num":  "2",
  3804  								"type": "aws_instance",
  3805  							},
  3806  							Tainted: true,
  3807  						},
  3808  					},
  3809  					"aws_instance.bar": &ResourceState{
  3810  						Type: "aws_instance",
  3811  						Primary: &InstanceState{
  3812  							ID: "bar",
  3813  							Attributes: map[string]string{
  3814  								"foo":  "baz",
  3815  								"num":  "2",
  3816  								"type": "aws_instance",
  3817  							},
  3818  						},
  3819  					},
  3820  				},
  3821  			},
  3822  		},
  3823  	}
  3824  	ctx := testContext2(t, &ContextOpts{
  3825  		Module: m,
  3826  		Providers: map[string]ResourceProviderFactory{
  3827  			"aws": testProviderFuncFixed(p),
  3828  		},
  3829  		State: s,
  3830  	})
  3831  
  3832  	if p, err := ctx.Plan(); err != nil {
  3833  		t.Fatalf("err: %s", err)
  3834  	} else {
  3835  		t.Logf("plan: %s", p)
  3836  	}
  3837  
  3838  	state, err := ctx.Apply()
  3839  	if err != nil {
  3840  		t.Fatalf("err: %s", err)
  3841  	}
  3842  
  3843  	actual := strings.TrimSpace(state.String())
  3844  	expected := strings.TrimSpace(testTerraformApplyTaintDepRequireNewStr)
  3845  	if actual != expected {
  3846  		t.Fatalf("bad:\n%s", actual)
  3847  	}
  3848  }
  3849  
  3850  func TestContext2Apply_targeted(t *testing.T) {
  3851  	m := testModule(t, "apply-targeted")
  3852  	p := testProvider("aws")
  3853  	p.ApplyFn = testApplyFn
  3854  	p.DiffFn = testDiffFn
  3855  	ctx := testContext2(t, &ContextOpts{
  3856  		Module: m,
  3857  		Providers: map[string]ResourceProviderFactory{
  3858  			"aws": testProviderFuncFixed(p),
  3859  		},
  3860  		Targets: []string{"aws_instance.foo"},
  3861  	})
  3862  
  3863  	if _, err := ctx.Plan(); err != nil {
  3864  		t.Fatalf("err: %s", err)
  3865  	}
  3866  
  3867  	state, err := ctx.Apply()
  3868  	if err != nil {
  3869  		t.Fatalf("err: %s", err)
  3870  	}
  3871  
  3872  	mod := state.RootModule()
  3873  	if len(mod.Resources) != 1 {
  3874  		t.Fatalf("expected 1 resource, got: %#v", mod.Resources)
  3875  	}
  3876  
  3877  	checkStateString(t, state, `
  3878  aws_instance.foo:
  3879    ID = foo
  3880    num = 2
  3881    type = aws_instance
  3882  	`)
  3883  }
  3884  
  3885  func TestContext2Apply_targetedCount(t *testing.T) {
  3886  	m := testModule(t, "apply-targeted-count")
  3887  	p := testProvider("aws")
  3888  	p.ApplyFn = testApplyFn
  3889  	p.DiffFn = testDiffFn
  3890  	ctx := testContext2(t, &ContextOpts{
  3891  		Module: m,
  3892  		Providers: map[string]ResourceProviderFactory{
  3893  			"aws": testProviderFuncFixed(p),
  3894  		},
  3895  		Targets: []string{"aws_instance.foo"},
  3896  	})
  3897  
  3898  	if _, err := ctx.Plan(); err != nil {
  3899  		t.Fatalf("err: %s", err)
  3900  	}
  3901  
  3902  	state, err := ctx.Apply()
  3903  	if err != nil {
  3904  		t.Fatalf("err: %s", err)
  3905  	}
  3906  
  3907  	checkStateString(t, state, `
  3908  aws_instance.foo.0:
  3909    ID = foo
  3910  aws_instance.foo.1:
  3911    ID = foo
  3912  aws_instance.foo.2:
  3913    ID = foo
  3914  	`)
  3915  }
  3916  
  3917  func TestContext2Apply_targetedCountIndex(t *testing.T) {
  3918  	m := testModule(t, "apply-targeted-count")
  3919  	p := testProvider("aws")
  3920  	p.ApplyFn = testApplyFn
  3921  	p.DiffFn = testDiffFn
  3922  	ctx := testContext2(t, &ContextOpts{
  3923  		Module: m,
  3924  		Providers: map[string]ResourceProviderFactory{
  3925  			"aws": testProviderFuncFixed(p),
  3926  		},
  3927  		Targets: []string{"aws_instance.foo[1]"},
  3928  	})
  3929  
  3930  	if _, err := ctx.Plan(); err != nil {
  3931  		t.Fatalf("err: %s", err)
  3932  	}
  3933  
  3934  	state, err := ctx.Apply()
  3935  	if err != nil {
  3936  		t.Fatalf("err: %s", err)
  3937  	}
  3938  
  3939  	checkStateString(t, state, `
  3940  aws_instance.foo.1:
  3941    ID = foo
  3942  	`)
  3943  }
  3944  
  3945  func TestContext2Apply_targetedDestroy(t *testing.T) {
  3946  	m := testModule(t, "apply-targeted")
  3947  	p := testProvider("aws")
  3948  	p.ApplyFn = testApplyFn
  3949  	p.DiffFn = testDiffFn
  3950  	ctx := testContext2(t, &ContextOpts{
  3951  		Module: m,
  3952  		Providers: map[string]ResourceProviderFactory{
  3953  			"aws": testProviderFuncFixed(p),
  3954  		},
  3955  		State: &State{
  3956  			Modules: []*ModuleState{
  3957  				&ModuleState{
  3958  					Path: rootModulePath,
  3959  					Resources: map[string]*ResourceState{
  3960  						"aws_instance.foo": resourceState("aws_instance", "i-bcd345"),
  3961  						"aws_instance.bar": resourceState("aws_instance", "i-abc123"),
  3962  					},
  3963  				},
  3964  			},
  3965  		},
  3966  		Targets: []string{"aws_instance.foo"},
  3967  		Destroy: true,
  3968  	})
  3969  
  3970  	if _, err := ctx.Plan(); err != nil {
  3971  		t.Fatalf("err: %s", err)
  3972  	}
  3973  
  3974  	state, err := ctx.Apply()
  3975  	if err != nil {
  3976  		t.Fatalf("err: %s", err)
  3977  	}
  3978  
  3979  	mod := state.RootModule()
  3980  	if len(mod.Resources) != 1 {
  3981  		t.Fatalf("expected 1 resource, got: %#v", mod.Resources)
  3982  	}
  3983  
  3984  	checkStateString(t, state, `
  3985  aws_instance.bar:
  3986    ID = i-abc123
  3987  	`)
  3988  }
  3989  
  3990  // https://github.com/hashicorp/terraform/issues/4462
  3991  func TestContext2Apply_targetedDestroyModule(t *testing.T) {
  3992  	m := testModule(t, "apply-targeted-module")
  3993  	p := testProvider("aws")
  3994  	p.ApplyFn = testApplyFn
  3995  	p.DiffFn = testDiffFn
  3996  	ctx := testContext2(t, &ContextOpts{
  3997  		Module: m,
  3998  		Providers: map[string]ResourceProviderFactory{
  3999  			"aws": testProviderFuncFixed(p),
  4000  		},
  4001  		State: &State{
  4002  			Modules: []*ModuleState{
  4003  				&ModuleState{
  4004  					Path: rootModulePath,
  4005  					Resources: map[string]*ResourceState{
  4006  						"aws_instance.foo": resourceState("aws_instance", "i-bcd345"),
  4007  						"aws_instance.bar": resourceState("aws_instance", "i-abc123"),
  4008  					},
  4009  				},
  4010  				&ModuleState{
  4011  					Path: []string{"root", "child"},
  4012  					Resources: map[string]*ResourceState{
  4013  						"aws_instance.foo": resourceState("aws_instance", "i-bcd345"),
  4014  						"aws_instance.bar": resourceState("aws_instance", "i-abc123"),
  4015  					},
  4016  				},
  4017  			},
  4018  		},
  4019  		Targets: []string{"module.child.aws_instance.foo"},
  4020  		Destroy: true,
  4021  	})
  4022  
  4023  	if _, err := ctx.Plan(); err != nil {
  4024  		t.Fatalf("err: %s", err)
  4025  	}
  4026  
  4027  	state, err := ctx.Apply()
  4028  	if err != nil {
  4029  		t.Fatalf("err: %s", err)
  4030  	}
  4031  
  4032  	checkStateString(t, state, `
  4033  aws_instance.bar:
  4034    ID = i-abc123
  4035  aws_instance.foo:
  4036    ID = i-bcd345
  4037  
  4038  module.child:
  4039    aws_instance.bar:
  4040      ID = i-abc123
  4041  	`)
  4042  }
  4043  
  4044  func TestContext2Apply_targetedDestroyCountIndex(t *testing.T) {
  4045  	m := testModule(t, "apply-targeted-count")
  4046  	p := testProvider("aws")
  4047  	p.ApplyFn = testApplyFn
  4048  	p.DiffFn = testDiffFn
  4049  	ctx := testContext2(t, &ContextOpts{
  4050  		Module: m,
  4051  		Providers: map[string]ResourceProviderFactory{
  4052  			"aws": testProviderFuncFixed(p),
  4053  		},
  4054  		State: &State{
  4055  			Modules: []*ModuleState{
  4056  				&ModuleState{
  4057  					Path: rootModulePath,
  4058  					Resources: map[string]*ResourceState{
  4059  						"aws_instance.foo.0": resourceState("aws_instance", "i-bcd345"),
  4060  						"aws_instance.foo.1": resourceState("aws_instance", "i-bcd345"),
  4061  						"aws_instance.foo.2": resourceState("aws_instance", "i-bcd345"),
  4062  						"aws_instance.bar.0": resourceState("aws_instance", "i-abc123"),
  4063  						"aws_instance.bar.1": resourceState("aws_instance", "i-abc123"),
  4064  						"aws_instance.bar.2": resourceState("aws_instance", "i-abc123"),
  4065  					},
  4066  				},
  4067  			},
  4068  		},
  4069  		Targets: []string{
  4070  			"aws_instance.foo[2]",
  4071  			"aws_instance.bar[1]",
  4072  		},
  4073  		Destroy: true,
  4074  	})
  4075  
  4076  	if _, err := ctx.Plan(); err != nil {
  4077  		t.Fatalf("err: %s", err)
  4078  	}
  4079  
  4080  	state, err := ctx.Apply()
  4081  	if err != nil {
  4082  		t.Fatalf("err: %s", err)
  4083  	}
  4084  
  4085  	checkStateString(t, state, `
  4086  aws_instance.bar.0:
  4087    ID = i-abc123
  4088  aws_instance.bar.2:
  4089    ID = i-abc123
  4090  aws_instance.foo.0:
  4091    ID = i-bcd345
  4092  aws_instance.foo.1:
  4093    ID = i-bcd345
  4094  	`)
  4095  }
  4096  
  4097  func TestContext2Apply_targetedModule(t *testing.T) {
  4098  	m := testModule(t, "apply-targeted-module")
  4099  	p := testProvider("aws")
  4100  	p.ApplyFn = testApplyFn
  4101  	p.DiffFn = testDiffFn
  4102  	ctx := testContext2(t, &ContextOpts{
  4103  		Module: m,
  4104  		Providers: map[string]ResourceProviderFactory{
  4105  			"aws": testProviderFuncFixed(p),
  4106  		},
  4107  		Targets: []string{"module.child"},
  4108  	})
  4109  
  4110  	if _, err := ctx.Plan(); err != nil {
  4111  		t.Fatalf("err: %s", err)
  4112  	}
  4113  
  4114  	state, err := ctx.Apply()
  4115  	if err != nil {
  4116  		t.Fatalf("err: %s", err)
  4117  	}
  4118  
  4119  	mod := state.ModuleByPath([]string{"root", "child"})
  4120  	if mod == nil {
  4121  		t.Fatalf("no child module found in the state!\n\n%#v", state)
  4122  	}
  4123  	if len(mod.Resources) != 2 {
  4124  		t.Fatalf("expected 2 resources, got: %#v", mod.Resources)
  4125  	}
  4126  
  4127  	checkStateString(t, state, `
  4128  <no state>
  4129  module.child:
  4130    aws_instance.bar:
  4131      ID = foo
  4132      num = 2
  4133      type = aws_instance
  4134    aws_instance.foo:
  4135      ID = foo
  4136      num = 2
  4137      type = aws_instance
  4138  	`)
  4139  }
  4140  
  4141  // GH-1858
  4142  func TestContext2Apply_targetedModuleDep(t *testing.T) {
  4143  	m := testModule(t, "apply-targeted-module-dep")
  4144  	p := testProvider("aws")
  4145  	p.ApplyFn = testApplyFn
  4146  	p.DiffFn = testDiffFn
  4147  	ctx := testContext2(t, &ContextOpts{
  4148  		Module: m,
  4149  		Providers: map[string]ResourceProviderFactory{
  4150  			"aws": testProviderFuncFixed(p),
  4151  		},
  4152  		Targets: []string{"aws_instance.foo"},
  4153  	})
  4154  
  4155  	if _, err := ctx.Plan(); err != nil {
  4156  		t.Fatalf("err: %s", err)
  4157  	}
  4158  
  4159  	state, err := ctx.Apply()
  4160  	if err != nil {
  4161  		t.Fatalf("err: %s", err)
  4162  	}
  4163  
  4164  	checkStateString(t, state, `
  4165  aws_instance.foo:
  4166    ID = foo
  4167    foo = foo
  4168    type = aws_instance
  4169  
  4170    Dependencies:
  4171      module.child
  4172  
  4173  module.child:
  4174    aws_instance.mod:
  4175      ID = foo
  4176  
  4177    Outputs:
  4178  
  4179    output = foo
  4180  	`)
  4181  }
  4182  
  4183  func TestContext2Apply_targetedModuleResource(t *testing.T) {
  4184  	m := testModule(t, "apply-targeted-module-resource")
  4185  	p := testProvider("aws")
  4186  	p.ApplyFn = testApplyFn
  4187  	p.DiffFn = testDiffFn
  4188  	ctx := testContext2(t, &ContextOpts{
  4189  		Module: m,
  4190  		Providers: map[string]ResourceProviderFactory{
  4191  			"aws": testProviderFuncFixed(p),
  4192  		},
  4193  		Targets: []string{"module.child.aws_instance.foo"},
  4194  	})
  4195  
  4196  	if _, err := ctx.Plan(); err != nil {
  4197  		t.Fatalf("err: %s", err)
  4198  	}
  4199  
  4200  	state, err := ctx.Apply()
  4201  	if err != nil {
  4202  		t.Fatalf("err: %s", err)
  4203  	}
  4204  
  4205  	mod := state.ModuleByPath([]string{"root", "child"})
  4206  	if len(mod.Resources) != 1 {
  4207  		t.Fatalf("expected 1 resource, got: %#v", mod.Resources)
  4208  	}
  4209  
  4210  	checkStateString(t, state, `
  4211  <no state>
  4212  module.child:
  4213    aws_instance.foo:
  4214      ID = foo
  4215      num = 2
  4216      type = aws_instance
  4217  	`)
  4218  }
  4219  
  4220  func TestContext2Apply_unknownAttribute(t *testing.T) {
  4221  	m := testModule(t, "apply-unknown")
  4222  	p := testProvider("aws")
  4223  	p.ApplyFn = testApplyFn
  4224  	p.DiffFn = testDiffFn
  4225  	ctx := testContext2(t, &ContextOpts{
  4226  		Module: m,
  4227  		Providers: map[string]ResourceProviderFactory{
  4228  			"aws": testProviderFuncFixed(p),
  4229  		},
  4230  	})
  4231  
  4232  	if _, err := ctx.Plan(); err != nil {
  4233  		t.Fatalf("err: %s", err)
  4234  	}
  4235  
  4236  	state, err := ctx.Apply()
  4237  	if err == nil {
  4238  		t.Fatal("should error")
  4239  	}
  4240  
  4241  	actual := strings.TrimSpace(state.String())
  4242  	expected := strings.TrimSpace(testTerraformApplyUnknownAttrStr)
  4243  	if actual != expected {
  4244  		t.Fatalf("bad: \n%s", actual)
  4245  	}
  4246  }
  4247  
  4248  func TestContext2Apply_unknownAttributeInterpolate(t *testing.T) {
  4249  	m := testModule(t, "apply-unknown-interpolate")
  4250  	p := testProvider("aws")
  4251  	p.ApplyFn = testApplyFn
  4252  	p.DiffFn = testDiffFn
  4253  	ctx := testContext2(t, &ContextOpts{
  4254  		Module: m,
  4255  		Providers: map[string]ResourceProviderFactory{
  4256  			"aws": testProviderFuncFixed(p),
  4257  		},
  4258  	})
  4259  
  4260  	if _, err := ctx.Plan(); err == nil {
  4261  		t.Fatal("should error")
  4262  	}
  4263  }
  4264  
  4265  func TestContext2Apply_vars(t *testing.T) {
  4266  	m := testModule(t, "apply-vars")
  4267  	p := testProvider("aws")
  4268  	p.ApplyFn = testApplyFn
  4269  	p.DiffFn = testDiffFn
  4270  	ctx := testContext2(t, &ContextOpts{
  4271  		Module: m,
  4272  		Providers: map[string]ResourceProviderFactory{
  4273  			"aws": testProviderFuncFixed(p),
  4274  		},
  4275  		Variables: map[string]interface{}{
  4276  			"foo":       "us-west-2",
  4277  			"test_list": []interface{}{"Hello", "World"},
  4278  			"test_map": map[string]interface{}{
  4279  				"Hello": "World",
  4280  				"Foo":   "Bar",
  4281  				"Baz":   "Foo",
  4282  			},
  4283  			"amis": []map[string]interface{}{
  4284  				map[string]interface{}{
  4285  					"us-east-1": "override",
  4286  				},
  4287  			},
  4288  		},
  4289  	})
  4290  
  4291  	w, e := ctx.Validate()
  4292  	if len(w) > 0 {
  4293  		t.Fatalf("bad: %#v", w)
  4294  	}
  4295  	if len(e) > 0 {
  4296  		t.Fatalf("bad: %s", e)
  4297  	}
  4298  
  4299  	if _, err := ctx.Plan(); err != nil {
  4300  		t.Fatalf("err: %s", err)
  4301  	}
  4302  
  4303  	state, err := ctx.Apply()
  4304  	if err != nil {
  4305  		t.Fatalf("err: %s", err)
  4306  	}
  4307  
  4308  	actual := strings.TrimSpace(state.String())
  4309  	expected := strings.TrimSpace(testTerraformApplyVarsStr)
  4310  	if actual != expected {
  4311  		t.Fatalf("expected: %s\n got:\n%s", expected, actual)
  4312  	}
  4313  }
  4314  
  4315  func TestContext2Apply_varsEnv(t *testing.T) {
  4316  	// Set the env var
  4317  	old_ami := tempEnv(t, "TF_VAR_ami", "baz")
  4318  	old_list := tempEnv(t, "TF_VAR_list", `["Hello", "World"]`)
  4319  	old_map := tempEnv(t, "TF_VAR_map", `{"Hello" = "World", "Foo" = "Bar", "Baz" = "Foo"}`)
  4320  
  4321  	defer os.Setenv("TF_VAR_ami", old_ami)
  4322  	defer os.Setenv("TF_VAR_list", old_list)
  4323  	defer os.Setenv("TF_VAR_list", old_map)
  4324  
  4325  	m := testModule(t, "apply-vars-env")
  4326  	p := testProvider("aws")
  4327  	p.ApplyFn = testApplyFn
  4328  	p.DiffFn = testDiffFn
  4329  	ctx := testContext2(t, &ContextOpts{
  4330  		Module: m,
  4331  		Providers: map[string]ResourceProviderFactory{
  4332  			"aws": testProviderFuncFixed(p),
  4333  		},
  4334  	})
  4335  
  4336  	w, e := ctx.Validate()
  4337  	if len(w) > 0 {
  4338  		t.Fatalf("bad: %#v", w)
  4339  	}
  4340  	if len(e) > 0 {
  4341  		t.Fatalf("bad: %s", e)
  4342  	}
  4343  
  4344  	if _, err := ctx.Plan(); err != nil {
  4345  		t.Fatalf("err: %s", err)
  4346  	}
  4347  
  4348  	state, err := ctx.Apply()
  4349  	if err != nil {
  4350  		t.Fatalf("err: %s", err)
  4351  	}
  4352  
  4353  	actual := strings.TrimSpace(state.String())
  4354  	expected := strings.TrimSpace(testTerraformApplyVarsEnvStr)
  4355  	if actual != expected {
  4356  		t.Fatalf("bad: \n%s", actual)
  4357  	}
  4358  }
  4359  
  4360  func TestContext2Apply_createBefore_depends(t *testing.T) {
  4361  	m := testModule(t, "apply-depends-create-before")
  4362  	h := new(HookRecordApplyOrder)
  4363  	p := testProvider("aws")
  4364  	p.ApplyFn = testApplyFn
  4365  	p.DiffFn = testDiffFn
  4366  	state := &State{
  4367  		Modules: []*ModuleState{
  4368  			&ModuleState{
  4369  				Path: rootModulePath,
  4370  				Resources: map[string]*ResourceState{
  4371  					"aws_instance.web": &ResourceState{
  4372  						Type: "aws_instance",
  4373  						Primary: &InstanceState{
  4374  							ID: "bar",
  4375  							Attributes: map[string]string{
  4376  								"require_new": "ami-old",
  4377  							},
  4378  						},
  4379  					},
  4380  					"aws_instance.lb": &ResourceState{
  4381  						Type: "aws_instance",
  4382  						Primary: &InstanceState{
  4383  							ID: "baz",
  4384  							Attributes: map[string]string{
  4385  								"instance": "bar",
  4386  							},
  4387  						},
  4388  					},
  4389  				},
  4390  			},
  4391  		},
  4392  	}
  4393  	ctx := testContext2(t, &ContextOpts{
  4394  		Module: m,
  4395  		Hooks:  []Hook{h},
  4396  		Providers: map[string]ResourceProviderFactory{
  4397  			"aws": testProviderFuncFixed(p),
  4398  		},
  4399  		State: state,
  4400  	})
  4401  
  4402  	if _, err := ctx.Plan(); err != nil {
  4403  		t.Fatalf("err: %s", err)
  4404  	}
  4405  
  4406  	h.Active = true
  4407  	state, err := ctx.Apply()
  4408  	if err != nil {
  4409  		t.Fatalf("err: %s", err)
  4410  	}
  4411  
  4412  	mod := state.RootModule()
  4413  	if len(mod.Resources) < 2 {
  4414  		t.Fatalf("bad: %#v", mod.Resources)
  4415  	}
  4416  
  4417  	actual := strings.TrimSpace(state.String())
  4418  	expected := strings.TrimSpace(testTerraformApplyDependsCreateBeforeStr)
  4419  	if actual != expected {
  4420  		t.Fatalf("bad: \n%s\n%s", actual, expected)
  4421  	}
  4422  
  4423  	// Test that things were managed _in the right order_
  4424  	order := h.States
  4425  	diffs := h.Diffs
  4426  	if order[0].ID != "" || diffs[0].Destroy {
  4427  		t.Fatalf("should create new instance first: %#v", order)
  4428  	}
  4429  
  4430  	if order[1].ID != "baz" {
  4431  		t.Fatalf("update must happen after create: %#v", order)
  4432  	}
  4433  
  4434  	if order[2].ID != "bar" || !diffs[2].Destroy {
  4435  		t.Fatalf("destroy must happen after update: %#v", order)
  4436  	}
  4437  }
  4438  
  4439  func TestContext2Apply_singleDestroy(t *testing.T) {
  4440  	m := testModule(t, "apply-depends-create-before")
  4441  	h := new(HookRecordApplyOrder)
  4442  	p := testProvider("aws")
  4443  
  4444  	invokeCount := 0
  4445  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  4446  		invokeCount++
  4447  		switch invokeCount {
  4448  		case 1:
  4449  			if d.Destroy {
  4450  				t.Fatalf("should not destroy")
  4451  			}
  4452  			if s.ID != "" {
  4453  				t.Fatalf("should not have ID")
  4454  			}
  4455  		case 2:
  4456  			if d.Destroy {
  4457  				t.Fatalf("should not destroy")
  4458  			}
  4459  			if s.ID != "baz" {
  4460  				t.Fatalf("should have id")
  4461  			}
  4462  		case 3:
  4463  			if !d.Destroy {
  4464  				t.Fatalf("should destroy")
  4465  			}
  4466  			if s.ID == "" {
  4467  				t.Fatalf("should have ID")
  4468  			}
  4469  		default:
  4470  			t.Fatalf("bad invoke count %d", invokeCount)
  4471  		}
  4472  		return testApplyFn(info, s, d)
  4473  	}
  4474  	p.DiffFn = testDiffFn
  4475  	state := &State{
  4476  		Modules: []*ModuleState{
  4477  			&ModuleState{
  4478  				Path: rootModulePath,
  4479  				Resources: map[string]*ResourceState{
  4480  					"aws_instance.web": &ResourceState{
  4481  						Type: "aws_instance",
  4482  						Primary: &InstanceState{
  4483  							ID: "bar",
  4484  							Attributes: map[string]string{
  4485  								"require_new": "ami-old",
  4486  							},
  4487  						},
  4488  					},
  4489  					"aws_instance.lb": &ResourceState{
  4490  						Type: "aws_instance",
  4491  						Primary: &InstanceState{
  4492  							ID: "baz",
  4493  							Attributes: map[string]string{
  4494  								"instance": "bar",
  4495  							},
  4496  						},
  4497  					},
  4498  				},
  4499  			},
  4500  		},
  4501  	}
  4502  	ctx := testContext2(t, &ContextOpts{
  4503  		Module: m,
  4504  		Hooks:  []Hook{h},
  4505  		Providers: map[string]ResourceProviderFactory{
  4506  			"aws": testProviderFuncFixed(p),
  4507  		},
  4508  		State: state,
  4509  	})
  4510  
  4511  	if _, err := ctx.Plan(); err != nil {
  4512  		t.Fatalf("err: %s", err)
  4513  	}
  4514  
  4515  	h.Active = true
  4516  	state, err := ctx.Apply()
  4517  	if err != nil {
  4518  		t.Fatalf("err: %s", err)
  4519  	}
  4520  
  4521  	if invokeCount != 3 {
  4522  		t.Fatalf("bad: %d", invokeCount)
  4523  	}
  4524  }
  4525  
  4526  // GH-7824
  4527  func TestContext2Apply_issue7824(t *testing.T) {
  4528  	p := testProvider("template")
  4529  	p.ResourcesReturn = append(p.ResourcesReturn, ResourceType{
  4530  		Name: "template_file",
  4531  	})
  4532  
  4533  	p.ApplyFn = testApplyFn
  4534  	p.DiffFn = testDiffFn
  4535  
  4536  	// Apply cleanly step 0
  4537  	ctx := testContext2(t, &ContextOpts{
  4538  		Module: testModule(t, "issue-7824"),
  4539  		Providers: map[string]ResourceProviderFactory{
  4540  			"template": testProviderFuncFixed(p),
  4541  		},
  4542  	})
  4543  
  4544  	plan, err := ctx.Plan()
  4545  	if err != nil {
  4546  		t.Fatalf("err: %s", err)
  4547  	}
  4548  
  4549  	// Write / Read plan to simulate running it through a Plan file
  4550  	var buf bytes.Buffer
  4551  	if err := WritePlan(plan, &buf); err != nil {
  4552  		t.Fatalf("err: %s", err)
  4553  	}
  4554  
  4555  	planFromFile, err := ReadPlan(&buf)
  4556  	if err != nil {
  4557  		t.Fatalf("err: %s", err)
  4558  	}
  4559  
  4560  	ctx, err = planFromFile.Context(&ContextOpts{
  4561  		Providers: map[string]ResourceProviderFactory{
  4562  			"template": testProviderFuncFixed(p),
  4563  		},
  4564  	})
  4565  	if err != nil {
  4566  		t.Fatalf("err: %s", err)
  4567  	}
  4568  
  4569  	_, err = ctx.Apply()
  4570  	if err != nil {
  4571  		t.Fatalf("err: %s", err)
  4572  	}
  4573  }
  4574  
  4575  // GH-5254
  4576  func TestContext2Apply_issue5254(t *testing.T) {
  4577  	// Create a provider. We use "template" here just to match the repro
  4578  	// we got from the issue itself.
  4579  	p := testProvider("template")
  4580  	p.ResourcesReturn = append(p.ResourcesReturn, ResourceType{
  4581  		Name: "template_file",
  4582  	})
  4583  
  4584  	p.ApplyFn = testApplyFn
  4585  	p.DiffFn = testDiffFn
  4586  
  4587  	// Apply cleanly step 0
  4588  	ctx := testContext2(t, &ContextOpts{
  4589  		Module: testModule(t, "issue-5254/step-0"),
  4590  		Providers: map[string]ResourceProviderFactory{
  4591  			"template": testProviderFuncFixed(p),
  4592  		},
  4593  	})
  4594  
  4595  	plan, err := ctx.Plan()
  4596  	if err != nil {
  4597  		t.Fatalf("err: %s", err)
  4598  	}
  4599  
  4600  	state, err := ctx.Apply()
  4601  	if err != nil {
  4602  		t.Fatalf("err: %s", err)
  4603  	}
  4604  
  4605  	// Application success. Now make the modification and store a plan
  4606  	ctx = testContext2(t, &ContextOpts{
  4607  		Module: testModule(t, "issue-5254/step-1"),
  4608  		State:  state,
  4609  		Providers: map[string]ResourceProviderFactory{
  4610  			"template": testProviderFuncFixed(p),
  4611  		},
  4612  	})
  4613  
  4614  	plan, err = ctx.Plan()
  4615  	if err != nil {
  4616  		t.Fatalf("err: %s", err)
  4617  	}
  4618  
  4619  	// Write / Read plan to simulate running it through a Plan file
  4620  	var buf bytes.Buffer
  4621  	if err := WritePlan(plan, &buf); err != nil {
  4622  		t.Fatalf("err: %s", err)
  4623  	}
  4624  
  4625  	planFromFile, err := ReadPlan(&buf)
  4626  	if err != nil {
  4627  		t.Fatalf("err: %s", err)
  4628  	}
  4629  
  4630  	ctx, err = planFromFile.Context(&ContextOpts{
  4631  		Providers: map[string]ResourceProviderFactory{
  4632  			"template": testProviderFuncFixed(p),
  4633  		},
  4634  	})
  4635  	if err != nil {
  4636  		t.Fatalf("err: %s", err)
  4637  	}
  4638  
  4639  	state, err = ctx.Apply()
  4640  	if err != nil {
  4641  		t.Fatalf("err: %s", err)
  4642  	}
  4643  
  4644  	actual := strings.TrimSpace(state.String())
  4645  	expected := strings.TrimSpace(`
  4646  template_file.child:
  4647    ID = foo
  4648    template = Hi
  4649    type = template_file
  4650  
  4651    Dependencies:
  4652      template_file.parent
  4653  template_file.parent:
  4654    ID = foo
  4655    template = Hi
  4656    type = template_file
  4657  		`)
  4658  	if actual != expected {
  4659  		t.Fatalf("expected state: \n%s\ngot: \n%s", expected, actual)
  4660  	}
  4661  }
  4662  
  4663  func TestContext2Apply_targetedWithTaintedInState(t *testing.T) {
  4664  	p := testProvider("aws")
  4665  	p.DiffFn = testDiffFn
  4666  	p.ApplyFn = testApplyFn
  4667  	ctx := testContext2(t, &ContextOpts{
  4668  		Module: testModule(t, "apply-tainted-targets"),
  4669  		Providers: map[string]ResourceProviderFactory{
  4670  			"aws": testProviderFuncFixed(p),
  4671  		},
  4672  		Targets: []string{"aws_instance.iambeingadded"},
  4673  		State: &State{
  4674  			Modules: []*ModuleState{
  4675  				&ModuleState{
  4676  					Path: rootModulePath,
  4677  					Resources: map[string]*ResourceState{
  4678  						"aws_instance.ifailedprovisioners": &ResourceState{
  4679  							Primary: &InstanceState{
  4680  								ID:      "ifailedprovisioners",
  4681  								Tainted: true,
  4682  							},
  4683  						},
  4684  					},
  4685  				},
  4686  			},
  4687  		},
  4688  	})
  4689  
  4690  	plan, err := ctx.Plan()
  4691  	if err != nil {
  4692  		t.Fatalf("err: %s", err)
  4693  	}
  4694  
  4695  	// Write / Read plan to simulate running it through a Plan file
  4696  	var buf bytes.Buffer
  4697  	if err := WritePlan(plan, &buf); err != nil {
  4698  		t.Fatalf("err: %s", err)
  4699  	}
  4700  
  4701  	planFromFile, err := ReadPlan(&buf)
  4702  	if err != nil {
  4703  		t.Fatalf("err: %s", err)
  4704  	}
  4705  
  4706  	ctx, err = planFromFile.Context(&ContextOpts{
  4707  		Module: testModule(t, "apply-tainted-targets"),
  4708  		Providers: map[string]ResourceProviderFactory{
  4709  			"aws": testProviderFuncFixed(p),
  4710  		},
  4711  	})
  4712  	if err != nil {
  4713  		t.Fatalf("err: %s", err)
  4714  	}
  4715  
  4716  	state, err := ctx.Apply()
  4717  	if err != nil {
  4718  		t.Fatalf("err: %s", err)
  4719  	}
  4720  
  4721  	actual := strings.TrimSpace(state.String())
  4722  	expected := strings.TrimSpace(`
  4723  aws_instance.iambeingadded:
  4724    ID = foo
  4725  aws_instance.ifailedprovisioners: (tainted)
  4726    ID = ifailedprovisioners
  4727  		`)
  4728  	if actual != expected {
  4729  		t.Fatalf("expected state: \n%s\ngot: \n%s", expected, actual)
  4730  	}
  4731  }
  4732  
  4733  // Higher level test exposing the bug this covers in
  4734  // TestResource_ignoreChangesRequired
  4735  func TestContext2Apply_ignoreChangesCreate(t *testing.T) {
  4736  	m := testModule(t, "apply-ignore-changes-create")
  4737  	p := testProvider("aws")
  4738  	p.ApplyFn = testApplyFn
  4739  	p.DiffFn = testDiffFn
  4740  	ctx := testContext2(t, &ContextOpts{
  4741  		Module: m,
  4742  		Providers: map[string]ResourceProviderFactory{
  4743  			"aws": testProviderFuncFixed(p),
  4744  		},
  4745  	})
  4746  
  4747  	if p, err := ctx.Plan(); err != nil {
  4748  		t.Fatalf("err: %s", err)
  4749  	} else {
  4750  		t.Logf(p.String())
  4751  	}
  4752  
  4753  	state, err := ctx.Apply()
  4754  	if err != nil {
  4755  		t.Fatalf("err: %s", err)
  4756  	}
  4757  
  4758  	mod := state.RootModule()
  4759  	if len(mod.Resources) != 1 {
  4760  		t.Fatalf("bad: %s", state)
  4761  	}
  4762  
  4763  	actual := strings.TrimSpace(state.String())
  4764  	// Expect no changes from original state
  4765  	expected := strings.TrimSpace(`
  4766  aws_instance.foo:
  4767    ID = foo
  4768    required_field = set
  4769    type = aws_instance
  4770  `)
  4771  	if actual != expected {
  4772  		t.Fatalf("expected:\n%s\ngot:\n%s", expected, actual)
  4773  	}
  4774  }
  4775  
  4776  func TestContext2Apply_ignoreChangesWithDep(t *testing.T) {
  4777  	m := testModule(t, "apply-ignore-changes-dep")
  4778  	p := testProvider("aws")
  4779  	p.ApplyFn = testApplyFn
  4780  	p.DiffFn = func(i *InstanceInfo, s *InstanceState, c *ResourceConfig) (*InstanceDiff, error) {
  4781  		switch i.Type {
  4782  		case "aws_instance":
  4783  			newAmi, _ := c.Get("ami")
  4784  			return &InstanceDiff{
  4785  				Attributes: map[string]*ResourceAttrDiff{
  4786  					"ami": &ResourceAttrDiff{
  4787  						Old:         s.Attributes["ami"],
  4788  						New:         newAmi.(string),
  4789  						RequiresNew: true,
  4790  					},
  4791  				},
  4792  			}, nil
  4793  		case "aws_eip":
  4794  			return testDiffFn(i, s, c)
  4795  		default:
  4796  			t.Fatalf("Unexpected type: %s", i.Type)
  4797  			return nil, nil
  4798  		}
  4799  	}
  4800  	s := &State{
  4801  		Modules: []*ModuleState{
  4802  			&ModuleState{
  4803  				Path: rootModulePath,
  4804  				Resources: map[string]*ResourceState{
  4805  					"aws_instance.foo.0": &ResourceState{
  4806  						Primary: &InstanceState{
  4807  							ID: "i-abc123",
  4808  							Attributes: map[string]string{
  4809  								"ami": "ami-abcd1234",
  4810  								"id":  "i-abc123",
  4811  							},
  4812  						},
  4813  					},
  4814  					"aws_instance.foo.1": &ResourceState{
  4815  						Primary: &InstanceState{
  4816  							ID: "i-bcd234",
  4817  							Attributes: map[string]string{
  4818  								"ami": "ami-abcd1234",
  4819  								"id":  "i-bcd234",
  4820  							},
  4821  						},
  4822  					},
  4823  					"aws_eip.foo.0": &ResourceState{
  4824  						Primary: &InstanceState{
  4825  							ID: "eip-abc123",
  4826  							Attributes: map[string]string{
  4827  								"id":       "eip-abc123",
  4828  								"instance": "i-abc123",
  4829  							},
  4830  						},
  4831  					},
  4832  					"aws_eip.foo.1": &ResourceState{
  4833  						Primary: &InstanceState{
  4834  							ID: "eip-bcd234",
  4835  							Attributes: map[string]string{
  4836  								"id":       "eip-bcd234",
  4837  								"instance": "i-bcd234",
  4838  							},
  4839  						},
  4840  					},
  4841  				},
  4842  			},
  4843  		},
  4844  	}
  4845  	ctx := testContext2(t, &ContextOpts{
  4846  		Module: m,
  4847  		Providers: map[string]ResourceProviderFactory{
  4848  			"aws": testProviderFuncFixed(p),
  4849  		},
  4850  		State: s,
  4851  	})
  4852  
  4853  	if p, err := ctx.Plan(); err != nil {
  4854  		t.Fatalf("err: %s", err)
  4855  	} else {
  4856  		t.Logf(p.String())
  4857  	}
  4858  
  4859  	state, err := ctx.Apply()
  4860  	if err != nil {
  4861  		t.Fatalf("err: %s", err)
  4862  	}
  4863  
  4864  	actual := strings.TrimSpace(state.String())
  4865  	expected := strings.TrimSpace(s.String())
  4866  	if actual != expected {
  4867  		t.Fatalf("bad: \n%s", actual)
  4868  	}
  4869  }
  4870  
  4871  // https://github.com/hashicorp/terraform/issues/7378
  4872  func TestContext2Apply_destroyNestedModuleWithAttrsReferencingResource(t *testing.T) {
  4873  	m := testModule(t, "apply-destroy-nested-module-with-attrs")
  4874  	p := testProvider("null")
  4875  	p.ApplyFn = testApplyFn
  4876  	p.DiffFn = testDiffFn
  4877  
  4878  	var state *State
  4879  	var err error
  4880  	{
  4881  		ctx := testContext2(t, &ContextOpts{
  4882  			Module: m,
  4883  			Providers: map[string]ResourceProviderFactory{
  4884  				"null": testProviderFuncFixed(p),
  4885  			},
  4886  		})
  4887  
  4888  		// First plan and apply a create operation
  4889  		if _, err := ctx.Plan(); err != nil {
  4890  			t.Fatalf("plan err: %s", err)
  4891  		}
  4892  
  4893  		state, err = ctx.Apply()
  4894  		if err != nil {
  4895  			t.Fatalf("apply err: %s", err)
  4896  		}
  4897  	}
  4898  
  4899  	{
  4900  		ctx := testContext2(t, &ContextOpts{
  4901  			Destroy: true,
  4902  			Module:  m,
  4903  			State:   state,
  4904  			Providers: map[string]ResourceProviderFactory{
  4905  				"null": testProviderFuncFixed(p),
  4906  			},
  4907  		})
  4908  
  4909  		plan, err := ctx.Plan()
  4910  		if err != nil {
  4911  			t.Fatalf("destroy plan err: %s", err)
  4912  		}
  4913  
  4914  		var buf bytes.Buffer
  4915  		if err := WritePlan(plan, &buf); err != nil {
  4916  			t.Fatalf("plan write err: %s", err)
  4917  		}
  4918  
  4919  		planFromFile, err := ReadPlan(&buf)
  4920  		if err != nil {
  4921  			t.Fatalf("plan read err: %s", err)
  4922  		}
  4923  
  4924  		ctx, err = planFromFile.Context(&ContextOpts{
  4925  			Providers: map[string]ResourceProviderFactory{
  4926  				"null": testProviderFuncFixed(p),
  4927  			},
  4928  		})
  4929  		if err != nil {
  4930  			t.Fatalf("err: %s", err)
  4931  		}
  4932  
  4933  		state, err = ctx.Apply()
  4934  		if err != nil {
  4935  			t.Fatalf("destroy apply err: %s", err)
  4936  		}
  4937  	}
  4938  
  4939  	//Test that things were destroyed
  4940  	actual := strings.TrimSpace(state.String())
  4941  	expected := strings.TrimSpace(`
  4942  <no state>
  4943  module.middle:
  4944    <no state>
  4945  module.middle.bottom:
  4946    <no state>
  4947  		`)
  4948  	if actual != expected {
  4949  		t.Fatalf("expected: \n%s\n\nbad: \n%s", expected, actual)
  4950  	}
  4951  }