github.com/turtlemonvh/terraform@v0.6.9-0.20151204001754-8e40b6b855e8/terraform/context_apply_test.go (about)

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