terraform: Context.Plan
This commit is contained in:
parent
2e10ddb878
commit
403876fff3
|
@ -52,6 +52,29 @@ func NewContext(opts *ContextOpts) *Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Plan generates an execution plan for the given context.
|
||||||
|
//
|
||||||
|
// The execution plan encapsulates the context and can be stored
|
||||||
|
// in order to reinstantiate a context later for Apply.
|
||||||
|
func (c *Context) Plan(opts *PlanOpts) (*Plan, error) {
|
||||||
|
g, err := Graph(&GraphOpts{
|
||||||
|
Config: c.config,
|
||||||
|
Providers: c.providers,
|
||||||
|
State: c.state,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
p := &Plan{
|
||||||
|
Config: c.config,
|
||||||
|
Vars: c.variables,
|
||||||
|
State: c.state,
|
||||||
|
}
|
||||||
|
err = g.Walk(c.planWalkFn(p, opts))
|
||||||
|
return p, err
|
||||||
|
}
|
||||||
|
|
||||||
// Refresh goes through all the resources in the state and refreshes them
|
// Refresh goes through all the resources in the state and refreshes them
|
||||||
// to their latest state. This will update the state that this context
|
// to their latest state. This will update the state that this context
|
||||||
// works with, along with returning it.
|
// works with, along with returning it.
|
||||||
|
@ -96,6 +119,68 @@ func (c *Context) Validate() ([]string, []error) {
|
||||||
return nil, errs
|
return nil, errs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Context) planWalkFn(result *Plan, opts *PlanOpts) depgraph.WalkFunc {
|
||||||
|
var l sync.Mutex
|
||||||
|
|
||||||
|
// If we were given nil options, instantiate it
|
||||||
|
if opts == nil {
|
||||||
|
opts = new(PlanOpts)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the result
|
||||||
|
result.init()
|
||||||
|
|
||||||
|
cb := func(r *Resource) (map[string]string, error) {
|
||||||
|
var diff *ResourceDiff
|
||||||
|
|
||||||
|
for _, h := range c.hooks {
|
||||||
|
handleHook(h.PreDiff(r.Id, r.State))
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts.Destroy {
|
||||||
|
if r.State.ID != "" {
|
||||||
|
log.Printf("[DEBUG] %s: Making for destroy", r.Id)
|
||||||
|
diff = &ResourceDiff{Destroy: true}
|
||||||
|
} else {
|
||||||
|
log.Printf("[DEBUG] %s: Not marking for destroy, no ID", r.Id)
|
||||||
|
}
|
||||||
|
} else if r.Config == nil {
|
||||||
|
log.Printf("[DEBUG] %s: Orphan, marking for destroy", r.Id)
|
||||||
|
|
||||||
|
// This is an orphan (no config), so we mark it to be destroyed
|
||||||
|
diff = &ResourceDiff{Destroy: true}
|
||||||
|
} else {
|
||||||
|
log.Printf("[DEBUG] %s: Executing diff", r.Id)
|
||||||
|
|
||||||
|
// Get a diff from the newest state
|
||||||
|
var err error
|
||||||
|
diff, err = r.Provider.Diff(r.State, r.Config)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
l.Lock()
|
||||||
|
if !diff.Empty() {
|
||||||
|
result.Diff.Resources[r.Id] = diff
|
||||||
|
}
|
||||||
|
l.Unlock()
|
||||||
|
|
||||||
|
for _, h := range c.hooks {
|
||||||
|
handleHook(h.PostDiff(r.Id, diff))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Determine the new state and update variables
|
||||||
|
if !diff.Empty() {
|
||||||
|
r.State = r.State.MergeDiff(diff)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r.Vars(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.genericWalkFn(c.variables, cb)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Context) refreshWalkFn(result *State) depgraph.WalkFunc {
|
func (c *Context) refreshWalkFn(result *State) depgraph.WalkFunc {
|
||||||
var l sync.Mutex
|
var l sync.Mutex
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package terraform
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -51,6 +52,213 @@ func TestContextValidate_requiredVar(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestContextPlan(t *testing.T) {
|
||||||
|
c := testConfig(t, "plan-good")
|
||||||
|
p := testProvider("aws")
|
||||||
|
p.DiffFn = testDiffFn
|
||||||
|
ctx := testContext(t, &ContextOpts{
|
||||||
|
Config: c,
|
||||||
|
Providers: map[string]ResourceProviderFactory{
|
||||||
|
"aws": testProviderFuncFixed(p),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
plan, err := ctx.Plan(nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(plan.Diff.Resources) < 2 {
|
||||||
|
t.Fatalf("bad: %#v", plan.Diff.Resources)
|
||||||
|
}
|
||||||
|
|
||||||
|
actual := strings.TrimSpace(plan.String())
|
||||||
|
expected := strings.TrimSpace(testTerraformPlanStr)
|
||||||
|
if actual != expected {
|
||||||
|
t.Fatalf("bad:\n%s", actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContextPlan_nil(t *testing.T) {
|
||||||
|
c := testConfig(t, "plan-nil")
|
||||||
|
p := testProvider("aws")
|
||||||
|
p.DiffFn = testDiffFn
|
||||||
|
ctx := testContext(t, &ContextOpts{
|
||||||
|
Config: c,
|
||||||
|
Providers: map[string]ResourceProviderFactory{
|
||||||
|
"aws": testProviderFuncFixed(p),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
plan, err := ctx.Plan(nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
if len(plan.Diff.Resources) != 0 {
|
||||||
|
t.Fatalf("bad: %#v", plan.Diff.Resources)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContextPlan_computed(t *testing.T) {
|
||||||
|
c := testConfig(t, "plan-computed")
|
||||||
|
p := testProvider("aws")
|
||||||
|
p.DiffFn = testDiffFn
|
||||||
|
ctx := testContext(t, &ContextOpts{
|
||||||
|
Config: c,
|
||||||
|
Providers: map[string]ResourceProviderFactory{
|
||||||
|
"aws": testProviderFuncFixed(p),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
plan, err := ctx.Plan(nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(plan.Diff.Resources) < 2 {
|
||||||
|
t.Fatalf("bad: %#v", plan.Diff.Resources)
|
||||||
|
}
|
||||||
|
|
||||||
|
actual := strings.TrimSpace(plan.String())
|
||||||
|
expected := strings.TrimSpace(testTerraformPlanComputedStr)
|
||||||
|
if actual != expected {
|
||||||
|
t.Fatalf("bad:\n%s", actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContextPlan_destroy(t *testing.T) {
|
||||||
|
c := testConfig(t, "plan-destroy")
|
||||||
|
p := testProvider("aws")
|
||||||
|
p.DiffFn = testDiffFn
|
||||||
|
s := &State{
|
||||||
|
Resources: map[string]*ResourceState{
|
||||||
|
"aws_instance.one": &ResourceState{
|
||||||
|
ID: "bar",
|
||||||
|
Type: "aws_instance",
|
||||||
|
},
|
||||||
|
"aws_instance.two": &ResourceState{
|
||||||
|
ID: "baz",
|
||||||
|
Type: "aws_instance",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
ctx := testContext(t, &ContextOpts{
|
||||||
|
Config: c,
|
||||||
|
Providers: map[string]ResourceProviderFactory{
|
||||||
|
"aws": testProviderFuncFixed(p),
|
||||||
|
},
|
||||||
|
State: s,
|
||||||
|
})
|
||||||
|
|
||||||
|
plan, err := ctx.Plan(&PlanOpts{Destroy: true})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(plan.Diff.Resources) != 2 {
|
||||||
|
t.Fatalf("bad: %#v", plan.Diff.Resources)
|
||||||
|
}
|
||||||
|
|
||||||
|
actual := strings.TrimSpace(plan.String())
|
||||||
|
expected := strings.TrimSpace(testTerraformPlanDestroyStr)
|
||||||
|
if actual != expected {
|
||||||
|
t.Fatalf("bad:\n%s", actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContextPlan_hook(t *testing.T) {
|
||||||
|
c := testConfig(t, "plan-good")
|
||||||
|
h := new(MockHook)
|
||||||
|
p := testProvider("aws")
|
||||||
|
p.DiffFn = testDiffFn
|
||||||
|
ctx := testContext(t, &ContextOpts{
|
||||||
|
Config: c,
|
||||||
|
Hooks: []Hook{h},
|
||||||
|
Providers: map[string]ResourceProviderFactory{
|
||||||
|
"aws": testProviderFuncFixed(p),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
_, err := ctx.Plan(nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !h.PreDiffCalled {
|
||||||
|
t.Fatal("should be called")
|
||||||
|
}
|
||||||
|
if !h.PostDiffCalled {
|
||||||
|
t.Fatal("should be called")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContextPlan_orphan(t *testing.T) {
|
||||||
|
c := testConfig(t, "plan-orphan")
|
||||||
|
p := testProvider("aws")
|
||||||
|
p.DiffFn = testDiffFn
|
||||||
|
s := &State{
|
||||||
|
Resources: map[string]*ResourceState{
|
||||||
|
"aws_instance.baz": &ResourceState{
|
||||||
|
ID: "bar",
|
||||||
|
Type: "aws_instance",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
ctx := testContext(t, &ContextOpts{
|
||||||
|
Config: c,
|
||||||
|
Providers: map[string]ResourceProviderFactory{
|
||||||
|
"aws": testProviderFuncFixed(p),
|
||||||
|
},
|
||||||
|
State: s,
|
||||||
|
})
|
||||||
|
|
||||||
|
plan, err := ctx.Plan(nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
actual := strings.TrimSpace(plan.String())
|
||||||
|
expected := strings.TrimSpace(testTerraformPlanOrphanStr)
|
||||||
|
if actual != expected {
|
||||||
|
t.Fatalf("bad:\n%s", actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestContextPlan_state(t *testing.T) {
|
||||||
|
c := testConfig(t, "plan-good")
|
||||||
|
p := testProvider("aws")
|
||||||
|
p.DiffFn = testDiffFn
|
||||||
|
s := &State{
|
||||||
|
Resources: map[string]*ResourceState{
|
||||||
|
"aws_instance.foo": &ResourceState{
|
||||||
|
ID: "bar",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
ctx := testContext(t, &ContextOpts{
|
||||||
|
Config: c,
|
||||||
|
Providers: map[string]ResourceProviderFactory{
|
||||||
|
"aws": testProviderFuncFixed(p),
|
||||||
|
},
|
||||||
|
State: s,
|
||||||
|
})
|
||||||
|
|
||||||
|
plan, err := ctx.Plan(nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(plan.Diff.Resources) < 2 {
|
||||||
|
t.Fatalf("bad: %#v", plan.Diff.Resources)
|
||||||
|
}
|
||||||
|
|
||||||
|
actual := strings.TrimSpace(plan.String())
|
||||||
|
expected := strings.TrimSpace(testTerraformPlanStateStr)
|
||||||
|
if actual != expected {
|
||||||
|
t.Fatalf("bad:\n%s", actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestContextRefresh(t *testing.T) {
|
func TestContextRefresh(t *testing.T) {
|
||||||
p := testProvider("aws")
|
p := testProvider("aws")
|
||||||
c := testConfig(t, "refresh-basic")
|
c := testConfig(t, "refresh-basic")
|
||||||
|
@ -158,6 +366,79 @@ func testContext(t *testing.T, opts *ContextOpts) *Context {
|
||||||
return NewContext(opts)
|
return NewContext(opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testDiffFn(
|
||||||
|
s *ResourceState,
|
||||||
|
c *ResourceConfig) (*ResourceDiff, error) {
|
||||||
|
var diff ResourceDiff
|
||||||
|
diff.Attributes = make(map[string]*ResourceAttrDiff)
|
||||||
|
diff.Attributes["type"] = &ResourceAttrDiff{
|
||||||
|
Old: "",
|
||||||
|
New: s.Type,
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v := range c.Raw {
|
||||||
|
if _, ok := v.(string); !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if k == "nil" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// This key is used for other purposes
|
||||||
|
if k == "compute_value" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if k == "compute" {
|
||||||
|
attrDiff := &ResourceAttrDiff{
|
||||||
|
Old: "",
|
||||||
|
New: "",
|
||||||
|
NewComputed: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
if cv, ok := c.Config["compute_value"]; ok {
|
||||||
|
if cv.(string) == "1" {
|
||||||
|
attrDiff.NewComputed = false
|
||||||
|
attrDiff.New = fmt.Sprintf("computed_%s", v.(string))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diff.Attributes[v.(string)] = attrDiff
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this key is not computed, then look it up in the
|
||||||
|
// cleaned config.
|
||||||
|
found := false
|
||||||
|
for _, ck := range c.ComputedKeys {
|
||||||
|
if ck == k {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
v = c.Config[k]
|
||||||
|
}
|
||||||
|
|
||||||
|
attrDiff := &ResourceAttrDiff{
|
||||||
|
Old: "",
|
||||||
|
New: v.(string),
|
||||||
|
}
|
||||||
|
|
||||||
|
diff.Attributes[k] = attrDiff
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, k := range c.ComputedKeys {
|
||||||
|
diff.Attributes[k] = &ResourceAttrDiff{
|
||||||
|
Old: "",
|
||||||
|
NewComputed: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &diff, nil
|
||||||
|
}
|
||||||
|
|
||||||
func testProvider(prefix string) *MockResourceProvider {
|
func testProvider(prefix string) *MockResourceProvider {
|
||||||
p := new(MockResourceProvider)
|
p := new(MockResourceProvider)
|
||||||
p.RefreshFn = func(s *ResourceState) (*ResourceState, error) {
|
p.RefreshFn = func(s *ResourceState) (*ResourceState, error) {
|
||||||
|
|
|
@ -442,173 +442,6 @@ func TestTerraformApply_vars(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTerraformPlan(t *testing.T) {
|
|
||||||
c := testConfig(t, "plan-good")
|
|
||||||
tf := testTerraform2(t, nil)
|
|
||||||
|
|
||||||
plan, err := tf.Plan(&PlanOpts{Config: c})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(plan.Diff.Resources) < 2 {
|
|
||||||
t.Fatalf("bad: %#v", plan.Diff.Resources)
|
|
||||||
}
|
|
||||||
|
|
||||||
actual := strings.TrimSpace(plan.String())
|
|
||||||
expected := strings.TrimSpace(testTerraformPlanStr)
|
|
||||||
if actual != expected {
|
|
||||||
t.Fatalf("bad:\n%s", actual)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTerraformPlan_nil(t *testing.T) {
|
|
||||||
c := testConfig(t, "plan-nil")
|
|
||||||
tf := testTerraform2(t, nil)
|
|
||||||
|
|
||||||
plan, err := tf.Plan(&PlanOpts{Config: c})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
if len(plan.Diff.Resources) != 0 {
|
|
||||||
t.Fatalf("bad: %#v", plan.Diff.Resources)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTerraformPlan_computed(t *testing.T) {
|
|
||||||
c := testConfig(t, "plan-computed")
|
|
||||||
tf := testTerraform2(t, nil)
|
|
||||||
|
|
||||||
plan, err := tf.Plan(&PlanOpts{Config: c})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(plan.Diff.Resources) < 2 {
|
|
||||||
t.Fatalf("bad: %#v", plan.Diff.Resources)
|
|
||||||
}
|
|
||||||
|
|
||||||
actual := strings.TrimSpace(plan.String())
|
|
||||||
expected := strings.TrimSpace(testTerraformPlanComputedStr)
|
|
||||||
if actual != expected {
|
|
||||||
t.Fatalf("bad:\n%s", actual)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTerraformPlan_destroy(t *testing.T) {
|
|
||||||
c := testConfig(t, "plan-destroy")
|
|
||||||
tf := testTerraform2(t, nil)
|
|
||||||
|
|
||||||
s := &State{
|
|
||||||
Resources: map[string]*ResourceState{
|
|
||||||
"aws_instance.one": &ResourceState{
|
|
||||||
ID: "bar",
|
|
||||||
Type: "aws_instance",
|
|
||||||
},
|
|
||||||
"aws_instance.two": &ResourceState{
|
|
||||||
ID: "baz",
|
|
||||||
Type: "aws_instance",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
plan, err := tf.Plan(&PlanOpts{
|
|
||||||
Destroy: true,
|
|
||||||
Config: c,
|
|
||||||
State: s,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(plan.Diff.Resources) != 2 {
|
|
||||||
t.Fatalf("bad: %#v", plan.Diff.Resources)
|
|
||||||
}
|
|
||||||
|
|
||||||
actual := strings.TrimSpace(plan.String())
|
|
||||||
expected := strings.TrimSpace(testTerraformPlanDestroyStr)
|
|
||||||
if actual != expected {
|
|
||||||
t.Fatalf("bad:\n%s", actual)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTerraformPlan_hook(t *testing.T) {
|
|
||||||
c := testConfig(t, "plan-good")
|
|
||||||
h := new(MockHook)
|
|
||||||
tf := testTerraform2(t, &Config{
|
|
||||||
Hooks: []Hook{h},
|
|
||||||
})
|
|
||||||
|
|
||||||
if _, err := tf.Plan(&PlanOpts{Config: c}); err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
if !h.PreDiffCalled {
|
|
||||||
t.Fatal("should be called")
|
|
||||||
}
|
|
||||||
if !h.PostDiffCalled {
|
|
||||||
t.Fatal("should be called")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTerraformPlan_orphan(t *testing.T) {
|
|
||||||
c := testConfig(t, "plan-orphan")
|
|
||||||
tf := testTerraform2(t, nil)
|
|
||||||
|
|
||||||
s := &State{
|
|
||||||
Resources: map[string]*ResourceState{
|
|
||||||
"aws_instance.baz": &ResourceState{
|
|
||||||
ID: "bar",
|
|
||||||
Type: "aws_instance",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
plan, err := tf.Plan(&PlanOpts{
|
|
||||||
Config: c,
|
|
||||||
State: s,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
actual := strings.TrimSpace(plan.String())
|
|
||||||
expected := strings.TrimSpace(testTerraformPlanOrphanStr)
|
|
||||||
if actual != expected {
|
|
||||||
t.Fatalf("bad:\n%s", actual)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTerraformPlan_state(t *testing.T) {
|
|
||||||
c := testConfig(t, "plan-good")
|
|
||||||
tf := testTerraform2(t, nil)
|
|
||||||
|
|
||||||
s := &State{
|
|
||||||
Resources: map[string]*ResourceState{
|
|
||||||
"aws_instance.foo": &ResourceState{
|
|
||||||
ID: "bar",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
plan, err := tf.Plan(&PlanOpts{
|
|
||||||
Config: c,
|
|
||||||
State: s,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(plan.Diff.Resources) < 2 {
|
|
||||||
t.Fatalf("bad: %#v", plan.Diff.Resources)
|
|
||||||
}
|
|
||||||
|
|
||||||
actual := strings.TrimSpace(plan.String())
|
|
||||||
expected := strings.TrimSpace(testTerraformPlanStateStr)
|
|
||||||
if actual != expected {
|
|
||||||
t.Fatalf("bad:\n%s", actual)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTerraformRefresh(t *testing.T) {
|
func TestTerraformRefresh(t *testing.T) {
|
||||||
rpAWS := new(MockResourceProvider)
|
rpAWS := new(MockResourceProvider)
|
||||||
rpAWS.ResourcesReturn = []ResourceType{
|
rpAWS.ResourcesReturn = []ResourceType{
|
||||||
|
|
Loading…
Reference in New Issue