github.com/anfernee/terraform@v0.6.16-0.20160430000239-06e5085a92f2/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  func TestContext2Apply_moduleGrandchildProvider(t *testing.T) {
  1060  	m := testModule(t, "apply-module-grandchild-provider-inherit")
  1061  	p := testProvider("aws")
  1062  	p.ApplyFn = testApplyFn
  1063  	p.DiffFn = testDiffFn
  1064  
  1065  	var callLock sync.Mutex
  1066  	called := false
  1067  	p.ConfigureFn = func(c *ResourceConfig) error {
  1068  		if _, ok := c.Get("value"); !ok {
  1069  			return fmt.Errorf("value is not found")
  1070  		}
  1071  		callLock.Lock()
  1072  		called = true
  1073  		callLock.Unlock()
  1074  
  1075  		return nil
  1076  	}
  1077  
  1078  	ctx := testContext2(t, &ContextOpts{
  1079  		Module: m,
  1080  		Providers: map[string]ResourceProviderFactory{
  1081  			"aws": testProviderFuncFixed(p),
  1082  		},
  1083  	})
  1084  
  1085  	if _, err := ctx.Plan(); err != nil {
  1086  		t.Fatalf("err: %s", err)
  1087  	}
  1088  
  1089  	if _, err := ctx.Apply(); err != nil {
  1090  		t.Fatalf("err: %s", err)
  1091  	}
  1092  
  1093  	callLock.Lock()
  1094  	defer callLock.Unlock()
  1095  	if called != true {
  1096  		t.Fatalf("err: configure never called")
  1097  	}
  1098  }
  1099  
  1100  // This tests an issue where all the providers in a module but not
  1101  // in the root weren't being added to the root properly. In this test
  1102  // case: aws is explicitly added to root, but "test" should be added to.
  1103  // With the bug, it wasn't.
  1104  func TestContext2Apply_moduleOnlyProvider(t *testing.T) {
  1105  	m := testModule(t, "apply-module-only-provider")
  1106  	p := testProvider("aws")
  1107  	p.ApplyFn = testApplyFn
  1108  	p.DiffFn = testDiffFn
  1109  	pTest := testProvider("test")
  1110  	pTest.ApplyFn = testApplyFn
  1111  	pTest.DiffFn = testDiffFn
  1112  
  1113  	ctx := testContext2(t, &ContextOpts{
  1114  		Module: m,
  1115  		Providers: map[string]ResourceProviderFactory{
  1116  			"aws":  testProviderFuncFixed(p),
  1117  			"test": testProviderFuncFixed(pTest),
  1118  		},
  1119  	})
  1120  
  1121  	if _, err := ctx.Plan(); err != nil {
  1122  		t.Fatalf("err: %s", err)
  1123  	}
  1124  
  1125  	state, err := ctx.Apply()
  1126  	if err != nil {
  1127  		t.Fatalf("err: %s", err)
  1128  	}
  1129  
  1130  	actual := strings.TrimSpace(state.String())
  1131  	expected := strings.TrimSpace(testTerraformApplyModuleOnlyProviderStr)
  1132  	if actual != expected {
  1133  		t.Fatalf("bad: \n%s", actual)
  1134  	}
  1135  }
  1136  
  1137  func TestContext2Apply_moduleProviderAlias(t *testing.T) {
  1138  	m := testModule(t, "apply-module-provider-alias")
  1139  	p := testProvider("aws")
  1140  	p.ApplyFn = testApplyFn
  1141  	p.DiffFn = testDiffFn
  1142  	ctx := testContext2(t, &ContextOpts{
  1143  		Module: m,
  1144  		Providers: map[string]ResourceProviderFactory{
  1145  			"aws": testProviderFuncFixed(p),
  1146  		},
  1147  	})
  1148  
  1149  	if _, err := ctx.Plan(); err != nil {
  1150  		t.Fatalf("err: %s", err)
  1151  	}
  1152  
  1153  	state, err := ctx.Apply()
  1154  	if err != nil {
  1155  		t.Fatalf("err: %s", err)
  1156  	}
  1157  
  1158  	actual := strings.TrimSpace(state.String())
  1159  	expected := strings.TrimSpace(testTerraformApplyModuleProviderAliasStr)
  1160  	if actual != expected {
  1161  		t.Fatalf("bad: \n%s", actual)
  1162  	}
  1163  }
  1164  
  1165  func TestContext2Apply_moduleProviderAliasTargets(t *testing.T) {
  1166  	m := testModule(t, "apply-module-provider-alias")
  1167  	p := testProvider("aws")
  1168  	p.ApplyFn = testApplyFn
  1169  	p.DiffFn = testDiffFn
  1170  	ctx := testContext2(t, &ContextOpts{
  1171  		Module: m,
  1172  		Providers: map[string]ResourceProviderFactory{
  1173  			"aws": testProviderFuncFixed(p),
  1174  		},
  1175  		Targets: []string{"no.thing"},
  1176  	})
  1177  
  1178  	if _, err := ctx.Plan(); err != nil {
  1179  		t.Fatalf("err: %s", err)
  1180  	}
  1181  
  1182  	state, err := ctx.Apply()
  1183  	if err != nil {
  1184  		t.Fatalf("err: %s", err)
  1185  	}
  1186  
  1187  	actual := strings.TrimSpace(state.String())
  1188  	expected := strings.TrimSpace(`
  1189  <no state>
  1190  	`)
  1191  	if actual != expected {
  1192  		t.Fatalf("bad: \n%s", actual)
  1193  	}
  1194  }
  1195  
  1196  func TestContext2Apply_moduleProviderCloseNested(t *testing.T) {
  1197  	m := testModule(t, "apply-module-provider-close-nested")
  1198  	p := testProvider("aws")
  1199  	p.ApplyFn = testApplyFn
  1200  	p.DiffFn = testDiffFn
  1201  	ctx := testContext2(t, &ContextOpts{
  1202  		Module: m,
  1203  		Providers: map[string]ResourceProviderFactory{
  1204  			"aws": testProviderFuncFixed(p),
  1205  		},
  1206  		State: &State{
  1207  			Modules: []*ModuleState{
  1208  				&ModuleState{
  1209  					Path: []string{"root", "child", "subchild"},
  1210  					Resources: map[string]*ResourceState{
  1211  						"aws_instance.foo": &ResourceState{
  1212  							Type: "aws_instance",
  1213  							Primary: &InstanceState{
  1214  								ID: "bar",
  1215  							},
  1216  						},
  1217  					},
  1218  				},
  1219  			},
  1220  		},
  1221  		Destroy: true,
  1222  	})
  1223  
  1224  	if _, err := ctx.Plan(); err != nil {
  1225  		t.Fatalf("err: %s", err)
  1226  	}
  1227  
  1228  	if _, err := ctx.Apply(); err != nil {
  1229  		t.Fatalf("err: %s", err)
  1230  	}
  1231  }
  1232  
  1233  func TestContext2Apply_moduleVarResourceCount(t *testing.T) {
  1234  	m := testModule(t, "apply-module-var-resource-count")
  1235  	p := testProvider("aws")
  1236  	p.ApplyFn = testApplyFn
  1237  	p.DiffFn = testDiffFn
  1238  	ctx := testContext2(t, &ContextOpts{
  1239  		Module: m,
  1240  		Providers: map[string]ResourceProviderFactory{
  1241  			"aws": testProviderFuncFixed(p),
  1242  		},
  1243  		Variables: map[string]string{
  1244  			"count": "2",
  1245  		},
  1246  		Destroy: true,
  1247  	})
  1248  
  1249  	if _, err := ctx.Plan(); err != nil {
  1250  		t.Fatalf("err: %s", err)
  1251  	}
  1252  
  1253  	if _, err := ctx.Apply(); err != nil {
  1254  		t.Fatalf("err: %s", err)
  1255  	}
  1256  
  1257  	ctx = testContext2(t, &ContextOpts{
  1258  		Module: m,
  1259  		Providers: map[string]ResourceProviderFactory{
  1260  			"aws": testProviderFuncFixed(p),
  1261  		},
  1262  		Variables: map[string]string{
  1263  			"count": "5",
  1264  		},
  1265  	})
  1266  
  1267  	if _, err := ctx.Plan(); err != nil {
  1268  		t.Fatalf("err: %s", err)
  1269  	}
  1270  
  1271  	if _, err := ctx.Apply(); err != nil {
  1272  		t.Fatalf("err: %s", err)
  1273  	}
  1274  }
  1275  
  1276  // GH-819
  1277  func TestContext2Apply_moduleBool(t *testing.T) {
  1278  	m := testModule(t, "apply-module-bool")
  1279  	p := testProvider("aws")
  1280  	p.ApplyFn = testApplyFn
  1281  	p.DiffFn = testDiffFn
  1282  	ctx := testContext2(t, &ContextOpts{
  1283  		Module: m,
  1284  		Providers: map[string]ResourceProviderFactory{
  1285  			"aws": testProviderFuncFixed(p),
  1286  		},
  1287  	})
  1288  
  1289  	if _, err := ctx.Plan(); err != nil {
  1290  		t.Fatalf("err: %s", err)
  1291  	}
  1292  
  1293  	state, err := ctx.Apply()
  1294  	if err != nil {
  1295  		t.Fatalf("err: %s", err)
  1296  	}
  1297  
  1298  	actual := strings.TrimSpace(state.String())
  1299  	expected := strings.TrimSpace(testTerraformApplyModuleBoolStr)
  1300  	if actual != expected {
  1301  		t.Fatalf("bad: \n%s", actual)
  1302  	}
  1303  }
  1304  
  1305  func TestContext2Apply_multiProvider(t *testing.T) {
  1306  	m := testModule(t, "apply-multi-provider")
  1307  	p := testProvider("aws")
  1308  	p.ApplyFn = testApplyFn
  1309  	p.DiffFn = testDiffFn
  1310  
  1311  	pDO := testProvider("do")
  1312  	pDO.ApplyFn = testApplyFn
  1313  	pDO.DiffFn = testDiffFn
  1314  
  1315  	ctx := testContext2(t, &ContextOpts{
  1316  		Module: m,
  1317  		Providers: map[string]ResourceProviderFactory{
  1318  			"aws": testProviderFuncFixed(p),
  1319  			"do":  testProviderFuncFixed(pDO),
  1320  		},
  1321  	})
  1322  
  1323  	if _, err := ctx.Plan(); err != nil {
  1324  		t.Fatalf("err: %s", err)
  1325  	}
  1326  
  1327  	state, err := ctx.Apply()
  1328  	if err != nil {
  1329  		t.Fatalf("err: %s", err)
  1330  	}
  1331  
  1332  	mod := state.RootModule()
  1333  	if len(mod.Resources) < 2 {
  1334  		t.Fatalf("bad: %#v", mod.Resources)
  1335  	}
  1336  
  1337  	actual := strings.TrimSpace(state.String())
  1338  	expected := strings.TrimSpace(testTerraformApplyMultiProviderStr)
  1339  	if actual != expected {
  1340  		t.Fatalf("bad: \n%s", actual)
  1341  	}
  1342  }
  1343  
  1344  func TestContext2Apply_multiVar(t *testing.T) {
  1345  	m := testModule(t, "apply-multi-var")
  1346  	p := testProvider("aws")
  1347  	p.ApplyFn = testApplyFn
  1348  	p.DiffFn = testDiffFn
  1349  
  1350  	// First, apply with a count of 3
  1351  	ctx := testContext2(t, &ContextOpts{
  1352  		Module: m,
  1353  		Providers: map[string]ResourceProviderFactory{
  1354  			"aws": testProviderFuncFixed(p),
  1355  		},
  1356  		Variables: map[string]string{
  1357  			"count": "3",
  1358  		},
  1359  	})
  1360  
  1361  	if _, err := ctx.Plan(); err != nil {
  1362  		t.Fatalf("err: %s", err)
  1363  	}
  1364  
  1365  	state, err := ctx.Apply()
  1366  	if err != nil {
  1367  		t.Fatalf("err: %s", err)
  1368  	}
  1369  
  1370  	actual := state.RootModule().Outputs["output"]
  1371  	expected := "bar0,bar1,bar2"
  1372  	if actual != expected {
  1373  		t.Fatalf("bad: \n%s", actual)
  1374  	}
  1375  
  1376  	// Apply again, reduce the count to 1
  1377  	{
  1378  		ctx := testContext2(t, &ContextOpts{
  1379  			Module: m,
  1380  			State:  state,
  1381  			Providers: map[string]ResourceProviderFactory{
  1382  				"aws": testProviderFuncFixed(p),
  1383  			},
  1384  			Variables: map[string]string{
  1385  				"count": "1",
  1386  			},
  1387  		})
  1388  
  1389  		if _, err := ctx.Plan(); err != nil {
  1390  			t.Fatalf("err: %s", err)
  1391  		}
  1392  
  1393  		state, err := ctx.Apply()
  1394  		if err != nil {
  1395  			t.Fatalf("err: %s", err)
  1396  		}
  1397  
  1398  		actual := state.RootModule().Outputs["output"]
  1399  		expected := "bar0"
  1400  		if actual != expected {
  1401  			t.Fatalf("bad: \n%s", actual)
  1402  		}
  1403  	}
  1404  }
  1405  
  1406  func TestContext2Apply_nilDiff(t *testing.T) {
  1407  	m := testModule(t, "apply-good")
  1408  	p := testProvider("aws")
  1409  	p.ApplyFn = testApplyFn
  1410  	p.DiffFn = testDiffFn
  1411  	ctx := testContext2(t, &ContextOpts{
  1412  		Module: m,
  1413  		Providers: map[string]ResourceProviderFactory{
  1414  			"aws": testProviderFuncFixed(p),
  1415  		},
  1416  	})
  1417  
  1418  	if _, err := ctx.Plan(); err != nil {
  1419  		t.Fatalf("err: %s", err)
  1420  	}
  1421  
  1422  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  1423  		return nil, nil
  1424  	}
  1425  
  1426  	if _, err := ctx.Apply(); err == nil {
  1427  		t.Fatal("should error")
  1428  	}
  1429  }
  1430  
  1431  func TestContext2Apply_outputOrphan(t *testing.T) {
  1432  	m := testModule(t, "apply-output-orphan")
  1433  	p := testProvider("aws")
  1434  	p.ApplyFn = testApplyFn
  1435  	p.DiffFn = testDiffFn
  1436  
  1437  	state := &State{
  1438  		Modules: []*ModuleState{
  1439  			&ModuleState{
  1440  				Path: rootModulePath,
  1441  				Outputs: map[string]string{
  1442  					"foo": "bar",
  1443  					"bar": "baz",
  1444  				},
  1445  			},
  1446  		},
  1447  	}
  1448  
  1449  	ctx := testContext2(t, &ContextOpts{
  1450  		Module: m,
  1451  		Providers: map[string]ResourceProviderFactory{
  1452  			"aws": testProviderFuncFixed(p),
  1453  		},
  1454  		State: state,
  1455  	})
  1456  
  1457  	if _, err := ctx.Plan(); err != nil {
  1458  		t.Fatalf("err: %s", err)
  1459  	}
  1460  
  1461  	state, err := ctx.Apply()
  1462  	if err != nil {
  1463  		t.Fatalf("err: %s", err)
  1464  	}
  1465  
  1466  	actual := strings.TrimSpace(state.String())
  1467  	expected := strings.TrimSpace(testTerraformApplyOutputOrphanStr)
  1468  	if actual != expected {
  1469  		t.Fatalf("bad: \n%s", actual)
  1470  	}
  1471  }
  1472  
  1473  func TestContext2Apply_providerComputedVar(t *testing.T) {
  1474  	m := testModule(t, "apply-provider-computed")
  1475  	p := testProvider("aws")
  1476  	p.ApplyFn = testApplyFn
  1477  	p.DiffFn = testDiffFn
  1478  
  1479  	pTest := testProvider("test")
  1480  	pTest.ApplyFn = testApplyFn
  1481  	pTest.DiffFn = testDiffFn
  1482  
  1483  	ctx := testContext2(t, &ContextOpts{
  1484  		Module: m,
  1485  		Providers: map[string]ResourceProviderFactory{
  1486  			"aws":  testProviderFuncFixed(p),
  1487  			"test": testProviderFuncFixed(pTest),
  1488  		},
  1489  	})
  1490  
  1491  	p.ConfigureFn = func(c *ResourceConfig) error {
  1492  		if c.IsComputed("value") {
  1493  			return fmt.Errorf("value is computed")
  1494  		}
  1495  
  1496  		v, ok := c.Get("value")
  1497  		if !ok {
  1498  			return fmt.Errorf("value is not found")
  1499  		}
  1500  		if v != "yes" {
  1501  			return fmt.Errorf("value is not 'yes': %v", v)
  1502  		}
  1503  
  1504  		return nil
  1505  	}
  1506  
  1507  	if _, err := ctx.Plan(); err != nil {
  1508  		t.Fatalf("err: %s", err)
  1509  	}
  1510  
  1511  	if _, err := ctx.Apply(); err != nil {
  1512  		t.Fatalf("err: %s", err)
  1513  	}
  1514  }
  1515  
  1516  func TestContext2Apply_Provisioner_compute(t *testing.T) {
  1517  	m := testModule(t, "apply-provisioner-compute")
  1518  	p := testProvider("aws")
  1519  	pr := testProvisioner()
  1520  	p.ApplyFn = testApplyFn
  1521  	p.DiffFn = testDiffFn
  1522  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  1523  		val, ok := c.Config["foo"]
  1524  		if !ok || val != "computed_dynamical" {
  1525  			t.Fatalf("bad value for foo: %v %#v", val, c)
  1526  		}
  1527  
  1528  		return nil
  1529  	}
  1530  	ctx := testContext2(t, &ContextOpts{
  1531  		Module: m,
  1532  		Providers: map[string]ResourceProviderFactory{
  1533  			"aws": testProviderFuncFixed(p),
  1534  		},
  1535  		Provisioners: map[string]ResourceProvisionerFactory{
  1536  			"shell": testProvisionerFuncFixed(pr),
  1537  		},
  1538  		Variables: map[string]string{
  1539  			"value": "1",
  1540  		},
  1541  	})
  1542  
  1543  	if _, err := ctx.Plan(); err != nil {
  1544  		t.Fatalf("err: %s", err)
  1545  	}
  1546  
  1547  	state, err := ctx.Apply()
  1548  	if err != nil {
  1549  		t.Fatalf("err: %s", err)
  1550  	}
  1551  
  1552  	actual := strings.TrimSpace(state.String())
  1553  	expected := strings.TrimSpace(testTerraformApplyProvisionerStr)
  1554  	if actual != expected {
  1555  		t.Fatalf("bad: \n%s", actual)
  1556  	}
  1557  
  1558  	// Verify apply was invoked
  1559  	if !pr.ApplyCalled {
  1560  		t.Fatalf("provisioner not invoked")
  1561  	}
  1562  }
  1563  
  1564  func TestContext2Apply_provisionerCreateFail(t *testing.T) {
  1565  	m := testModule(t, "apply-provisioner-fail-create")
  1566  	p := testProvider("aws")
  1567  	pr := testProvisioner()
  1568  	p.DiffFn = testDiffFn
  1569  
  1570  	p.ApplyFn = func(
  1571  		info *InstanceInfo,
  1572  		is *InstanceState,
  1573  		id *InstanceDiff) (*InstanceState, error) {
  1574  		is.ID = "foo"
  1575  		return is, fmt.Errorf("error")
  1576  	}
  1577  
  1578  	ctx := testContext2(t, &ContextOpts{
  1579  		Module: m,
  1580  		Providers: map[string]ResourceProviderFactory{
  1581  			"aws": testProviderFuncFixed(p),
  1582  		},
  1583  		Provisioners: map[string]ResourceProvisionerFactory{
  1584  			"shell": testProvisionerFuncFixed(pr),
  1585  		},
  1586  	})
  1587  
  1588  	if _, err := ctx.Plan(); err != nil {
  1589  		t.Fatalf("err: %s", err)
  1590  	}
  1591  
  1592  	state, err := ctx.Apply()
  1593  	if err == nil {
  1594  		t.Fatal("should error")
  1595  	}
  1596  
  1597  	actual := strings.TrimSpace(state.String())
  1598  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailCreateStr)
  1599  	if actual != expected {
  1600  		t.Fatalf("bad: \n%s", actual)
  1601  	}
  1602  }
  1603  
  1604  func TestContext2Apply_provisionerCreateFailNoId(t *testing.T) {
  1605  	m := testModule(t, "apply-provisioner-fail-create")
  1606  	p := testProvider("aws")
  1607  	pr := testProvisioner()
  1608  	p.DiffFn = testDiffFn
  1609  
  1610  	p.ApplyFn = func(
  1611  		info *InstanceInfo,
  1612  		is *InstanceState,
  1613  		id *InstanceDiff) (*InstanceState, error) {
  1614  		return nil, fmt.Errorf("error")
  1615  	}
  1616  
  1617  	ctx := testContext2(t, &ContextOpts{
  1618  		Module: m,
  1619  		Providers: map[string]ResourceProviderFactory{
  1620  			"aws": testProviderFuncFixed(p),
  1621  		},
  1622  		Provisioners: map[string]ResourceProvisionerFactory{
  1623  			"shell": testProvisionerFuncFixed(pr),
  1624  		},
  1625  	})
  1626  
  1627  	if _, err := ctx.Plan(); err != nil {
  1628  		t.Fatalf("err: %s", err)
  1629  	}
  1630  
  1631  	state, err := ctx.Apply()
  1632  	if err == nil {
  1633  		t.Fatal("should error")
  1634  	}
  1635  
  1636  	actual := strings.TrimSpace(state.String())
  1637  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailCreateNoIdStr)
  1638  	if actual != expected {
  1639  		t.Fatalf("bad: \n%s", actual)
  1640  	}
  1641  }
  1642  
  1643  func TestContext2Apply_provisionerFail(t *testing.T) {
  1644  	m := testModule(t, "apply-provisioner-fail")
  1645  	p := testProvider("aws")
  1646  	pr := testProvisioner()
  1647  	p.ApplyFn = testApplyFn
  1648  	p.DiffFn = testDiffFn
  1649  
  1650  	pr.ApplyFn = func(*InstanceState, *ResourceConfig) error {
  1651  		return fmt.Errorf("EXPLOSION")
  1652  	}
  1653  
  1654  	ctx := testContext2(t, &ContextOpts{
  1655  		Module: m,
  1656  		Providers: map[string]ResourceProviderFactory{
  1657  			"aws": testProviderFuncFixed(p),
  1658  		},
  1659  		Provisioners: map[string]ResourceProvisionerFactory{
  1660  			"shell": testProvisionerFuncFixed(pr),
  1661  		},
  1662  		Variables: map[string]string{
  1663  			"value": "1",
  1664  		},
  1665  	})
  1666  
  1667  	if _, err := ctx.Plan(); err != nil {
  1668  		t.Fatalf("err: %s", err)
  1669  	}
  1670  
  1671  	state, err := ctx.Apply()
  1672  	if err == nil {
  1673  		t.Fatal("should error")
  1674  	}
  1675  
  1676  	actual := strings.TrimSpace(state.String())
  1677  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailStr)
  1678  	if actual != expected {
  1679  		t.Fatalf("bad: \n%s", actual)
  1680  	}
  1681  }
  1682  
  1683  func TestContext2Apply_provisionerFail_createBeforeDestroy(t *testing.T) {
  1684  	m := testModule(t, "apply-provisioner-fail-create-before")
  1685  	p := testProvider("aws")
  1686  	pr := testProvisioner()
  1687  	p.ApplyFn = testApplyFn
  1688  	p.DiffFn = testDiffFn
  1689  	pr.ApplyFn = func(*InstanceState, *ResourceConfig) error {
  1690  		return fmt.Errorf("EXPLOSION")
  1691  	}
  1692  
  1693  	state := &State{
  1694  		Modules: []*ModuleState{
  1695  			&ModuleState{
  1696  				Path: rootModulePath,
  1697  				Resources: map[string]*ResourceState{
  1698  					"aws_instance.bar": &ResourceState{
  1699  						Type: "aws_instance",
  1700  						Primary: &InstanceState{
  1701  							ID: "bar",
  1702  							Attributes: map[string]string{
  1703  								"require_new": "abc",
  1704  							},
  1705  						},
  1706  					},
  1707  				},
  1708  			},
  1709  		},
  1710  	}
  1711  	ctx := testContext2(t, &ContextOpts{
  1712  		Module: m,
  1713  		Providers: map[string]ResourceProviderFactory{
  1714  			"aws": testProviderFuncFixed(p),
  1715  		},
  1716  		Provisioners: map[string]ResourceProvisionerFactory{
  1717  			"shell": testProvisionerFuncFixed(pr),
  1718  		},
  1719  		State: state,
  1720  	})
  1721  
  1722  	if _, err := ctx.Plan(); err != nil {
  1723  		t.Fatalf("err: %s", err)
  1724  	}
  1725  
  1726  	state, err := ctx.Apply()
  1727  	if err == nil {
  1728  		t.Fatal("should error")
  1729  	}
  1730  
  1731  	actual := strings.TrimSpace(state.String())
  1732  	expected := strings.TrimSpace(testTerraformApplyProvisionerFailCreateBeforeDestroyStr)
  1733  	if actual != expected {
  1734  		t.Fatalf("bad: \n%s", actual)
  1735  	}
  1736  }
  1737  
  1738  func TestContext2Apply_error_createBeforeDestroy(t *testing.T) {
  1739  	m := testModule(t, "apply-error-create-before")
  1740  	p := testProvider("aws")
  1741  	state := &State{
  1742  		Modules: []*ModuleState{
  1743  			&ModuleState{
  1744  				Path: rootModulePath,
  1745  				Resources: map[string]*ResourceState{
  1746  					"aws_instance.bar": &ResourceState{
  1747  						Type: "aws_instance",
  1748  						Primary: &InstanceState{
  1749  							ID: "bar",
  1750  							Attributes: map[string]string{
  1751  								"require_new": "abc",
  1752  							},
  1753  						},
  1754  					},
  1755  				},
  1756  			},
  1757  		},
  1758  	}
  1759  	ctx := testContext2(t, &ContextOpts{
  1760  		Module: m,
  1761  		Providers: map[string]ResourceProviderFactory{
  1762  			"aws": testProviderFuncFixed(p),
  1763  		},
  1764  		State: state,
  1765  	})
  1766  	p.ApplyFn = func(info *InstanceInfo, is *InstanceState, id *InstanceDiff) (*InstanceState, error) {
  1767  		return nil, fmt.Errorf("error")
  1768  	}
  1769  	p.DiffFn = testDiffFn
  1770  
  1771  	if _, err := ctx.Plan(); err != nil {
  1772  		t.Fatalf("err: %s", err)
  1773  	}
  1774  
  1775  	state, err := ctx.Apply()
  1776  	if err == nil {
  1777  		t.Fatal("should have error")
  1778  	}
  1779  
  1780  	actual := strings.TrimSpace(state.String())
  1781  	expected := strings.TrimSpace(testTerraformApplyErrorCreateBeforeDestroyStr)
  1782  	if actual != expected {
  1783  		t.Fatalf("bad: \n%s\n\nExpected:\n\n%s", actual, expected)
  1784  	}
  1785  }
  1786  
  1787  func TestContext2Apply_errorDestroy_createBeforeDestroy(t *testing.T) {
  1788  	m := testModule(t, "apply-error-create-before")
  1789  	p := testProvider("aws")
  1790  	state := &State{
  1791  		Modules: []*ModuleState{
  1792  			&ModuleState{
  1793  				Path: rootModulePath,
  1794  				Resources: map[string]*ResourceState{
  1795  					"aws_instance.bar": &ResourceState{
  1796  						Type: "aws_instance",
  1797  						Primary: &InstanceState{
  1798  							ID: "bar",
  1799  							Attributes: map[string]string{
  1800  								"require_new": "abc",
  1801  							},
  1802  						},
  1803  					},
  1804  				},
  1805  			},
  1806  		},
  1807  	}
  1808  	ctx := testContext2(t, &ContextOpts{
  1809  		Module: m,
  1810  		Providers: map[string]ResourceProviderFactory{
  1811  			"aws": testProviderFuncFixed(p),
  1812  		},
  1813  		State: state,
  1814  	})
  1815  	p.ApplyFn = func(info *InstanceInfo, is *InstanceState, id *InstanceDiff) (*InstanceState, error) {
  1816  		// Fail the destroy!
  1817  		if id.Destroy {
  1818  			return is, fmt.Errorf("error")
  1819  		}
  1820  
  1821  		// Create should work
  1822  		is = &InstanceState{
  1823  			ID: "foo",
  1824  		}
  1825  		return is, nil
  1826  	}
  1827  	p.DiffFn = testDiffFn
  1828  
  1829  	if _, err := ctx.Plan(); err != nil {
  1830  		t.Fatalf("err: %s", err)
  1831  	}
  1832  
  1833  	state, err := ctx.Apply()
  1834  	if err == nil {
  1835  		t.Fatal("should have error")
  1836  	}
  1837  
  1838  	actual := strings.TrimSpace(state.String())
  1839  	expected := strings.TrimSpace(testTerraformApplyErrorDestroyCreateBeforeDestroyStr)
  1840  	if actual != expected {
  1841  		t.Fatalf("bad: actual:\n%s\n\nexpected:\n%s", actual, expected)
  1842  	}
  1843  }
  1844  
  1845  func TestContext2Apply_multiDepose_createBeforeDestroy(t *testing.T) {
  1846  	m := testModule(t, "apply-multi-depose-create-before-destroy")
  1847  	p := testProvider("aws")
  1848  	p.DiffFn = testDiffFn
  1849  	ps := map[string]ResourceProviderFactory{"aws": testProviderFuncFixed(p)}
  1850  	state := &State{
  1851  		Modules: []*ModuleState{
  1852  			&ModuleState{
  1853  				Path: rootModulePath,
  1854  				Resources: map[string]*ResourceState{
  1855  					"aws_instance.web": &ResourceState{
  1856  						Type:    "aws_instance",
  1857  						Primary: &InstanceState{ID: "foo"},
  1858  					},
  1859  				},
  1860  			},
  1861  		},
  1862  	}
  1863  
  1864  	ctx := testContext2(t, &ContextOpts{
  1865  		Module:    m,
  1866  		Providers: ps,
  1867  		State:     state,
  1868  	})
  1869  	createdInstanceId := "bar"
  1870  	// Create works
  1871  	createFunc := func(is *InstanceState) (*InstanceState, error) {
  1872  		return &InstanceState{ID: createdInstanceId}, nil
  1873  	}
  1874  	// Destroy starts broken
  1875  	destroyFunc := func(is *InstanceState) (*InstanceState, error) {
  1876  		return is, fmt.Errorf("destroy failed")
  1877  	}
  1878  	p.ApplyFn = func(info *InstanceInfo, is *InstanceState, id *InstanceDiff) (*InstanceState, error) {
  1879  		if id.Destroy {
  1880  			return destroyFunc(is)
  1881  		} else {
  1882  			return createFunc(is)
  1883  		}
  1884  	}
  1885  
  1886  	if _, err := ctx.Plan(); err != nil {
  1887  		t.Fatalf("err: %s", err)
  1888  	}
  1889  
  1890  	// Destroy is broken, so even though CBD successfully replaces the instance,
  1891  	// we'll have to save the Deposed instance to destroy later
  1892  	state, err := ctx.Apply()
  1893  	if err == nil {
  1894  		t.Fatal("should have error")
  1895  	}
  1896  
  1897  	checkStateString(t, state, `
  1898  aws_instance.web: (1 deposed)
  1899    ID = bar
  1900    Deposed ID 1 = foo
  1901  	`)
  1902  
  1903  	createdInstanceId = "baz"
  1904  	ctx = testContext2(t, &ContextOpts{
  1905  		Module:    m,
  1906  		Providers: ps,
  1907  		State:     state,
  1908  	})
  1909  
  1910  	if _, err := ctx.Plan(); err != nil {
  1911  		t.Fatalf("err: %s", err)
  1912  	}
  1913  
  1914  	// We're replacing the primary instance once again. Destroy is _still_
  1915  	// broken, so the Deposed list gets longer
  1916  	state, err = ctx.Apply()
  1917  	if err == nil {
  1918  		t.Fatal("should have error")
  1919  	}
  1920  
  1921  	checkStateString(t, state, `
  1922  aws_instance.web: (2 deposed)
  1923    ID = baz
  1924    Deposed ID 1 = foo
  1925    Deposed ID 2 = bar
  1926  	`)
  1927  
  1928  	// Destroy partially fixed!
  1929  	destroyFunc = func(is *InstanceState) (*InstanceState, error) {
  1930  		if is.ID == "foo" || is.ID == "baz" {
  1931  			return nil, nil
  1932  		} else {
  1933  			return is, fmt.Errorf("destroy partially failed")
  1934  		}
  1935  	}
  1936  
  1937  	createdInstanceId = "qux"
  1938  	if _, err := ctx.Plan(); err != nil {
  1939  		t.Fatalf("err: %s", err)
  1940  	}
  1941  	state, err = ctx.Apply()
  1942  	// Expect error because 1/2 of Deposed destroys failed
  1943  	if err == nil {
  1944  		t.Fatal("should have error")
  1945  	}
  1946  
  1947  	// foo and baz are now gone, bar sticks around
  1948  	checkStateString(t, state, `
  1949  aws_instance.web: (1 deposed)
  1950    ID = qux
  1951    Deposed ID 1 = bar
  1952  	`)
  1953  
  1954  	// Destroy working fully!
  1955  	destroyFunc = func(is *InstanceState) (*InstanceState, error) {
  1956  		return nil, nil
  1957  	}
  1958  
  1959  	createdInstanceId = "quux"
  1960  	if _, err := ctx.Plan(); err != nil {
  1961  		t.Fatalf("err: %s", err)
  1962  	}
  1963  	state, err = ctx.Apply()
  1964  	if err != nil {
  1965  		t.Fatal("should not have error:", err)
  1966  	}
  1967  
  1968  	// And finally the state is clean
  1969  	checkStateString(t, state, `
  1970  aws_instance.web:
  1971    ID = quux
  1972  	`)
  1973  }
  1974  
  1975  func TestContext2Apply_provisionerResourceRef(t *testing.T) {
  1976  	m := testModule(t, "apply-provisioner-resource-ref")
  1977  	p := testProvider("aws")
  1978  	pr := testProvisioner()
  1979  	p.ApplyFn = testApplyFn
  1980  	p.DiffFn = testDiffFn
  1981  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  1982  		val, ok := c.Config["foo"]
  1983  		if !ok || val != "2" {
  1984  			t.Fatalf("bad value for foo: %v %#v", val, c)
  1985  		}
  1986  
  1987  		return nil
  1988  	}
  1989  
  1990  	ctx := testContext2(t, &ContextOpts{
  1991  		Module: m,
  1992  		Providers: map[string]ResourceProviderFactory{
  1993  			"aws": testProviderFuncFixed(p),
  1994  		},
  1995  		Provisioners: map[string]ResourceProvisionerFactory{
  1996  			"shell": testProvisionerFuncFixed(pr),
  1997  		},
  1998  	})
  1999  
  2000  	if _, err := ctx.Plan(); err != nil {
  2001  		t.Fatalf("err: %s", err)
  2002  	}
  2003  
  2004  	state, err := ctx.Apply()
  2005  	if err != nil {
  2006  		t.Fatalf("err: %s", err)
  2007  	}
  2008  
  2009  	actual := strings.TrimSpace(state.String())
  2010  	expected := strings.TrimSpace(testTerraformApplyProvisionerResourceRefStr)
  2011  	if actual != expected {
  2012  		t.Fatalf("bad: \n%s", actual)
  2013  	}
  2014  
  2015  	// Verify apply was invoked
  2016  	if !pr.ApplyCalled {
  2017  		t.Fatalf("provisioner not invoked")
  2018  	}
  2019  }
  2020  
  2021  func TestContext2Apply_provisionerSelfRef(t *testing.T) {
  2022  	m := testModule(t, "apply-provisioner-self-ref")
  2023  	p := testProvider("aws")
  2024  	pr := testProvisioner()
  2025  	p.ApplyFn = testApplyFn
  2026  	p.DiffFn = testDiffFn
  2027  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  2028  		val, ok := c.Config["command"]
  2029  		if !ok || val != "bar" {
  2030  			t.Fatalf("bad value for command: %v %#v", val, c)
  2031  		}
  2032  
  2033  		return nil
  2034  	}
  2035  
  2036  	ctx := testContext2(t, &ContextOpts{
  2037  		Module: m,
  2038  		Providers: map[string]ResourceProviderFactory{
  2039  			"aws": testProviderFuncFixed(p),
  2040  		},
  2041  		Provisioners: map[string]ResourceProvisionerFactory{
  2042  			"shell": testProvisionerFuncFixed(pr),
  2043  		},
  2044  	})
  2045  
  2046  	if _, err := ctx.Plan(); err != nil {
  2047  		t.Fatalf("err: %s", err)
  2048  	}
  2049  
  2050  	state, err := ctx.Apply()
  2051  	if err != nil {
  2052  		t.Fatalf("err: %s", err)
  2053  	}
  2054  
  2055  	actual := strings.TrimSpace(state.String())
  2056  	expected := strings.TrimSpace(testTerraformApplyProvisionerSelfRefStr)
  2057  	if actual != expected {
  2058  		t.Fatalf("bad: \n%s", actual)
  2059  	}
  2060  
  2061  	// Verify apply was invoked
  2062  	if !pr.ApplyCalled {
  2063  		t.Fatalf("provisioner not invoked")
  2064  	}
  2065  }
  2066  
  2067  func TestContext2Apply_provisionerMultiSelfRef(t *testing.T) {
  2068  	var lock sync.Mutex
  2069  	commands := make([]string, 0, 5)
  2070  
  2071  	m := testModule(t, "apply-provisioner-multi-self-ref")
  2072  	p := testProvider("aws")
  2073  	pr := testProvisioner()
  2074  	p.ApplyFn = testApplyFn
  2075  	p.DiffFn = testDiffFn
  2076  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  2077  		lock.Lock()
  2078  		defer lock.Unlock()
  2079  
  2080  		val, ok := c.Config["command"]
  2081  		if !ok {
  2082  			t.Fatalf("bad value for command: %v %#v", val, c)
  2083  		}
  2084  
  2085  		commands = append(commands, val.(string))
  2086  		return nil
  2087  	}
  2088  
  2089  	ctx := testContext2(t, &ContextOpts{
  2090  		Module: m,
  2091  		Providers: map[string]ResourceProviderFactory{
  2092  			"aws": testProviderFuncFixed(p),
  2093  		},
  2094  		Provisioners: map[string]ResourceProvisionerFactory{
  2095  			"shell": testProvisionerFuncFixed(pr),
  2096  		},
  2097  	})
  2098  
  2099  	if _, err := ctx.Plan(); err != nil {
  2100  		t.Fatalf("err: %s", err)
  2101  	}
  2102  
  2103  	state, err := ctx.Apply()
  2104  	if err != nil {
  2105  		t.Fatalf("err: %s", err)
  2106  	}
  2107  
  2108  	actual := strings.TrimSpace(state.String())
  2109  	expected := strings.TrimSpace(testTerraformApplyProvisionerMultiSelfRefStr)
  2110  	if actual != expected {
  2111  		t.Fatalf("bad: \n%s", actual)
  2112  	}
  2113  
  2114  	// Verify apply was invoked
  2115  	if !pr.ApplyCalled {
  2116  		t.Fatalf("provisioner not invoked")
  2117  	}
  2118  
  2119  	// Verify our result
  2120  	sort.Strings(commands)
  2121  	expectedCommands := []string{"number 0", "number 1", "number 2"}
  2122  	if !reflect.DeepEqual(commands, expectedCommands) {
  2123  		t.Fatalf("bad: %#v", commands)
  2124  	}
  2125  }
  2126  
  2127  // Provisioner should NOT run on a diff, only create
  2128  func TestContext2Apply_Provisioner_Diff(t *testing.T) {
  2129  	m := testModule(t, "apply-provisioner-diff")
  2130  	p := testProvider("aws")
  2131  	pr := testProvisioner()
  2132  	p.ApplyFn = testApplyFn
  2133  	p.DiffFn = testDiffFn
  2134  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  2135  		return nil
  2136  	}
  2137  	ctx := testContext2(t, &ContextOpts{
  2138  		Module: m,
  2139  		Providers: map[string]ResourceProviderFactory{
  2140  			"aws": testProviderFuncFixed(p),
  2141  		},
  2142  		Provisioners: map[string]ResourceProvisionerFactory{
  2143  			"shell": testProvisionerFuncFixed(pr),
  2144  		},
  2145  	})
  2146  
  2147  	if _, err := ctx.Plan(); err != nil {
  2148  		t.Fatalf("err: %s", err)
  2149  	}
  2150  
  2151  	state, err := ctx.Apply()
  2152  	if err != nil {
  2153  		t.Fatalf("err: %s", err)
  2154  	}
  2155  
  2156  	actual := strings.TrimSpace(state.String())
  2157  	expected := strings.TrimSpace(testTerraformApplyProvisionerDiffStr)
  2158  	if actual != expected {
  2159  		t.Fatalf("bad: \n%s", actual)
  2160  	}
  2161  
  2162  	// Verify apply was invoked
  2163  	if !pr.ApplyCalled {
  2164  		t.Fatalf("provisioner not invoked")
  2165  	}
  2166  	pr.ApplyCalled = false
  2167  
  2168  	// Change the state to force a diff
  2169  	mod := state.RootModule()
  2170  	mod.Resources["aws_instance.bar"].Primary.Attributes["foo"] = "baz"
  2171  
  2172  	// Re-create context with state
  2173  	ctx = testContext2(t, &ContextOpts{
  2174  		Module: m,
  2175  		Providers: map[string]ResourceProviderFactory{
  2176  			"aws": testProviderFuncFixed(p),
  2177  		},
  2178  		Provisioners: map[string]ResourceProvisionerFactory{
  2179  			"shell": testProvisionerFuncFixed(pr),
  2180  		},
  2181  		State: state,
  2182  	})
  2183  
  2184  	if _, err := ctx.Plan(); err != nil {
  2185  		t.Fatalf("err: %s", err)
  2186  	}
  2187  
  2188  	state2, err := ctx.Apply()
  2189  	if err != nil {
  2190  		t.Fatalf("err: %s", err)
  2191  	}
  2192  
  2193  	actual = strings.TrimSpace(state2.String())
  2194  	if actual != expected {
  2195  		t.Fatalf("bad: \n%s", actual)
  2196  	}
  2197  
  2198  	// Verify apply was NOT invoked
  2199  	if pr.ApplyCalled {
  2200  		t.Fatalf("provisioner invoked")
  2201  	}
  2202  }
  2203  
  2204  func TestContext2Apply_outputDiffVars(t *testing.T) {
  2205  	m := testModule(t, "apply-good")
  2206  	p := testProvider("aws")
  2207  	s := &State{
  2208  		Modules: []*ModuleState{
  2209  			&ModuleState{
  2210  				Path: rootModulePath,
  2211  				Resources: map[string]*ResourceState{
  2212  					"aws_instance.baz": &ResourceState{
  2213  						Type: "aws_instance",
  2214  						Primary: &InstanceState{
  2215  							ID: "bar",
  2216  						},
  2217  					},
  2218  				},
  2219  			},
  2220  		},
  2221  	}
  2222  	ctx := testContext2(t, &ContextOpts{
  2223  		Module: m,
  2224  		Providers: map[string]ResourceProviderFactory{
  2225  			"aws": testProviderFuncFixed(p),
  2226  		},
  2227  		State: s,
  2228  	})
  2229  
  2230  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  2231  		for k, ad := range d.Attributes {
  2232  			if ad.NewComputed {
  2233  				return nil, fmt.Errorf("%s: computed", k)
  2234  			}
  2235  		}
  2236  
  2237  		result := s.MergeDiff(d)
  2238  		result.ID = "foo"
  2239  		return result, nil
  2240  	}
  2241  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  2242  		return &InstanceDiff{
  2243  			Attributes: map[string]*ResourceAttrDiff{
  2244  				"foo": &ResourceAttrDiff{
  2245  					NewComputed: true,
  2246  					Type:        DiffAttrOutput,
  2247  				},
  2248  				"bar": &ResourceAttrDiff{
  2249  					New: "baz",
  2250  				},
  2251  			},
  2252  		}, nil
  2253  	}
  2254  
  2255  	if _, err := ctx.Plan(); err != nil {
  2256  		t.Fatalf("err: %s", err)
  2257  	}
  2258  	if _, err := ctx.Apply(); err != nil {
  2259  		t.Fatalf("err: %s", err)
  2260  	}
  2261  }
  2262  
  2263  func TestContext2Apply_Provisioner_ConnInfo(t *testing.T) {
  2264  	m := testModule(t, "apply-provisioner-conninfo")
  2265  	p := testProvider("aws")
  2266  	pr := testProvisioner()
  2267  
  2268  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  2269  		if s.Ephemeral.ConnInfo == nil {
  2270  			t.Fatalf("ConnInfo not initialized")
  2271  		}
  2272  
  2273  		result, _ := testApplyFn(info, s, d)
  2274  		result.Ephemeral.ConnInfo = map[string]string{
  2275  			"type": "ssh",
  2276  			"host": "127.0.0.1",
  2277  			"port": "22",
  2278  		}
  2279  		return result, nil
  2280  	}
  2281  	p.DiffFn = testDiffFn
  2282  
  2283  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  2284  		conn := rs.Ephemeral.ConnInfo
  2285  		if conn["type"] != "telnet" {
  2286  			t.Fatalf("Bad: %#v", conn)
  2287  		}
  2288  		if conn["host"] != "127.0.0.1" {
  2289  			t.Fatalf("Bad: %#v", conn)
  2290  		}
  2291  		if conn["port"] != "2222" {
  2292  			t.Fatalf("Bad: %#v", conn)
  2293  		}
  2294  		if conn["user"] != "superuser" {
  2295  			t.Fatalf("Bad: %#v", conn)
  2296  		}
  2297  		if conn["pass"] != "test" {
  2298  			t.Fatalf("Bad: %#v", conn)
  2299  		}
  2300  
  2301  		return nil
  2302  	}
  2303  
  2304  	ctx := testContext2(t, &ContextOpts{
  2305  		Module: m,
  2306  		Providers: map[string]ResourceProviderFactory{
  2307  			"aws": testProviderFuncFixed(p),
  2308  		},
  2309  		Provisioners: map[string]ResourceProvisionerFactory{
  2310  			"shell": testProvisionerFuncFixed(pr),
  2311  		},
  2312  		Variables: map[string]string{
  2313  			"value": "1",
  2314  			"pass":  "test",
  2315  		},
  2316  	})
  2317  
  2318  	if _, err := ctx.Plan(); err != nil {
  2319  		t.Fatalf("err: %s", err)
  2320  	}
  2321  
  2322  	state, err := ctx.Apply()
  2323  	if err != nil {
  2324  		t.Fatalf("err: %s", err)
  2325  	}
  2326  
  2327  	actual := strings.TrimSpace(state.String())
  2328  	expected := strings.TrimSpace(testTerraformApplyProvisionerStr)
  2329  	if actual != expected {
  2330  		t.Fatalf("bad: \n%s", actual)
  2331  	}
  2332  
  2333  	// Verify apply was invoked
  2334  	if !pr.ApplyCalled {
  2335  		t.Fatalf("provisioner not invoked")
  2336  	}
  2337  }
  2338  
  2339  func TestContext2Apply_destroy(t *testing.T) {
  2340  	m := testModule(t, "apply-destroy")
  2341  	h := new(HookRecordApplyOrder)
  2342  	p := testProvider("aws")
  2343  	p.ApplyFn = testApplyFn
  2344  	p.DiffFn = testDiffFn
  2345  	ctx := testContext2(t, &ContextOpts{
  2346  		Module: m,
  2347  		Hooks:  []Hook{h},
  2348  		Providers: map[string]ResourceProviderFactory{
  2349  			"aws": testProviderFuncFixed(p),
  2350  		},
  2351  	})
  2352  
  2353  	// First plan and apply a create operation
  2354  	if _, err := ctx.Plan(); err != nil {
  2355  		t.Fatalf("err: %s", err)
  2356  	}
  2357  
  2358  	state, err := ctx.Apply()
  2359  	if err != nil {
  2360  		t.Fatalf("err: %s", err)
  2361  	}
  2362  
  2363  	// Next, plan and apply a destroy operation
  2364  	h.Active = true
  2365  	ctx = testContext2(t, &ContextOpts{
  2366  		Destroy: true,
  2367  		State:   state,
  2368  		Module:  m,
  2369  		Hooks:   []Hook{h},
  2370  		Providers: map[string]ResourceProviderFactory{
  2371  			"aws": testProviderFuncFixed(p),
  2372  		},
  2373  	})
  2374  
  2375  	if _, err := ctx.Plan(); err != nil {
  2376  		t.Fatalf("err: %s", err)
  2377  	}
  2378  
  2379  	state, err = ctx.Apply()
  2380  	if err != nil {
  2381  		t.Fatalf("err: %s", err)
  2382  	}
  2383  
  2384  	// Test that things were destroyed
  2385  	actual := strings.TrimSpace(state.String())
  2386  	expected := strings.TrimSpace(testTerraformApplyDestroyStr)
  2387  	if actual != expected {
  2388  		t.Fatalf("bad: \n%s", actual)
  2389  	}
  2390  
  2391  	// Test that things were destroyed _in the right order_
  2392  	expected2 := []string{"aws_instance.bar", "aws_instance.foo"}
  2393  	actual2 := h.IDs
  2394  	if !reflect.DeepEqual(actual2, expected2) {
  2395  		t.Fatalf("expected: %#v\n\ngot:%#v", expected2, actual2)
  2396  	}
  2397  }
  2398  
  2399  func TestContext2Apply_destroyNestedModule(t *testing.T) {
  2400  	m := testModule(t, "apply-destroy-nested-module")
  2401  	p := testProvider("aws")
  2402  	p.ApplyFn = testApplyFn
  2403  	p.DiffFn = testDiffFn
  2404  
  2405  	s := &State{
  2406  		Modules: []*ModuleState{
  2407  			&ModuleState{
  2408  				Path: []string{"root", "child", "subchild"},
  2409  				Resources: map[string]*ResourceState{
  2410  					"aws_instance.bar": &ResourceState{
  2411  						Type: "aws_instance",
  2412  						Primary: &InstanceState{
  2413  							ID: "bar",
  2414  						},
  2415  					},
  2416  				},
  2417  			},
  2418  		},
  2419  	}
  2420  
  2421  	ctx := testContext2(t, &ContextOpts{
  2422  		Module: m,
  2423  		Providers: map[string]ResourceProviderFactory{
  2424  			"aws": testProviderFuncFixed(p),
  2425  		},
  2426  		State: s,
  2427  	})
  2428  
  2429  	// First plan and apply a create operation
  2430  	if _, err := ctx.Plan(); err != nil {
  2431  		t.Fatalf("err: %s", err)
  2432  	}
  2433  
  2434  	state, err := ctx.Apply()
  2435  	if err != nil {
  2436  		t.Fatalf("err: %s", err)
  2437  	}
  2438  
  2439  	// Test that things were destroyed
  2440  	actual := strings.TrimSpace(state.String())
  2441  	expected := strings.TrimSpace(testTerraformApplyDestroyNestedModuleStr)
  2442  	if actual != expected {
  2443  		t.Fatalf("bad: \n%s", actual)
  2444  	}
  2445  }
  2446  
  2447  func TestContext2Apply_destroyDeeplyNestedModule(t *testing.T) {
  2448  	m := testModule(t, "apply-destroy-deeply-nested-module")
  2449  	p := testProvider("aws")
  2450  	p.ApplyFn = testApplyFn
  2451  	p.DiffFn = testDiffFn
  2452  
  2453  	s := &State{
  2454  		Modules: []*ModuleState{
  2455  			&ModuleState{
  2456  				Path: []string{"root", "child", "subchild", "subsubchild"},
  2457  				Resources: map[string]*ResourceState{
  2458  					"aws_instance.bar": &ResourceState{
  2459  						Type: "aws_instance",
  2460  						Primary: &InstanceState{
  2461  							ID: "bar",
  2462  						},
  2463  					},
  2464  				},
  2465  			},
  2466  		},
  2467  	}
  2468  
  2469  	ctx := testContext2(t, &ContextOpts{
  2470  		Module: m,
  2471  		Providers: map[string]ResourceProviderFactory{
  2472  			"aws": testProviderFuncFixed(p),
  2473  		},
  2474  		State: s,
  2475  	})
  2476  
  2477  	// First plan and apply a create operation
  2478  	if _, err := ctx.Plan(); err != nil {
  2479  		t.Fatalf("err: %s", err)
  2480  	}
  2481  
  2482  	state, err := ctx.Apply()
  2483  	if err != nil {
  2484  		t.Fatalf("err: %s", err)
  2485  	}
  2486  
  2487  	// Test that things were destroyed
  2488  	actual := strings.TrimSpace(state.String())
  2489  	expected := strings.TrimSpace(`
  2490  module.child.subchild.subsubchild:
  2491    <no state>
  2492  	`)
  2493  	if actual != expected {
  2494  		t.Fatalf("bad: \n%s", actual)
  2495  	}
  2496  }
  2497  
  2498  func TestContext2Apply_destroyOutputs(t *testing.T) {
  2499  	m := testModule(t, "apply-destroy-outputs")
  2500  	h := new(HookRecordApplyOrder)
  2501  	p := testProvider("aws")
  2502  	p.ApplyFn = testApplyFn
  2503  	p.DiffFn = testDiffFn
  2504  	ctx := testContext2(t, &ContextOpts{
  2505  		Module: m,
  2506  		Hooks:  []Hook{h},
  2507  		Providers: map[string]ResourceProviderFactory{
  2508  			"aws": testProviderFuncFixed(p),
  2509  		},
  2510  	})
  2511  
  2512  	// First plan and apply a create operation
  2513  	if _, err := ctx.Plan(); err != nil {
  2514  		t.Fatalf("err: %s", err)
  2515  	}
  2516  
  2517  	state, err := ctx.Apply()
  2518  
  2519  	if err != nil {
  2520  		t.Fatalf("err: %s", err)
  2521  	}
  2522  
  2523  	// Next, plan and apply a destroy operation
  2524  	h.Active = true
  2525  	ctx = testContext2(t, &ContextOpts{
  2526  		Destroy: true,
  2527  		State:   state,
  2528  		Module:  m,
  2529  		Hooks:   []Hook{h},
  2530  		Providers: map[string]ResourceProviderFactory{
  2531  			"aws": testProviderFuncFixed(p),
  2532  		},
  2533  	})
  2534  
  2535  	if _, err := ctx.Plan(); err != nil {
  2536  		t.Fatalf("err: %s", err)
  2537  	}
  2538  
  2539  	state, err = ctx.Apply()
  2540  	if err != nil {
  2541  		t.Fatalf("err: %s", err)
  2542  	}
  2543  
  2544  	mod := state.RootModule()
  2545  	if len(mod.Resources) > 0 {
  2546  		t.Fatalf("bad: %#v", mod)
  2547  	}
  2548  }
  2549  
  2550  func TestContext2Apply_destroyOrphan(t *testing.T) {
  2551  	m := testModule(t, "apply-error")
  2552  	p := testProvider("aws")
  2553  	s := &State{
  2554  		Modules: []*ModuleState{
  2555  			&ModuleState{
  2556  				Path: rootModulePath,
  2557  				Resources: map[string]*ResourceState{
  2558  					"aws_instance.baz": &ResourceState{
  2559  						Type: "aws_instance",
  2560  						Primary: &InstanceState{
  2561  							ID: "bar",
  2562  						},
  2563  					},
  2564  				},
  2565  			},
  2566  		},
  2567  	}
  2568  	ctx := testContext2(t, &ContextOpts{
  2569  		Module: m,
  2570  		Providers: map[string]ResourceProviderFactory{
  2571  			"aws": testProviderFuncFixed(p),
  2572  		},
  2573  		State: s,
  2574  	})
  2575  
  2576  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  2577  		if d.Destroy {
  2578  			return nil, nil
  2579  		}
  2580  
  2581  		result := s.MergeDiff(d)
  2582  		result.ID = "foo"
  2583  		return result, nil
  2584  	}
  2585  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  2586  		return &InstanceDiff{
  2587  			Attributes: map[string]*ResourceAttrDiff{
  2588  				"num": &ResourceAttrDiff{
  2589  					New: "bar",
  2590  				},
  2591  			},
  2592  		}, nil
  2593  	}
  2594  
  2595  	if _, err := ctx.Plan(); err != nil {
  2596  		t.Fatalf("err: %s", err)
  2597  	}
  2598  
  2599  	state, err := ctx.Apply()
  2600  	if err != nil {
  2601  		t.Fatalf("err: %s", err)
  2602  	}
  2603  
  2604  	mod := state.RootModule()
  2605  	if _, ok := mod.Resources["aws_instance.baz"]; ok {
  2606  		t.Fatalf("bad: %#v", mod.Resources)
  2607  	}
  2608  }
  2609  
  2610  func TestContext2Apply_destroyTaintedProvisioner(t *testing.T) {
  2611  	m := testModule(t, "apply-destroy-provisioner")
  2612  	p := testProvider("aws")
  2613  	pr := testProvisioner()
  2614  	p.ApplyFn = testApplyFn
  2615  	p.DiffFn = testDiffFn
  2616  
  2617  	called := false
  2618  	pr.ApplyFn = func(rs *InstanceState, c *ResourceConfig) error {
  2619  		called = true
  2620  		return nil
  2621  	}
  2622  
  2623  	s := &State{
  2624  		Modules: []*ModuleState{
  2625  			&ModuleState{
  2626  				Path: rootModulePath,
  2627  				Resources: map[string]*ResourceState{
  2628  					"aws_instance.foo": &ResourceState{
  2629  						Type: "aws_instance",
  2630  						Tainted: []*InstanceState{
  2631  							&InstanceState{
  2632  								ID: "bar",
  2633  								Attributes: map[string]string{
  2634  									"id": "bar",
  2635  								},
  2636  							},
  2637  						},
  2638  					},
  2639  				},
  2640  			},
  2641  		},
  2642  	}
  2643  
  2644  	ctx := testContext2(t, &ContextOpts{
  2645  		Module: m,
  2646  		Providers: map[string]ResourceProviderFactory{
  2647  			"aws": testProviderFuncFixed(p),
  2648  		},
  2649  		Provisioners: map[string]ResourceProvisionerFactory{
  2650  			"shell": testProvisionerFuncFixed(pr),
  2651  		},
  2652  		State:   s,
  2653  		Destroy: true,
  2654  	})
  2655  
  2656  	if _, err := ctx.Plan(); err != nil {
  2657  		t.Fatalf("err: %s", err)
  2658  	}
  2659  
  2660  	state, err := ctx.Apply()
  2661  	if err != nil {
  2662  		t.Fatalf("err: %s", err)
  2663  	}
  2664  
  2665  	if called {
  2666  		t.Fatal("provisioner should not be called")
  2667  	}
  2668  
  2669  	actual := strings.TrimSpace(state.String())
  2670  	expected := strings.TrimSpace("<no state>")
  2671  	if actual != expected {
  2672  		t.Fatalf("bad: \n%s", actual)
  2673  	}
  2674  }
  2675  
  2676  func TestContext2Apply_error(t *testing.T) {
  2677  	errored := false
  2678  
  2679  	m := testModule(t, "apply-error")
  2680  	p := testProvider("aws")
  2681  	ctx := testContext2(t, &ContextOpts{
  2682  		Module: m,
  2683  		Providers: map[string]ResourceProviderFactory{
  2684  			"aws": testProviderFuncFixed(p),
  2685  		},
  2686  	})
  2687  
  2688  	p.ApplyFn = func(*InstanceInfo, *InstanceState, *InstanceDiff) (*InstanceState, error) {
  2689  		if errored {
  2690  			state := &InstanceState{
  2691  				ID: "bar",
  2692  			}
  2693  			return state, fmt.Errorf("error")
  2694  		}
  2695  		errored = true
  2696  
  2697  		return &InstanceState{
  2698  			ID: "foo",
  2699  			Attributes: map[string]string{
  2700  				"num": "2",
  2701  			},
  2702  		}, nil
  2703  	}
  2704  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  2705  		return &InstanceDiff{
  2706  			Attributes: map[string]*ResourceAttrDiff{
  2707  				"num": &ResourceAttrDiff{
  2708  					New: "bar",
  2709  				},
  2710  			},
  2711  		}, nil
  2712  	}
  2713  
  2714  	if _, err := ctx.Plan(); err != nil {
  2715  		t.Fatalf("err: %s", err)
  2716  	}
  2717  
  2718  	state, err := ctx.Apply()
  2719  	if err == nil {
  2720  		t.Fatal("should have error")
  2721  	}
  2722  
  2723  	actual := strings.TrimSpace(state.String())
  2724  	expected := strings.TrimSpace(testTerraformApplyErrorStr)
  2725  	if actual != expected {
  2726  		t.Fatalf("bad: \n%s", actual)
  2727  	}
  2728  }
  2729  
  2730  func TestContext2Apply_errorPartial(t *testing.T) {
  2731  	errored := false
  2732  
  2733  	m := testModule(t, "apply-error")
  2734  	p := testProvider("aws")
  2735  	s := &State{
  2736  		Modules: []*ModuleState{
  2737  			&ModuleState{
  2738  				Path: rootModulePath,
  2739  				Resources: map[string]*ResourceState{
  2740  					"aws_instance.bar": &ResourceState{
  2741  						Type: "aws_instance",
  2742  						Primary: &InstanceState{
  2743  							ID: "bar",
  2744  						},
  2745  					},
  2746  				},
  2747  			},
  2748  		},
  2749  	}
  2750  	ctx := testContext2(t, &ContextOpts{
  2751  		Module: m,
  2752  		Providers: map[string]ResourceProviderFactory{
  2753  			"aws": testProviderFuncFixed(p),
  2754  		},
  2755  		State: s,
  2756  	})
  2757  
  2758  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  2759  		if errored {
  2760  			return s, fmt.Errorf("error")
  2761  		}
  2762  		errored = true
  2763  
  2764  		return &InstanceState{
  2765  			ID: "foo",
  2766  			Attributes: map[string]string{
  2767  				"num": "2",
  2768  			},
  2769  		}, nil
  2770  	}
  2771  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  2772  		return &InstanceDiff{
  2773  			Attributes: map[string]*ResourceAttrDiff{
  2774  				"num": &ResourceAttrDiff{
  2775  					New: "bar",
  2776  				},
  2777  			},
  2778  		}, nil
  2779  	}
  2780  
  2781  	if _, err := ctx.Plan(); err != nil {
  2782  		t.Fatalf("err: %s", err)
  2783  	}
  2784  
  2785  	state, err := ctx.Apply()
  2786  	if err == nil {
  2787  		t.Fatal("should have error")
  2788  	}
  2789  
  2790  	mod := state.RootModule()
  2791  	if len(mod.Resources) != 2 {
  2792  		t.Fatalf("bad: %#v", mod.Resources)
  2793  	}
  2794  
  2795  	actual := strings.TrimSpace(state.String())
  2796  	expected := strings.TrimSpace(testTerraformApplyErrorPartialStr)
  2797  	if actual != expected {
  2798  		t.Fatalf("bad: \n%s", actual)
  2799  	}
  2800  }
  2801  
  2802  func TestContext2Apply_hook(t *testing.T) {
  2803  	m := testModule(t, "apply-good")
  2804  	h := new(MockHook)
  2805  	p := testProvider("aws")
  2806  	p.ApplyFn = testApplyFn
  2807  	p.DiffFn = testDiffFn
  2808  	ctx := testContext2(t, &ContextOpts{
  2809  		Module: m,
  2810  		Hooks:  []Hook{h},
  2811  		Providers: map[string]ResourceProviderFactory{
  2812  			"aws": testProviderFuncFixed(p),
  2813  		},
  2814  	})
  2815  
  2816  	if _, err := ctx.Plan(); err != nil {
  2817  		t.Fatalf("err: %s", err)
  2818  	}
  2819  
  2820  	if _, err := ctx.Apply(); err != nil {
  2821  		t.Fatalf("err: %s", err)
  2822  	}
  2823  
  2824  	if !h.PreApplyCalled {
  2825  		t.Fatal("should be called")
  2826  	}
  2827  	if !h.PostApplyCalled {
  2828  		t.Fatal("should be called")
  2829  	}
  2830  	if !h.PostStateUpdateCalled {
  2831  		t.Fatalf("should call post state update")
  2832  	}
  2833  }
  2834  
  2835  func TestContext2Apply_hookOrphan(t *testing.T) {
  2836  	m := testModule(t, "apply-blank")
  2837  	h := new(MockHook)
  2838  	p := testProvider("aws")
  2839  	p.ApplyFn = testApplyFn
  2840  	p.DiffFn = testDiffFn
  2841  
  2842  	state := &State{
  2843  		Modules: []*ModuleState{
  2844  			&ModuleState{
  2845  				Path: rootModulePath,
  2846  				Resources: map[string]*ResourceState{
  2847  					"aws_instance.bar": &ResourceState{
  2848  						Type: "aws_instance",
  2849  						Primary: &InstanceState{
  2850  							ID: "bar",
  2851  						},
  2852  					},
  2853  				},
  2854  			},
  2855  		},
  2856  	}
  2857  
  2858  	ctx := testContext2(t, &ContextOpts{
  2859  		Module: m,
  2860  		State:  state,
  2861  		Hooks:  []Hook{h},
  2862  		Providers: map[string]ResourceProviderFactory{
  2863  			"aws": testProviderFuncFixed(p),
  2864  		},
  2865  	})
  2866  
  2867  	if _, err := ctx.Plan(); err != nil {
  2868  		t.Fatalf("err: %s", err)
  2869  	}
  2870  
  2871  	if _, err := ctx.Apply(); err != nil {
  2872  		t.Fatalf("err: %s", err)
  2873  	}
  2874  
  2875  	if !h.PreApplyCalled {
  2876  		t.Fatal("should be called")
  2877  	}
  2878  	if !h.PostApplyCalled {
  2879  		t.Fatal("should be called")
  2880  	}
  2881  	if !h.PostStateUpdateCalled {
  2882  		t.Fatalf("should call post state update")
  2883  	}
  2884  }
  2885  
  2886  func TestContext2Apply_idAttr(t *testing.T) {
  2887  	m := testModule(t, "apply-idattr")
  2888  	p := testProvider("aws")
  2889  	ctx := testContext2(t, &ContextOpts{
  2890  		Module: m,
  2891  		Providers: map[string]ResourceProviderFactory{
  2892  			"aws": testProviderFuncFixed(p),
  2893  		},
  2894  	})
  2895  
  2896  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  2897  		result := s.MergeDiff(d)
  2898  		result.ID = "foo"
  2899  		result.Attributes = map[string]string{
  2900  			"id": "bar",
  2901  		}
  2902  
  2903  		return result, nil
  2904  	}
  2905  	p.DiffFn = func(*InstanceInfo, *InstanceState, *ResourceConfig) (*InstanceDiff, error) {
  2906  		return &InstanceDiff{
  2907  			Attributes: map[string]*ResourceAttrDiff{
  2908  				"num": &ResourceAttrDiff{
  2909  					New: "bar",
  2910  				},
  2911  			},
  2912  		}, nil
  2913  	}
  2914  
  2915  	if _, err := ctx.Plan(); err != nil {
  2916  		t.Fatalf("err: %s", err)
  2917  	}
  2918  
  2919  	state, err := ctx.Apply()
  2920  	if err != nil {
  2921  		t.Fatalf("err: %s", err)
  2922  	}
  2923  
  2924  	mod := state.RootModule()
  2925  	rs, ok := mod.Resources["aws_instance.foo"]
  2926  	if !ok {
  2927  		t.Fatal("not in state")
  2928  	}
  2929  	if rs.Primary.ID != "foo" {
  2930  		t.Fatalf("bad: %#v", rs.Primary.ID)
  2931  	}
  2932  	if rs.Primary.Attributes["id"] != "foo" {
  2933  		t.Fatalf("bad: %#v", rs.Primary.Attributes)
  2934  	}
  2935  }
  2936  
  2937  func TestContext2Apply_output(t *testing.T) {
  2938  	m := testModule(t, "apply-output")
  2939  	p := testProvider("aws")
  2940  	p.ApplyFn = testApplyFn
  2941  	p.DiffFn = testDiffFn
  2942  	ctx := testContext2(t, &ContextOpts{
  2943  		Module: m,
  2944  		Providers: map[string]ResourceProviderFactory{
  2945  			"aws": testProviderFuncFixed(p),
  2946  		},
  2947  	})
  2948  
  2949  	if _, err := ctx.Plan(); err != nil {
  2950  		t.Fatalf("err: %s", err)
  2951  	}
  2952  
  2953  	state, err := ctx.Apply()
  2954  	if err != nil {
  2955  		t.Fatalf("err: %s", err)
  2956  	}
  2957  
  2958  	actual := strings.TrimSpace(state.String())
  2959  	expected := strings.TrimSpace(testTerraformApplyOutputStr)
  2960  	if actual != expected {
  2961  		t.Fatalf("bad: \n%s", actual)
  2962  	}
  2963  }
  2964  
  2965  func TestContext2Apply_outputInvalid(t *testing.T) {
  2966  	m := testModule(t, "apply-output-invalid")
  2967  	p := testProvider("aws")
  2968  	p.ApplyFn = testApplyFn
  2969  	p.DiffFn = testDiffFn
  2970  	ctx := testContext2(t, &ContextOpts{
  2971  		Module: m,
  2972  		Providers: map[string]ResourceProviderFactory{
  2973  			"aws": testProviderFuncFixed(p),
  2974  		},
  2975  	})
  2976  
  2977  	_, err := ctx.Plan()
  2978  	if err == nil {
  2979  		t.Fatalf("err: %s", err)
  2980  	}
  2981  	if !strings.Contains(err.Error(), "is not a string") {
  2982  		t.Fatalf("err: %s", err)
  2983  	}
  2984  }
  2985  
  2986  func TestContext2Apply_outputAdd(t *testing.T) {
  2987  	m1 := testModule(t, "apply-output-add-before")
  2988  	p1 := testProvider("aws")
  2989  	p1.ApplyFn = testApplyFn
  2990  	p1.DiffFn = testDiffFn
  2991  	ctx1 := testContext2(t, &ContextOpts{
  2992  		Module: m1,
  2993  		Providers: map[string]ResourceProviderFactory{
  2994  			"aws": testProviderFuncFixed(p1),
  2995  		},
  2996  	})
  2997  
  2998  	if _, err := ctx1.Plan(); err != nil {
  2999  		t.Fatalf("err: %s", err)
  3000  	}
  3001  
  3002  	state1, err := ctx1.Apply()
  3003  	if err != nil {
  3004  		t.Fatalf("err: %s", err)
  3005  	}
  3006  
  3007  	m2 := testModule(t, "apply-output-add-after")
  3008  	p2 := testProvider("aws")
  3009  	p2.ApplyFn = testApplyFn
  3010  	p2.DiffFn = testDiffFn
  3011  	ctx2 := testContext2(t, &ContextOpts{
  3012  		Module: m2,
  3013  		Providers: map[string]ResourceProviderFactory{
  3014  			"aws": testProviderFuncFixed(p2),
  3015  		},
  3016  		State: state1,
  3017  	})
  3018  
  3019  	if _, err := ctx2.Plan(); err != nil {
  3020  		t.Fatalf("err: %s", err)
  3021  	}
  3022  
  3023  	state2, err := ctx2.Apply()
  3024  	if err != nil {
  3025  		t.Fatalf("err: %s", err)
  3026  	}
  3027  
  3028  	actual := strings.TrimSpace(state2.String())
  3029  	expected := strings.TrimSpace(testTerraformApplyOutputAddStr)
  3030  	if actual != expected {
  3031  		t.Fatalf("bad: \n%s", actual)
  3032  	}
  3033  }
  3034  
  3035  func TestContext2Apply_outputList(t *testing.T) {
  3036  	m := testModule(t, "apply-output-list")
  3037  	p := testProvider("aws")
  3038  	p.ApplyFn = testApplyFn
  3039  	p.DiffFn = testDiffFn
  3040  	ctx := testContext2(t, &ContextOpts{
  3041  		Module: m,
  3042  		Providers: map[string]ResourceProviderFactory{
  3043  			"aws": testProviderFuncFixed(p),
  3044  		},
  3045  	})
  3046  
  3047  	if _, err := ctx.Plan(); err != nil {
  3048  		t.Fatalf("err: %s", err)
  3049  	}
  3050  
  3051  	state, err := ctx.Apply()
  3052  	if err != nil {
  3053  		t.Fatalf("err: %s", err)
  3054  	}
  3055  
  3056  	actual := strings.TrimSpace(state.String())
  3057  	expected := strings.TrimSpace(testTerraformApplyOutputListStr)
  3058  	if actual != expected {
  3059  		t.Fatalf("bad: \n%s", actual)
  3060  	}
  3061  }
  3062  
  3063  func TestContext2Apply_outputMulti(t *testing.T) {
  3064  	m := testModule(t, "apply-output-multi")
  3065  	p := testProvider("aws")
  3066  	p.ApplyFn = testApplyFn
  3067  	p.DiffFn = testDiffFn
  3068  	ctx := testContext2(t, &ContextOpts{
  3069  		Module: m,
  3070  		Providers: map[string]ResourceProviderFactory{
  3071  			"aws": testProviderFuncFixed(p),
  3072  		},
  3073  	})
  3074  
  3075  	if _, err := ctx.Plan(); err != nil {
  3076  		t.Fatalf("err: %s", err)
  3077  	}
  3078  
  3079  	state, err := ctx.Apply()
  3080  	if err != nil {
  3081  		t.Fatalf("err: %s", err)
  3082  	}
  3083  
  3084  	actual := strings.TrimSpace(state.String())
  3085  	expected := strings.TrimSpace(testTerraformApplyOutputMultiStr)
  3086  	if actual != expected {
  3087  		t.Fatalf("bad: \n%s", actual)
  3088  	}
  3089  }
  3090  
  3091  func TestContext2Apply_outputMultiIndex(t *testing.T) {
  3092  	m := testModule(t, "apply-output-multi-index")
  3093  	p := testProvider("aws")
  3094  	p.ApplyFn = testApplyFn
  3095  	p.DiffFn = testDiffFn
  3096  	ctx := testContext2(t, &ContextOpts{
  3097  		Module: m,
  3098  		Providers: map[string]ResourceProviderFactory{
  3099  			"aws": testProviderFuncFixed(p),
  3100  		},
  3101  	})
  3102  
  3103  	if _, err := ctx.Plan(); err != nil {
  3104  		t.Fatalf("err: %s", err)
  3105  	}
  3106  
  3107  	state, err := ctx.Apply()
  3108  	if err != nil {
  3109  		t.Fatalf("err: %s", err)
  3110  	}
  3111  
  3112  	actual := strings.TrimSpace(state.String())
  3113  	expected := strings.TrimSpace(testTerraformApplyOutputMultiIndexStr)
  3114  	if actual != expected {
  3115  		t.Fatalf("bad: \n%s", actual)
  3116  	}
  3117  }
  3118  
  3119  func TestContext2Apply_taint(t *testing.T) {
  3120  	m := testModule(t, "apply-taint")
  3121  	p := testProvider("aws")
  3122  
  3123  	// destroyCount tests against regression of
  3124  	// https://github.com/hashicorp/terraform/issues/1056
  3125  	var destroyCount = int32(0)
  3126  	var once sync.Once
  3127  	simulateProviderDelay := func() {
  3128  		time.Sleep(10 * time.Millisecond)
  3129  	}
  3130  
  3131  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  3132  		once.Do(simulateProviderDelay)
  3133  		if d.Destroy {
  3134  			atomic.AddInt32(&destroyCount, 1)
  3135  		}
  3136  		return testApplyFn(info, s, d)
  3137  	}
  3138  	p.DiffFn = testDiffFn
  3139  	s := &State{
  3140  		Modules: []*ModuleState{
  3141  			&ModuleState{
  3142  				Path: rootModulePath,
  3143  				Resources: map[string]*ResourceState{
  3144  					"aws_instance.bar": &ResourceState{
  3145  						Type: "aws_instance",
  3146  						Tainted: []*InstanceState{
  3147  							&InstanceState{
  3148  								ID: "baz",
  3149  								Attributes: map[string]string{
  3150  									"num":  "2",
  3151  									"type": "aws_instance",
  3152  								},
  3153  							},
  3154  						},
  3155  					},
  3156  				},
  3157  			},
  3158  		},
  3159  	}
  3160  	ctx := testContext2(t, &ContextOpts{
  3161  		Module: m,
  3162  		Providers: map[string]ResourceProviderFactory{
  3163  			"aws": testProviderFuncFixed(p),
  3164  		},
  3165  		State: s,
  3166  	})
  3167  
  3168  	if _, err := ctx.Plan(); err != nil {
  3169  		t.Fatalf("err: %s", err)
  3170  	}
  3171  
  3172  	state, err := ctx.Apply()
  3173  	if err != nil {
  3174  		t.Fatalf("err: %s", err)
  3175  	}
  3176  
  3177  	actual := strings.TrimSpace(state.String())
  3178  	expected := strings.TrimSpace(testTerraformApplyTaintStr)
  3179  	if actual != expected {
  3180  		t.Fatalf("bad:\n%s", actual)
  3181  	}
  3182  
  3183  	if destroyCount != 1 {
  3184  		t.Fatalf("Expected 1 destroy, got %d", destroyCount)
  3185  	}
  3186  }
  3187  
  3188  func TestContext2Apply_taintDep(t *testing.T) {
  3189  	m := testModule(t, "apply-taint-dep")
  3190  	p := testProvider("aws")
  3191  	p.ApplyFn = testApplyFn
  3192  	p.DiffFn = testDiffFn
  3193  	s := &State{
  3194  		Modules: []*ModuleState{
  3195  			&ModuleState{
  3196  				Path: rootModulePath,
  3197  				Resources: map[string]*ResourceState{
  3198  					"aws_instance.foo": &ResourceState{
  3199  						Type: "aws_instance",
  3200  						Tainted: []*InstanceState{
  3201  							&InstanceState{
  3202  								ID: "baz",
  3203  								Attributes: map[string]string{
  3204  									"num":  "2",
  3205  									"type": "aws_instance",
  3206  								},
  3207  							},
  3208  						},
  3209  					},
  3210  					"aws_instance.bar": &ResourceState{
  3211  						Type: "aws_instance",
  3212  						Primary: &InstanceState{
  3213  							ID: "bar",
  3214  							Attributes: map[string]string{
  3215  								"foo":  "baz",
  3216  								"num":  "2",
  3217  								"type": "aws_instance",
  3218  							},
  3219  						},
  3220  					},
  3221  				},
  3222  			},
  3223  		},
  3224  	}
  3225  	ctx := testContext2(t, &ContextOpts{
  3226  		Module: m,
  3227  		Providers: map[string]ResourceProviderFactory{
  3228  			"aws": testProviderFuncFixed(p),
  3229  		},
  3230  		State: s,
  3231  	})
  3232  
  3233  	if p, err := ctx.Plan(); err != nil {
  3234  		t.Fatalf("err: %s", err)
  3235  	} else {
  3236  		t.Logf("plan: %s", p)
  3237  	}
  3238  
  3239  	state, err := ctx.Apply()
  3240  	if err != nil {
  3241  		t.Fatalf("err: %s", err)
  3242  	}
  3243  
  3244  	actual := strings.TrimSpace(state.String())
  3245  	expected := strings.TrimSpace(testTerraformApplyTaintDepStr)
  3246  	if actual != expected {
  3247  		t.Fatalf("bad:\n%s", actual)
  3248  	}
  3249  }
  3250  
  3251  func TestContext2Apply_taintDepRequiresNew(t *testing.T) {
  3252  	m := testModule(t, "apply-taint-dep-requires-new")
  3253  	p := testProvider("aws")
  3254  	p.ApplyFn = testApplyFn
  3255  	p.DiffFn = testDiffFn
  3256  	s := &State{
  3257  		Modules: []*ModuleState{
  3258  			&ModuleState{
  3259  				Path: rootModulePath,
  3260  				Resources: map[string]*ResourceState{
  3261  					"aws_instance.foo": &ResourceState{
  3262  						Type: "aws_instance",
  3263  						Tainted: []*InstanceState{
  3264  							&InstanceState{
  3265  								ID: "baz",
  3266  								Attributes: map[string]string{
  3267  									"num":  "2",
  3268  									"type": "aws_instance",
  3269  								},
  3270  							},
  3271  						},
  3272  					},
  3273  					"aws_instance.bar": &ResourceState{
  3274  						Type: "aws_instance",
  3275  						Primary: &InstanceState{
  3276  							ID: "bar",
  3277  							Attributes: map[string]string{
  3278  								"foo":  "baz",
  3279  								"num":  "2",
  3280  								"type": "aws_instance",
  3281  							},
  3282  						},
  3283  					},
  3284  				},
  3285  			},
  3286  		},
  3287  	}
  3288  	ctx := testContext2(t, &ContextOpts{
  3289  		Module: m,
  3290  		Providers: map[string]ResourceProviderFactory{
  3291  			"aws": testProviderFuncFixed(p),
  3292  		},
  3293  		State: s,
  3294  	})
  3295  
  3296  	if p, err := ctx.Plan(); err != nil {
  3297  		t.Fatalf("err: %s", err)
  3298  	} else {
  3299  		t.Logf("plan: %s", p)
  3300  	}
  3301  
  3302  	state, err := ctx.Apply()
  3303  	if err != nil {
  3304  		t.Fatalf("err: %s", err)
  3305  	}
  3306  
  3307  	actual := strings.TrimSpace(state.String())
  3308  	expected := strings.TrimSpace(testTerraformApplyTaintDepRequireNewStr)
  3309  	if actual != expected {
  3310  		t.Fatalf("bad:\n%s", actual)
  3311  	}
  3312  }
  3313  
  3314  func TestContext2Apply_targeted(t *testing.T) {
  3315  	m := testModule(t, "apply-targeted")
  3316  	p := testProvider("aws")
  3317  	p.ApplyFn = testApplyFn
  3318  	p.DiffFn = testDiffFn
  3319  	ctx := testContext2(t, &ContextOpts{
  3320  		Module: m,
  3321  		Providers: map[string]ResourceProviderFactory{
  3322  			"aws": testProviderFuncFixed(p),
  3323  		},
  3324  		Targets: []string{"aws_instance.foo"},
  3325  	})
  3326  
  3327  	if _, err := ctx.Plan(); err != nil {
  3328  		t.Fatalf("err: %s", err)
  3329  	}
  3330  
  3331  	state, err := ctx.Apply()
  3332  	if err != nil {
  3333  		t.Fatalf("err: %s", err)
  3334  	}
  3335  
  3336  	mod := state.RootModule()
  3337  	if len(mod.Resources) != 1 {
  3338  		t.Fatalf("expected 1 resource, got: %#v", mod.Resources)
  3339  	}
  3340  
  3341  	checkStateString(t, state, `
  3342  aws_instance.foo:
  3343    ID = foo
  3344    num = 2
  3345    type = aws_instance
  3346  	`)
  3347  }
  3348  
  3349  func TestContext2Apply_targetedCount(t *testing.T) {
  3350  	m := testModule(t, "apply-targeted-count")
  3351  	p := testProvider("aws")
  3352  	p.ApplyFn = testApplyFn
  3353  	p.DiffFn = testDiffFn
  3354  	ctx := testContext2(t, &ContextOpts{
  3355  		Module: m,
  3356  		Providers: map[string]ResourceProviderFactory{
  3357  			"aws": testProviderFuncFixed(p),
  3358  		},
  3359  		Targets: []string{"aws_instance.foo"},
  3360  	})
  3361  
  3362  	if _, err := ctx.Plan(); err != nil {
  3363  		t.Fatalf("err: %s", err)
  3364  	}
  3365  
  3366  	state, err := ctx.Apply()
  3367  	if err != nil {
  3368  		t.Fatalf("err: %s", err)
  3369  	}
  3370  
  3371  	checkStateString(t, state, `
  3372  aws_instance.foo.0:
  3373    ID = foo
  3374  aws_instance.foo.1:
  3375    ID = foo
  3376  aws_instance.foo.2:
  3377    ID = foo
  3378  	`)
  3379  }
  3380  
  3381  func TestContext2Apply_targetedCountIndex(t *testing.T) {
  3382  	m := testModule(t, "apply-targeted-count")
  3383  	p := testProvider("aws")
  3384  	p.ApplyFn = testApplyFn
  3385  	p.DiffFn = testDiffFn
  3386  	ctx := testContext2(t, &ContextOpts{
  3387  		Module: m,
  3388  		Providers: map[string]ResourceProviderFactory{
  3389  			"aws": testProviderFuncFixed(p),
  3390  		},
  3391  		Targets: []string{"aws_instance.foo[1]"},
  3392  	})
  3393  
  3394  	if _, err := ctx.Plan(); err != nil {
  3395  		t.Fatalf("err: %s", err)
  3396  	}
  3397  
  3398  	state, err := ctx.Apply()
  3399  	if err != nil {
  3400  		t.Fatalf("err: %s", err)
  3401  	}
  3402  
  3403  	checkStateString(t, state, `
  3404  aws_instance.foo.1:
  3405    ID = foo
  3406  	`)
  3407  }
  3408  
  3409  func TestContext2Apply_targetedDestroy(t *testing.T) {
  3410  	m := testModule(t, "apply-targeted")
  3411  	p := testProvider("aws")
  3412  	p.ApplyFn = testApplyFn
  3413  	p.DiffFn = testDiffFn
  3414  	ctx := testContext2(t, &ContextOpts{
  3415  		Module: m,
  3416  		Providers: map[string]ResourceProviderFactory{
  3417  			"aws": testProviderFuncFixed(p),
  3418  		},
  3419  		State: &State{
  3420  			Modules: []*ModuleState{
  3421  				&ModuleState{
  3422  					Path: rootModulePath,
  3423  					Resources: map[string]*ResourceState{
  3424  						"aws_instance.foo": resourceState("aws_instance", "i-bcd345"),
  3425  						"aws_instance.bar": resourceState("aws_instance", "i-abc123"),
  3426  					},
  3427  				},
  3428  			},
  3429  		},
  3430  		Targets: []string{"aws_instance.foo"},
  3431  		Destroy: true,
  3432  	})
  3433  
  3434  	if _, err := ctx.Plan(); err != nil {
  3435  		t.Fatalf("err: %s", err)
  3436  	}
  3437  
  3438  	state, err := ctx.Apply()
  3439  	if err != nil {
  3440  		t.Fatalf("err: %s", err)
  3441  	}
  3442  
  3443  	mod := state.RootModule()
  3444  	if len(mod.Resources) != 1 {
  3445  		t.Fatalf("expected 1 resource, got: %#v", mod.Resources)
  3446  	}
  3447  
  3448  	checkStateString(t, state, `
  3449  aws_instance.bar:
  3450    ID = i-abc123
  3451  	`)
  3452  }
  3453  
  3454  // https://github.com/hashicorp/terraform/issues/4462
  3455  func TestContext2Apply_targetedDestroyModule(t *testing.T) {
  3456  	m := testModule(t, "apply-targeted-module")
  3457  	p := testProvider("aws")
  3458  	p.ApplyFn = testApplyFn
  3459  	p.DiffFn = testDiffFn
  3460  	ctx := testContext2(t, &ContextOpts{
  3461  		Module: m,
  3462  		Providers: map[string]ResourceProviderFactory{
  3463  			"aws": testProviderFuncFixed(p),
  3464  		},
  3465  		State: &State{
  3466  			Modules: []*ModuleState{
  3467  				&ModuleState{
  3468  					Path: rootModulePath,
  3469  					Resources: map[string]*ResourceState{
  3470  						"aws_instance.foo": resourceState("aws_instance", "i-bcd345"),
  3471  						"aws_instance.bar": resourceState("aws_instance", "i-abc123"),
  3472  					},
  3473  				},
  3474  				&ModuleState{
  3475  					Path: []string{"root", "child"},
  3476  					Resources: map[string]*ResourceState{
  3477  						"aws_instance.foo": resourceState("aws_instance", "i-bcd345"),
  3478  						"aws_instance.bar": resourceState("aws_instance", "i-abc123"),
  3479  					},
  3480  				},
  3481  			},
  3482  		},
  3483  		Targets: []string{"module.child.aws_instance.foo"},
  3484  		Destroy: true,
  3485  	})
  3486  
  3487  	if _, err := ctx.Plan(); err != nil {
  3488  		t.Fatalf("err: %s", err)
  3489  	}
  3490  
  3491  	state, err := ctx.Apply()
  3492  	if err != nil {
  3493  		t.Fatalf("err: %s", err)
  3494  	}
  3495  
  3496  	checkStateString(t, state, `
  3497  aws_instance.bar:
  3498    ID = i-abc123
  3499  aws_instance.foo:
  3500    ID = i-bcd345
  3501  
  3502  module.child:
  3503    aws_instance.bar:
  3504      ID = i-abc123
  3505  	`)
  3506  }
  3507  
  3508  func TestContext2Apply_targetedDestroyCountIndex(t *testing.T) {
  3509  	m := testModule(t, "apply-targeted-count")
  3510  	p := testProvider("aws")
  3511  	p.ApplyFn = testApplyFn
  3512  	p.DiffFn = testDiffFn
  3513  	ctx := testContext2(t, &ContextOpts{
  3514  		Module: m,
  3515  		Providers: map[string]ResourceProviderFactory{
  3516  			"aws": testProviderFuncFixed(p),
  3517  		},
  3518  		State: &State{
  3519  			Modules: []*ModuleState{
  3520  				&ModuleState{
  3521  					Path: rootModulePath,
  3522  					Resources: map[string]*ResourceState{
  3523  						"aws_instance.foo.0": resourceState("aws_instance", "i-bcd345"),
  3524  						"aws_instance.foo.1": resourceState("aws_instance", "i-bcd345"),
  3525  						"aws_instance.foo.2": resourceState("aws_instance", "i-bcd345"),
  3526  						"aws_instance.bar.0": resourceState("aws_instance", "i-abc123"),
  3527  						"aws_instance.bar.1": resourceState("aws_instance", "i-abc123"),
  3528  						"aws_instance.bar.2": resourceState("aws_instance", "i-abc123"),
  3529  					},
  3530  				},
  3531  			},
  3532  		},
  3533  		Targets: []string{
  3534  			"aws_instance.foo[2]",
  3535  			"aws_instance.bar[1]",
  3536  		},
  3537  		Destroy: true,
  3538  	})
  3539  
  3540  	if _, err := ctx.Plan(); err != nil {
  3541  		t.Fatalf("err: %s", err)
  3542  	}
  3543  
  3544  	state, err := ctx.Apply()
  3545  	if err != nil {
  3546  		t.Fatalf("err: %s", err)
  3547  	}
  3548  
  3549  	checkStateString(t, state, `
  3550  aws_instance.bar.0:
  3551    ID = i-abc123
  3552  aws_instance.bar.2:
  3553    ID = i-abc123
  3554  aws_instance.foo.0:
  3555    ID = i-bcd345
  3556  aws_instance.foo.1:
  3557    ID = i-bcd345
  3558  	`)
  3559  }
  3560  
  3561  func TestContext2Apply_targetedModule(t *testing.T) {
  3562  	m := testModule(t, "apply-targeted-module")
  3563  	p := testProvider("aws")
  3564  	p.ApplyFn = testApplyFn
  3565  	p.DiffFn = testDiffFn
  3566  	ctx := testContext2(t, &ContextOpts{
  3567  		Module: m,
  3568  		Providers: map[string]ResourceProviderFactory{
  3569  			"aws": testProviderFuncFixed(p),
  3570  		},
  3571  		Targets: []string{"module.child"},
  3572  	})
  3573  
  3574  	if _, err := ctx.Plan(); err != nil {
  3575  		t.Fatalf("err: %s", err)
  3576  	}
  3577  
  3578  	state, err := ctx.Apply()
  3579  	if err != nil {
  3580  		t.Fatalf("err: %s", err)
  3581  	}
  3582  
  3583  	mod := state.ModuleByPath([]string{"root", "child"})
  3584  	if mod == nil {
  3585  		t.Fatalf("no child module found in the state!\n\n%#v", state)
  3586  	}
  3587  	if len(mod.Resources) != 2 {
  3588  		t.Fatalf("expected 2 resources, got: %#v", mod.Resources)
  3589  	}
  3590  
  3591  	checkStateString(t, state, `
  3592  <no state>
  3593  module.child:
  3594    aws_instance.bar:
  3595      ID = foo
  3596      num = 2
  3597      type = aws_instance
  3598    aws_instance.foo:
  3599      ID = foo
  3600      num = 2
  3601      type = aws_instance
  3602  	`)
  3603  }
  3604  
  3605  // GH-1858
  3606  func TestContext2Apply_targetedModuleDep(t *testing.T) {
  3607  	m := testModule(t, "apply-targeted-module-dep")
  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{"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  	checkStateString(t, state, `
  3629  aws_instance.foo:
  3630    ID = foo
  3631    foo = foo
  3632    type = aws_instance
  3633  
  3634    Dependencies:
  3635      module.child
  3636  
  3637  module.child:
  3638    aws_instance.mod:
  3639      ID = foo
  3640  
  3641    Outputs:
  3642  
  3643    output = foo
  3644  	`)
  3645  }
  3646  
  3647  func TestContext2Apply_targetedModuleResource(t *testing.T) {
  3648  	m := testModule(t, "apply-targeted-module-resource")
  3649  	p := testProvider("aws")
  3650  	p.ApplyFn = testApplyFn
  3651  	p.DiffFn = testDiffFn
  3652  	ctx := testContext2(t, &ContextOpts{
  3653  		Module: m,
  3654  		Providers: map[string]ResourceProviderFactory{
  3655  			"aws": testProviderFuncFixed(p),
  3656  		},
  3657  		Targets: []string{"module.child.aws_instance.foo"},
  3658  	})
  3659  
  3660  	if _, err := ctx.Plan(); err != nil {
  3661  		t.Fatalf("err: %s", err)
  3662  	}
  3663  
  3664  	state, err := ctx.Apply()
  3665  	if err != nil {
  3666  		t.Fatalf("err: %s", err)
  3667  	}
  3668  
  3669  	mod := state.ModuleByPath([]string{"root", "child"})
  3670  	if len(mod.Resources) != 1 {
  3671  		t.Fatalf("expected 1 resource, got: %#v", mod.Resources)
  3672  	}
  3673  
  3674  	checkStateString(t, state, `
  3675  <no state>
  3676  module.child:
  3677    aws_instance.foo:
  3678      ID = foo
  3679      num = 2
  3680      type = aws_instance
  3681  	`)
  3682  }
  3683  
  3684  func TestContext2Apply_unknownAttribute(t *testing.T) {
  3685  	m := testModule(t, "apply-unknown")
  3686  	p := testProvider("aws")
  3687  	p.ApplyFn = testApplyFn
  3688  	p.DiffFn = testDiffFn
  3689  	ctx := testContext2(t, &ContextOpts{
  3690  		Module: m,
  3691  		Providers: map[string]ResourceProviderFactory{
  3692  			"aws": testProviderFuncFixed(p),
  3693  		},
  3694  	})
  3695  
  3696  	if _, err := ctx.Plan(); err != nil {
  3697  		t.Fatalf("err: %s", err)
  3698  	}
  3699  
  3700  	state, err := ctx.Apply()
  3701  	if err == nil {
  3702  		t.Fatal("should error")
  3703  	}
  3704  
  3705  	actual := strings.TrimSpace(state.String())
  3706  	expected := strings.TrimSpace(testTerraformApplyUnknownAttrStr)
  3707  	if actual != expected {
  3708  		t.Fatalf("bad: \n%s", actual)
  3709  	}
  3710  }
  3711  
  3712  func TestContext2Apply_unknownAttributeInterpolate(t *testing.T) {
  3713  	m := testModule(t, "apply-unknown-interpolate")
  3714  	p := testProvider("aws")
  3715  	p.ApplyFn = testApplyFn
  3716  	p.DiffFn = testDiffFn
  3717  	ctx := testContext2(t, &ContextOpts{
  3718  		Module: m,
  3719  		Providers: map[string]ResourceProviderFactory{
  3720  			"aws": testProviderFuncFixed(p),
  3721  		},
  3722  	})
  3723  
  3724  	if _, err := ctx.Plan(); err == nil {
  3725  		t.Fatal("should error")
  3726  	}
  3727  }
  3728  
  3729  func TestContext2Apply_vars(t *testing.T) {
  3730  	m := testModule(t, "apply-vars")
  3731  	p := testProvider("aws")
  3732  	p.ApplyFn = testApplyFn
  3733  	p.DiffFn = testDiffFn
  3734  	ctx := testContext2(t, &ContextOpts{
  3735  		Module: m,
  3736  		Providers: map[string]ResourceProviderFactory{
  3737  			"aws": testProviderFuncFixed(p),
  3738  		},
  3739  		Variables: map[string]string{
  3740  			"foo":            "us-west-2",
  3741  			"amis.us-east-1": "override",
  3742  		},
  3743  	})
  3744  
  3745  	w, e := ctx.Validate()
  3746  	if len(w) > 0 {
  3747  		t.Fatalf("bad: %#v", w)
  3748  	}
  3749  	if len(e) > 0 {
  3750  		t.Fatalf("bad: %s", e)
  3751  	}
  3752  
  3753  	if _, err := ctx.Plan(); err != nil {
  3754  		t.Fatalf("err: %s", err)
  3755  	}
  3756  
  3757  	state, err := ctx.Apply()
  3758  	if err != nil {
  3759  		t.Fatalf("err: %s", err)
  3760  	}
  3761  
  3762  	actual := strings.TrimSpace(state.String())
  3763  	expected := strings.TrimSpace(testTerraformApplyVarsStr)
  3764  	if actual != expected {
  3765  		t.Fatalf("bad: \n%s", actual)
  3766  	}
  3767  }
  3768  
  3769  func TestContext2Apply_varsEnv(t *testing.T) {
  3770  	// Set the env var
  3771  	old := tempEnv(t, "TF_VAR_ami", "baz")
  3772  	defer os.Setenv("TF_VAR_ami", old)
  3773  
  3774  	m := testModule(t, "apply-vars-env")
  3775  	p := testProvider("aws")
  3776  	p.ApplyFn = testApplyFn
  3777  	p.DiffFn = testDiffFn
  3778  	ctx := testContext2(t, &ContextOpts{
  3779  		Module: m,
  3780  		Providers: map[string]ResourceProviderFactory{
  3781  			"aws": testProviderFuncFixed(p),
  3782  		},
  3783  	})
  3784  
  3785  	w, e := ctx.Validate()
  3786  	if len(w) > 0 {
  3787  		t.Fatalf("bad: %#v", w)
  3788  	}
  3789  	if len(e) > 0 {
  3790  		t.Fatalf("bad: %s", e)
  3791  	}
  3792  
  3793  	if _, err := ctx.Plan(); err != nil {
  3794  		t.Fatalf("err: %s", err)
  3795  	}
  3796  
  3797  	state, err := ctx.Apply()
  3798  	if err != nil {
  3799  		t.Fatalf("err: %s", err)
  3800  	}
  3801  
  3802  	actual := strings.TrimSpace(state.String())
  3803  	expected := strings.TrimSpace(testTerraformApplyVarsEnvStr)
  3804  	if actual != expected {
  3805  		t.Fatalf("bad: \n%s", actual)
  3806  	}
  3807  }
  3808  
  3809  func TestContext2Apply_createBefore_depends(t *testing.T) {
  3810  	m := testModule(t, "apply-depends-create-before")
  3811  	h := new(HookRecordApplyOrder)
  3812  	p := testProvider("aws")
  3813  	p.ApplyFn = testApplyFn
  3814  	p.DiffFn = testDiffFn
  3815  	state := &State{
  3816  		Modules: []*ModuleState{
  3817  			&ModuleState{
  3818  				Path: rootModulePath,
  3819  				Resources: map[string]*ResourceState{
  3820  					"aws_instance.web": &ResourceState{
  3821  						Type: "aws_instance",
  3822  						Primary: &InstanceState{
  3823  							ID: "bar",
  3824  							Attributes: map[string]string{
  3825  								"require_new": "ami-old",
  3826  							},
  3827  						},
  3828  					},
  3829  					"aws_instance.lb": &ResourceState{
  3830  						Type: "aws_instance",
  3831  						Primary: &InstanceState{
  3832  							ID: "baz",
  3833  							Attributes: map[string]string{
  3834  								"instance": "bar",
  3835  							},
  3836  						},
  3837  					},
  3838  				},
  3839  			},
  3840  		},
  3841  	}
  3842  	ctx := testContext2(t, &ContextOpts{
  3843  		Module: m,
  3844  		Hooks:  []Hook{h},
  3845  		Providers: map[string]ResourceProviderFactory{
  3846  			"aws": testProviderFuncFixed(p),
  3847  		},
  3848  		State: state,
  3849  	})
  3850  
  3851  	if _, err := ctx.Plan(); err != nil {
  3852  		t.Fatalf("err: %s", err)
  3853  	}
  3854  
  3855  	h.Active = true
  3856  	state, err := ctx.Apply()
  3857  	if err != nil {
  3858  		t.Fatalf("err: %s", err)
  3859  	}
  3860  
  3861  	mod := state.RootModule()
  3862  	if len(mod.Resources) < 2 {
  3863  		t.Fatalf("bad: %#v", mod.Resources)
  3864  	}
  3865  
  3866  	actual := strings.TrimSpace(state.String())
  3867  	expected := strings.TrimSpace(testTerraformApplyDependsCreateBeforeStr)
  3868  	if actual != expected {
  3869  		t.Fatalf("bad: \n%s\n%s", actual, expected)
  3870  	}
  3871  
  3872  	// Test that things were managed _in the right order_
  3873  	order := h.States
  3874  	diffs := h.Diffs
  3875  	if order[0].ID != "" || diffs[0].Destroy {
  3876  		t.Fatalf("should create new instance first: %#v", order)
  3877  	}
  3878  
  3879  	if order[1].ID != "baz" {
  3880  		t.Fatalf("update must happen after create: %#v", order)
  3881  	}
  3882  
  3883  	if order[2].ID != "bar" || !diffs[2].Destroy {
  3884  		t.Fatalf("destroy must happen after update: %#v", order)
  3885  	}
  3886  }
  3887  
  3888  func TestContext2Apply_singleDestroy(t *testing.T) {
  3889  	m := testModule(t, "apply-depends-create-before")
  3890  	h := new(HookRecordApplyOrder)
  3891  	p := testProvider("aws")
  3892  
  3893  	invokeCount := 0
  3894  	p.ApplyFn = func(info *InstanceInfo, s *InstanceState, d *InstanceDiff) (*InstanceState, error) {
  3895  		invokeCount++
  3896  		switch invokeCount {
  3897  		case 1:
  3898  			if d.Destroy {
  3899  				t.Fatalf("should not destroy")
  3900  			}
  3901  			if s.ID != "" {
  3902  				t.Fatalf("should not have ID")
  3903  			}
  3904  		case 2:
  3905  			if d.Destroy {
  3906  				t.Fatalf("should not destroy")
  3907  			}
  3908  			if s.ID != "baz" {
  3909  				t.Fatalf("should have id")
  3910  			}
  3911  		case 3:
  3912  			if !d.Destroy {
  3913  				t.Fatalf("should destroy")
  3914  			}
  3915  			if s.ID == "" {
  3916  				t.Fatalf("should have ID")
  3917  			}
  3918  		default:
  3919  			t.Fatalf("bad invoke count %d", invokeCount)
  3920  		}
  3921  		return testApplyFn(info, s, d)
  3922  	}
  3923  	p.DiffFn = testDiffFn
  3924  	state := &State{
  3925  		Modules: []*ModuleState{
  3926  			&ModuleState{
  3927  				Path: rootModulePath,
  3928  				Resources: map[string]*ResourceState{
  3929  					"aws_instance.web": &ResourceState{
  3930  						Type: "aws_instance",
  3931  						Primary: &InstanceState{
  3932  							ID: "bar",
  3933  							Attributes: map[string]string{
  3934  								"require_new": "ami-old",
  3935  							},
  3936  						},
  3937  					},
  3938  					"aws_instance.lb": &ResourceState{
  3939  						Type: "aws_instance",
  3940  						Primary: &InstanceState{
  3941  							ID: "baz",
  3942  							Attributes: map[string]string{
  3943  								"instance": "bar",
  3944  							},
  3945  						},
  3946  					},
  3947  				},
  3948  			},
  3949  		},
  3950  	}
  3951  	ctx := testContext2(t, &ContextOpts{
  3952  		Module: m,
  3953  		Hooks:  []Hook{h},
  3954  		Providers: map[string]ResourceProviderFactory{
  3955  			"aws": testProviderFuncFixed(p),
  3956  		},
  3957  		State: state,
  3958  	})
  3959  
  3960  	if _, err := ctx.Plan(); err != nil {
  3961  		t.Fatalf("err: %s", err)
  3962  	}
  3963  
  3964  	h.Active = true
  3965  	state, err := ctx.Apply()
  3966  	if err != nil {
  3967  		t.Fatalf("err: %s", err)
  3968  	}
  3969  
  3970  	if invokeCount != 3 {
  3971  		t.Fatalf("bad: %d", invokeCount)
  3972  	}
  3973  }
  3974  
  3975  // GH-5254
  3976  func TestContext2Apply_issue5254(t *testing.T) {
  3977  	// Create a provider. We use "template" here just to match the repro
  3978  	// we got from the issue itself.
  3979  	p := testProvider("template")
  3980  	p.ResourcesReturn = append(p.ResourcesReturn, ResourceType{
  3981  		Name: "template_file",
  3982  	})
  3983  
  3984  	p.ApplyFn = testApplyFn
  3985  	p.DiffFn = testDiffFn
  3986  
  3987  	// Apply cleanly step 0
  3988  	ctx := testContext2(t, &ContextOpts{
  3989  		Module: testModule(t, "issue-5254/step-0"),
  3990  		Providers: map[string]ResourceProviderFactory{
  3991  			"template": testProviderFuncFixed(p),
  3992  		},
  3993  	})
  3994  
  3995  	plan, err := ctx.Plan()
  3996  	if err != nil {
  3997  		t.Fatalf("err: %s", err)
  3998  	}
  3999  
  4000  	state, err := ctx.Apply()
  4001  	if err != nil {
  4002  		t.Fatalf("err: %s", err)
  4003  	}
  4004  
  4005  	// Application success. Now make the modification and store a plan
  4006  	ctx = testContext2(t, &ContextOpts{
  4007  		Module: testModule(t, "issue-5254/step-1"),
  4008  		State:  state,
  4009  		Providers: map[string]ResourceProviderFactory{
  4010  			"template": testProviderFuncFixed(p),
  4011  		},
  4012  	})
  4013  
  4014  	plan, err = ctx.Plan()
  4015  	if err != nil {
  4016  		t.Fatalf("err: %s", err)
  4017  	}
  4018  
  4019  	// Write / Read plan to simulate running it through a Plan file
  4020  	var buf bytes.Buffer
  4021  	if err := WritePlan(plan, &buf); err != nil {
  4022  		t.Fatalf("err: %s", err)
  4023  	}
  4024  
  4025  	planFromFile, err := ReadPlan(&buf)
  4026  	if err != nil {
  4027  		t.Fatalf("err: %s", err)
  4028  	}
  4029  
  4030  	ctx = planFromFile.Context(&ContextOpts{
  4031  		Providers: map[string]ResourceProviderFactory{
  4032  			"template": testProviderFuncFixed(p),
  4033  		},
  4034  	})
  4035  
  4036  	state, err = ctx.Apply()
  4037  	if err != nil {
  4038  		t.Fatalf("err: %s", err)
  4039  	}
  4040  
  4041  	actual := strings.TrimSpace(state.String())
  4042  	expected := strings.TrimSpace(`
  4043  template_file.child:
  4044    ID = foo
  4045    template = Hi
  4046    type = template_file
  4047  
  4048    Dependencies:
  4049      template_file.parent
  4050  template_file.parent:
  4051    ID = foo
  4052    template = Hi
  4053    type = template_file
  4054  		`)
  4055  	if actual != expected {
  4056  		t.Fatalf("expected state: \n%s\ngot: \n%s", expected, actual)
  4057  	}
  4058  }
  4059  
  4060  func TestContext2Apply_targetedWithTaintedInState(t *testing.T) {
  4061  	p := testProvider("aws")
  4062  	p.DiffFn = testDiffFn
  4063  	p.ApplyFn = testApplyFn
  4064  	ctx := testContext2(t, &ContextOpts{
  4065  		Module: testModule(t, "apply-tainted-targets"),
  4066  		Providers: map[string]ResourceProviderFactory{
  4067  			"aws": testProviderFuncFixed(p),
  4068  		},
  4069  		Targets: []string{"aws_instance.iambeingadded"},
  4070  		State: &State{
  4071  			Modules: []*ModuleState{
  4072  				&ModuleState{
  4073  					Path: rootModulePath,
  4074  					Resources: map[string]*ResourceState{
  4075  						"aws_instance.ifailedprovisioners": &ResourceState{
  4076  							Tainted: []*InstanceState{
  4077  								&InstanceState{
  4078  									ID: "ifailedprovisioners",
  4079  								},
  4080  							},
  4081  						},
  4082  					},
  4083  				},
  4084  			},
  4085  		},
  4086  	})
  4087  
  4088  	plan, err := ctx.Plan()
  4089  	if err != nil {
  4090  		t.Fatalf("err: %s", err)
  4091  	}
  4092  
  4093  	// Write / Read plan to simulate running it through a Plan file
  4094  	var buf bytes.Buffer
  4095  	if err := WritePlan(plan, &buf); err != nil {
  4096  		t.Fatalf("err: %s", err)
  4097  	}
  4098  
  4099  	planFromFile, err := ReadPlan(&buf)
  4100  	if err != nil {
  4101  		t.Fatalf("err: %s", err)
  4102  	}
  4103  
  4104  	ctx = planFromFile.Context(&ContextOpts{
  4105  		Module: testModule(t, "apply-tainted-targets"),
  4106  		Providers: map[string]ResourceProviderFactory{
  4107  			"aws": testProviderFuncFixed(p),
  4108  		},
  4109  	})
  4110  
  4111  	state, err := ctx.Apply()
  4112  	if err != nil {
  4113  		t.Fatalf("err: %s", err)
  4114  	}
  4115  
  4116  	actual := strings.TrimSpace(state.String())
  4117  	expected := strings.TrimSpace(`
  4118  aws_instance.iambeingadded:
  4119    ID = foo
  4120  aws_instance.ifailedprovisioners: (1 tainted)
  4121    ID = <not created>
  4122    Tainted ID 1 = ifailedprovisioners
  4123  		`)
  4124  	if actual != expected {
  4125  		t.Fatalf("expected state: \n%s\ngot: \n%s", expected, actual)
  4126  	}
  4127  }
  4128  
  4129  // Higher level test exposing the bug this covers in
  4130  // TestResource_ignoreChangesRequired
  4131  func TestContext2Apply_ignoreChangesCreate(t *testing.T) {
  4132  	m := testModule(t, "apply-ignore-changes-create")
  4133  	p := testProvider("aws")
  4134  	p.ApplyFn = testApplyFn
  4135  	p.DiffFn = testDiffFn
  4136  	ctx := testContext2(t, &ContextOpts{
  4137  		Module: m,
  4138  		Providers: map[string]ResourceProviderFactory{
  4139  			"aws": testProviderFuncFixed(p),
  4140  		},
  4141  	})
  4142  
  4143  	if p, err := ctx.Plan(); err != nil {
  4144  		t.Fatalf("err: %s", err)
  4145  	} else {
  4146  		t.Logf(p.String())
  4147  	}
  4148  
  4149  	state, err := ctx.Apply()
  4150  	if err != nil {
  4151  		t.Fatalf("err: %s", err)
  4152  	}
  4153  
  4154  	mod := state.RootModule()
  4155  	if len(mod.Resources) != 1 {
  4156  		t.Fatalf("bad: %s", state)
  4157  	}
  4158  
  4159  	actual := strings.TrimSpace(state.String())
  4160  	// Expect no changes from original state
  4161  	expected := strings.TrimSpace(`
  4162  aws_instance.foo:
  4163    ID = foo
  4164    required_field = set
  4165    type = aws_instance
  4166  `)
  4167  	if actual != expected {
  4168  		t.Fatalf("bad: \n%s", actual)
  4169  	}
  4170  }