mirror of
https://github.com/opentofu/opentofu.git
synced 2025-01-02 04:07:22 -06:00
797 lines
15 KiB
Go
797 lines
15 KiB
Go
package terraform
|
|
|
|
import (
|
|
"fmt"
|
|
"path/filepath"
|
|
"reflect"
|
|
"strings"
|
|
"sync"
|
|
"testing"
|
|
|
|
"github.com/hashicorp/terraform/config"
|
|
)
|
|
|
|
// This is the directory where our test fixtures are.
|
|
const fixtureDir = "./test-fixtures"
|
|
|
|
func TestTerraformApply(t *testing.T) {
|
|
c := testConfig(t, "apply-good")
|
|
tf := testTerraform2(t, nil)
|
|
|
|
p, err := tf.Plan(&PlanOpts{Config: c})
|
|
if err != nil {
|
|
t.Fatalf("err: %s", err)
|
|
}
|
|
|
|
state, err := tf.Apply(p)
|
|
if err != nil {
|
|
t.Fatalf("err: %s", err)
|
|
}
|
|
|
|
if len(state.Resources) < 2 {
|
|
t.Fatalf("bad: %#v", state.Resources)
|
|
}
|
|
|
|
actual := strings.TrimSpace(state.String())
|
|
expected := strings.TrimSpace(testTerraformApplyStr)
|
|
if actual != expected {
|
|
t.Fatalf("bad: \n%s", actual)
|
|
}
|
|
}
|
|
|
|
func TestTerraformApply_compute(t *testing.T) {
|
|
// This tests that computed variables are properly re-diffed
|
|
// to get the value prior to application (Apply).
|
|
c := testConfig(t, "apply-compute")
|
|
tf := testTerraform2(t, nil)
|
|
|
|
p, err := tf.Plan(&PlanOpts{Config: c})
|
|
if err != nil {
|
|
t.Fatalf("err: %s", err)
|
|
}
|
|
|
|
p.Vars["value"] = "1"
|
|
|
|
state, err := tf.Apply(p)
|
|
if err != nil {
|
|
t.Fatalf("err: %s", err)
|
|
}
|
|
|
|
actual := strings.TrimSpace(state.String())
|
|
expected := strings.TrimSpace(testTerraformApplyComputeStr)
|
|
if actual != expected {
|
|
t.Fatalf("bad: \n%s", actual)
|
|
}
|
|
}
|
|
|
|
func TestTerraformApply_destroy(t *testing.T) {
|
|
h := new(HookRecordApplyOrder)
|
|
|
|
// First, apply the good configuration, build it
|
|
c := testConfig(t, "apply-destroy")
|
|
tf := testTerraform2(t, &Config{
|
|
Hooks: []Hook{h},
|
|
})
|
|
|
|
p, err := tf.Plan(&PlanOpts{Config: c})
|
|
if err != nil {
|
|
t.Fatalf("err: %s", err)
|
|
}
|
|
|
|
state, err := tf.Apply(p)
|
|
if err != nil {
|
|
t.Fatalf("err: %s", err)
|
|
}
|
|
|
|
// Next, plan and apply a destroy operation
|
|
p, err = tf.Plan(&PlanOpts{
|
|
Config: new(config.Config),
|
|
State: state,
|
|
Destroy: true,
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("err: %s", err)
|
|
}
|
|
|
|
h.Active = true
|
|
|
|
state, err = tf.Apply(p)
|
|
if err != nil {
|
|
t.Fatalf("err: %s", err)
|
|
}
|
|
|
|
// Test that things were destroyed
|
|
actual := strings.TrimSpace(state.String())
|
|
expected := strings.TrimSpace(testTerraformApplyDestroyStr)
|
|
if actual != expected {
|
|
t.Fatalf("bad: \n%s", actual)
|
|
}
|
|
|
|
// Test that things were destroyed _in the right order_
|
|
expected2 := []string{"aws_instance.bar", "aws_instance.foo"}
|
|
actual2 := h.IDs
|
|
if !reflect.DeepEqual(actual2, expected2) {
|
|
t.Fatalf("bad: %#v", actual2)
|
|
}
|
|
}
|
|
|
|
func TestTerraformApply_hook(t *testing.T) {
|
|
c := testConfig(t, "apply-good")
|
|
h := new(MockHook)
|
|
tf := testTerraform2(t, &Config{
|
|
Hooks: []Hook{h},
|
|
})
|
|
|
|
p, err := tf.Plan(&PlanOpts{Config: c})
|
|
if err != nil {
|
|
t.Fatalf("err: %s", err)
|
|
}
|
|
|
|
if _, err := tf.Apply(p); err != nil {
|
|
t.Fatalf("err: %s", err)
|
|
}
|
|
|
|
if !h.PreApplyCalled {
|
|
t.Fatal("should be called")
|
|
}
|
|
if !h.PostApplyCalled {
|
|
t.Fatal("should be called")
|
|
}
|
|
}
|
|
|
|
func TestTerraformApply_unknownAttribute(t *testing.T) {
|
|
c := testConfig(t, "apply-unknown")
|
|
tf := testTerraform2(t, nil)
|
|
|
|
p, err := tf.Plan(&PlanOpts{Config: c})
|
|
if err != nil {
|
|
t.Fatalf("err: %s", err)
|
|
}
|
|
|
|
state, err := tf.Apply(p)
|
|
if err == nil {
|
|
t.Fatal("should error")
|
|
}
|
|
|
|
actual := strings.TrimSpace(state.String())
|
|
expected := strings.TrimSpace(testTerraformApplyUnknownAttrStr)
|
|
if actual != expected {
|
|
t.Fatalf("bad: \n%s", actual)
|
|
}
|
|
}
|
|
|
|
func TestTerraformApply_vars(t *testing.T) {
|
|
c := testConfig(t, "apply-vars")
|
|
tf := testTerraform2(t, nil)
|
|
|
|
p, err := tf.Plan(&PlanOpts{
|
|
Config: c,
|
|
Vars: map[string]string{"foo": "baz"},
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("err: %s", err)
|
|
}
|
|
|
|
// Explicitly set the "foo" variable
|
|
p.Vars["foo"] = "bar"
|
|
|
|
state, err := tf.Apply(p)
|
|
if err != nil {
|
|
t.Fatalf("err: %s", err)
|
|
}
|
|
|
|
actual := strings.TrimSpace(state.String())
|
|
expected := strings.TrimSpace(testTerraformApplyVarsStr)
|
|
if actual != expected {
|
|
t.Fatalf("bad: \n%s", actual)
|
|
}
|
|
}
|
|
|
|
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) {
|
|
rpAWS := new(MockResourceProvider)
|
|
rpAWS.ResourcesReturn = []ResourceType{
|
|
ResourceType{Name: "aws_instance"},
|
|
}
|
|
|
|
c := testConfig(t, "refresh-basic")
|
|
tf := testTerraform2(t, &Config{
|
|
Providers: map[string]ResourceProviderFactory{
|
|
"aws": testProviderFuncFixed(rpAWS),
|
|
},
|
|
})
|
|
|
|
rpAWS.RefreshReturn = &ResourceState{
|
|
ID: "foo",
|
|
}
|
|
|
|
s, err := tf.Refresh(c, nil)
|
|
if err != nil {
|
|
t.Fatalf("err: %s", err)
|
|
}
|
|
if !rpAWS.RefreshCalled {
|
|
t.Fatal("refresh should be called")
|
|
}
|
|
if rpAWS.RefreshState.ID != "" {
|
|
t.Fatalf("bad: %#v", rpAWS.RefreshState)
|
|
}
|
|
if !reflect.DeepEqual(s.Resources["aws_instance.web"], rpAWS.RefreshReturn) {
|
|
t.Fatalf("bad: %#v", s.Resources)
|
|
}
|
|
|
|
for _, r := range s.Resources {
|
|
if r.Type == "" {
|
|
t.Fatalf("no type: %#v", r)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestTerraformRefresh_hook(t *testing.T) {
|
|
rpAWS := new(MockResourceProvider)
|
|
rpAWS.ResourcesReturn = []ResourceType{
|
|
ResourceType{Name: "aws_instance"},
|
|
}
|
|
|
|
h := new(MockHook)
|
|
|
|
c := testConfig(t, "refresh-basic")
|
|
tf := testTerraform2(t, &Config{
|
|
Hooks: []Hook{h},
|
|
Providers: map[string]ResourceProviderFactory{
|
|
"aws": testProviderFuncFixed(rpAWS),
|
|
},
|
|
})
|
|
|
|
if _, err := tf.Refresh(c, nil); err != nil {
|
|
t.Fatalf("err: %s", err)
|
|
}
|
|
if !h.PreRefreshCalled {
|
|
t.Fatal("should be called")
|
|
}
|
|
if h.PreRefreshState.Type != "aws_instance" {
|
|
t.Fatalf("bad: %#v", h.PreRefreshState)
|
|
}
|
|
if !h.PostRefreshCalled {
|
|
t.Fatal("should be called")
|
|
}
|
|
if h.PostRefreshState.Type != "aws_instance" {
|
|
t.Fatalf("bad: %#v", h.PostRefreshState)
|
|
}
|
|
}
|
|
|
|
func TestTerraformRefresh_state(t *testing.T) {
|
|
rpAWS := new(MockResourceProvider)
|
|
rpAWS.ResourcesReturn = []ResourceType{
|
|
ResourceType{Name: "aws_instance"},
|
|
}
|
|
|
|
c := testConfig(t, "refresh-basic")
|
|
tf := testTerraform2(t, &Config{
|
|
Providers: map[string]ResourceProviderFactory{
|
|
"aws": testProviderFuncFixed(rpAWS),
|
|
},
|
|
})
|
|
|
|
rpAWS.RefreshReturn = &ResourceState{
|
|
ID: "foo",
|
|
}
|
|
|
|
state := &State{
|
|
Resources: map[string]*ResourceState{
|
|
"aws_instance.web": &ResourceState{
|
|
ID: "bar",
|
|
},
|
|
},
|
|
}
|
|
|
|
s, err := tf.Refresh(c, state)
|
|
if err != nil {
|
|
t.Fatalf("err: %s", err)
|
|
}
|
|
if !rpAWS.RefreshCalled {
|
|
t.Fatal("refresh should be called")
|
|
}
|
|
if !reflect.DeepEqual(rpAWS.RefreshState, state.Resources["aws_instance.web"]) {
|
|
t.Fatalf("bad: %#v", rpAWS.RefreshState)
|
|
}
|
|
if !reflect.DeepEqual(s.Resources["aws_instance.web"], rpAWS.RefreshReturn) {
|
|
t.Fatalf("bad: %#v", s.Resources)
|
|
}
|
|
}
|
|
|
|
func testConfig(t *testing.T, name string) *config.Config {
|
|
c, err := config.Load(filepath.Join(fixtureDir, name, "main.tf"))
|
|
if err != nil {
|
|
t.Fatalf("err: %s", err)
|
|
}
|
|
|
|
return c
|
|
}
|
|
|
|
func testProviderFunc(n string, rs []string) ResourceProviderFactory {
|
|
resources := make([]ResourceType, len(rs))
|
|
for i, v := range rs {
|
|
resources[i] = ResourceType{
|
|
Name: v,
|
|
}
|
|
}
|
|
|
|
return func() (ResourceProvider, error) {
|
|
p := &MockResourceProvider{Meta: n}
|
|
|
|
applyFn := func(
|
|
s *ResourceState,
|
|
d *ResourceDiff) (*ResourceState, error) {
|
|
if d.Destroy {
|
|
return nil, nil
|
|
}
|
|
|
|
id := "foo"
|
|
if idAttr, ok := d.Attributes["id"]; ok && !idAttr.NewComputed {
|
|
id = idAttr.New
|
|
}
|
|
|
|
result := &ResourceState{
|
|
ID: id,
|
|
}
|
|
|
|
if d != nil {
|
|
result = result.MergeDiff(d)
|
|
}
|
|
|
|
if depAttr, ok := d.Attributes["dep"]; ok {
|
|
result.Dependencies = []ResourceDependency{
|
|
ResourceDependency{
|
|
ID: depAttr.New,
|
|
},
|
|
}
|
|
}
|
|
|
|
return result, nil
|
|
}
|
|
|
|
diffFn := func(
|
|
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
|
|
}
|
|
|
|
refreshFn := func(s *ResourceState) (*ResourceState, error) {
|
|
if _, ok := s.Attributes["nil"]; ok {
|
|
return nil, nil
|
|
}
|
|
|
|
return s, nil
|
|
}
|
|
|
|
p.ApplyFn = applyFn
|
|
p.DiffFn = diffFn
|
|
p.RefreshFn = refreshFn
|
|
p.ResourcesReturn = resources
|
|
|
|
return p, nil
|
|
}
|
|
}
|
|
|
|
func testProviderFuncFixed(rp ResourceProvider) ResourceProviderFactory {
|
|
return func() (ResourceProvider, error) {
|
|
return rp, nil
|
|
}
|
|
}
|
|
|
|
func testProviderMock(p ResourceProvider) *MockResourceProvider {
|
|
return p.(*MockResourceProvider)
|
|
}
|
|
|
|
func testTerraform2(t *testing.T, c *Config) *Terraform {
|
|
if c == nil {
|
|
c = new(Config)
|
|
}
|
|
|
|
if c.Providers == nil {
|
|
c.Providers = map[string]ResourceProviderFactory{
|
|
"aws": testProviderFunc("aws", []string{"aws_instance"}),
|
|
"do": testProviderFunc("do", []string{"do_droplet"}),
|
|
}
|
|
}
|
|
|
|
tf, err := New(c)
|
|
if err != nil {
|
|
t.Fatalf("err: %s", err)
|
|
}
|
|
if tf == nil {
|
|
t.Fatal("tf should not be nil")
|
|
}
|
|
|
|
return tf
|
|
}
|
|
|
|
// HookRecordApplyOrder is a test hook that records the order of applies
|
|
// by recording the PreApply event.
|
|
type HookRecordApplyOrder struct {
|
|
NilHook
|
|
|
|
Active bool
|
|
|
|
IDs []string
|
|
States []*ResourceState
|
|
Diffs []*ResourceDiff
|
|
|
|
l sync.Mutex
|
|
}
|
|
|
|
func (h *HookRecordApplyOrder) PreApply(
|
|
id string,
|
|
s *ResourceState,
|
|
d *ResourceDiff) (HookAction, error) {
|
|
if h.Active {
|
|
h.l.Lock()
|
|
defer h.l.Unlock()
|
|
|
|
h.IDs = append(h.IDs, id)
|
|
h.Diffs = append(h.Diffs, d)
|
|
h.States = append(h.States, s)
|
|
}
|
|
|
|
return HookActionContinue, nil
|
|
}
|
|
|
|
// Below are all the constant strings that are the expected output for
|
|
// various tests.
|
|
|
|
const testTerraformApplyStr = `
|
|
aws_instance.bar:
|
|
ID = foo
|
|
type = aws_instance
|
|
foo = bar
|
|
aws_instance.foo:
|
|
ID = foo
|
|
type = aws_instance
|
|
num = 2
|
|
`
|
|
|
|
const testTerraformApplyComputeStr = `
|
|
aws_instance.bar:
|
|
ID = foo
|
|
type = aws_instance
|
|
foo = computed_dynamical
|
|
aws_instance.foo:
|
|
ID = foo
|
|
type = aws_instance
|
|
num = 2
|
|
dynamical = computed_dynamical
|
|
`
|
|
|
|
const testTerraformApplyDestroyStr = `
|
|
aws_instance.bar:
|
|
ID = <not created>
|
|
aws_instance.foo:
|
|
ID = <not created>
|
|
`
|
|
|
|
const testTerraformApplyUnknownAttrStr = `
|
|
aws_instance.foo:
|
|
ID = foo
|
|
type = aws_instance
|
|
num = 2
|
|
`
|
|
|
|
const testTerraformApplyVarsStr = `
|
|
aws_instance.bar:
|
|
ID = foo
|
|
type = aws_instance
|
|
foo = bar
|
|
aws_instance.foo:
|
|
ID = foo
|
|
type = aws_instance
|
|
num = 2
|
|
`
|
|
|
|
const testTerraformPlanStr = `
|
|
DIFF:
|
|
|
|
UPDATE: aws_instance.bar
|
|
foo: "" => "2"
|
|
type: "" => "aws_instance"
|
|
UPDATE: aws_instance.foo
|
|
num: "" => "2"
|
|
type: "" => "aws_instance"
|
|
|
|
STATE:
|
|
|
|
<no state>
|
|
`
|
|
|
|
const testTerraformPlanComputedStr = `
|
|
DIFF:
|
|
|
|
UPDATE: aws_instance.bar
|
|
foo: "" => "<computed>"
|
|
type: "" => "aws_instance"
|
|
UPDATE: aws_instance.foo
|
|
id: "" => "<computed>"
|
|
num: "" => "2"
|
|
type: "" => "aws_instance"
|
|
|
|
STATE:
|
|
|
|
<no state>
|
|
`
|
|
|
|
const testTerraformPlanDestroyStr = `
|
|
DIFF:
|
|
|
|
DESTROY: aws_instance.one
|
|
DESTROY: aws_instance.two
|
|
|
|
STATE:
|
|
|
|
aws_instance.one:
|
|
ID = bar
|
|
aws_instance.two:
|
|
ID = baz
|
|
`
|
|
|
|
const testTerraformPlanOrphanStr = `
|
|
DIFF:
|
|
|
|
DESTROY: aws_instance.baz
|
|
UPDATE: aws_instance.foo
|
|
num: "" => "2"
|
|
type: "" => "aws_instance"
|
|
|
|
STATE:
|
|
|
|
aws_instance.baz:
|
|
ID = bar
|
|
`
|
|
|
|
const testTerraformPlanStateStr = `
|
|
DIFF:
|
|
|
|
UPDATE: aws_instance.bar
|
|
foo: "" => "2"
|
|
type: "" => "aws_instance"
|
|
UPDATE: aws_instance.foo
|
|
num: "" => "2"
|
|
type: "" => ""
|
|
|
|
STATE:
|
|
|
|
aws_instance.foo:
|
|
ID = bar
|
|
`
|