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