Merge pull request #14868 from hashicorp/jbardin/GH-14792

Check for nil/empty diff in CountHook.PreApply
This commit is contained in:
James Bardin 2017-05-26 15:20:03 -04:00 committed by GitHub
commit 46be301806
5 changed files with 4 additions and 385 deletions

View File

@ -42,6 +42,10 @@ func (h *CountHook) PreApply(
h.Lock() h.Lock()
defer h.Unlock() defer h.Unlock()
if d.Empty() {
return terraform.HookActionContinue, nil
}
if h.pending == nil { if h.pending == nil {
h.pending = make(map[string]countHookAction) h.pending = make(map[string]countHookAction)
} }

View File

@ -1,16 +0,0 @@
// Code generated by "stringer -type=countHookAction hook_count_action.go"; DO NOT EDIT.
package command
import "fmt"
const _countHookAction_name = "countHookActionAddcountHookActionChangecountHookActionRemove"
var _countHookAction_index = [...]uint8{0, 18, 39, 60}
func (i countHookAction) String() string {
if i >= countHookAction(len(_countHookAction_index)-1) {
return fmt.Sprintf("countHookAction(%d)", i)
}
return _countHookAction_name[_countHookAction_index[i]:_countHookAction_index[i+1]]
}

View File

@ -1,115 +0,0 @@
package command
import (
"strings"
"sync"
"github.com/hashicorp/terraform/terraform"
)
// CountHook is a hook that counts the number of resources
// added, removed, changed during the course of an apply.
type CountHook struct {
Added int
Changed int
Removed int
ToAdd int
ToChange int
ToRemove int
ToRemoveAndAdd int
pending map[string]countHookAction
sync.Mutex
terraform.NilHook
}
func (h *CountHook) Reset() {
h.Lock()
defer h.Unlock()
h.pending = nil
h.Added = 0
h.Changed = 0
h.Removed = 0
}
func (h *CountHook) PreApply(
n *terraform.InstanceInfo,
s *terraform.InstanceState,
d *terraform.InstanceDiff) (terraform.HookAction, error) {
h.Lock()
defer h.Unlock()
if d.Empty() {
return terraform.HookActionContinue, nil
}
if h.pending == nil {
h.pending = make(map[string]countHookAction)
}
action := countHookActionChange
if d.GetDestroy() {
action = countHookActionRemove
} else if s.ID == "" {
action = countHookActionAdd
}
h.pending[n.HumanId()] = action
return terraform.HookActionContinue, nil
}
func (h *CountHook) PostApply(
n *terraform.InstanceInfo,
s *terraform.InstanceState,
e error) (terraform.HookAction, error) {
h.Lock()
defer h.Unlock()
if h.pending != nil {
if a, ok := h.pending[n.HumanId()]; ok {
delete(h.pending, n.HumanId())
if e == nil {
switch a {
case countHookActionAdd:
h.Added += 1
case countHookActionChange:
h.Changed += 1
case countHookActionRemove:
h.Removed += 1
}
}
}
}
return terraform.HookActionContinue, nil
}
func (h *CountHook) PostDiff(
n *terraform.InstanceInfo, d *terraform.InstanceDiff) (
terraform.HookAction, error) {
h.Lock()
defer h.Unlock()
// We don't count anything for data sources
if strings.HasPrefix(n.Id, "data.") {
return terraform.HookActionContinue, nil
}
switch d.ChangeType() {
case terraform.DiffDestroyCreate:
h.ToRemoveAndAdd += 1
case terraform.DiffCreate:
h.ToAdd += 1
case terraform.DiffDestroy:
h.ToRemove += 1
case terraform.DiffUpdate:
h.ToChange += 1
}
return terraform.HookActionContinue, nil
}

View File

@ -1,11 +0,0 @@
package command
//go:generate stringer -type=countHookAction hook_count_action.go
type countHookAction byte
const (
countHookActionAdd countHookAction = iota
countHookActionChange
countHookActionRemove
)

View File

@ -1,243 +0,0 @@
package command
import (
"reflect"
"testing"
"github.com/hashicorp/terraform/terraform"
)
func TestCountHook_impl(t *testing.T) {
var _ terraform.Hook = new(CountHook)
}
func TestCountHookPostDiff_DestroyDeposed(t *testing.T) {
h := new(CountHook)
resources := map[string]*terraform.InstanceDiff{
"lorem": &terraform.InstanceDiff{DestroyDeposed: true},
}
n := &terraform.InstanceInfo{} // TODO
for _, d := range resources {
h.PostDiff(n, d)
}
expected := new(CountHook)
expected.ToAdd = 0
expected.ToChange = 0
expected.ToRemoveAndAdd = 0
expected.ToRemove = 1
if !reflect.DeepEqual(expected, h) {
t.Fatalf("Expected %#v, got %#v instead.",
expected, h)
}
}
func TestCountHookPostDiff_DestroyOnly(t *testing.T) {
h := new(CountHook)
resources := map[string]*terraform.InstanceDiff{
"foo": &terraform.InstanceDiff{Destroy: true},
"bar": &terraform.InstanceDiff{Destroy: true},
"lorem": &terraform.InstanceDiff{Destroy: true},
"ipsum": &terraform.InstanceDiff{Destroy: true},
}
n := &terraform.InstanceInfo{} // TODO
for _, d := range resources {
h.PostDiff(n, d)
}
expected := new(CountHook)
expected.ToAdd = 0
expected.ToChange = 0
expected.ToRemoveAndAdd = 0
expected.ToRemove = 4
if !reflect.DeepEqual(expected, h) {
t.Fatalf("Expected %#v, got %#v instead.",
expected, h)
}
}
func TestCountHookPostDiff_AddOnly(t *testing.T) {
h := new(CountHook)
resources := map[string]*terraform.InstanceDiff{
"foo": &terraform.InstanceDiff{
Attributes: map[string]*terraform.ResourceAttrDiff{
"foo": &terraform.ResourceAttrDiff{RequiresNew: true},
},
},
"bar": &terraform.InstanceDiff{
Attributes: map[string]*terraform.ResourceAttrDiff{
"foo": &terraform.ResourceAttrDiff{RequiresNew: true},
},
},
"lorem": &terraform.InstanceDiff{
Attributes: map[string]*terraform.ResourceAttrDiff{
"foo": &terraform.ResourceAttrDiff{RequiresNew: true},
},
},
}
n := &terraform.InstanceInfo{}
for _, d := range resources {
h.PostDiff(n, d)
}
expected := new(CountHook)
expected.ToAdd = 3
expected.ToChange = 0
expected.ToRemoveAndAdd = 0
expected.ToRemove = 0
if !reflect.DeepEqual(expected, h) {
t.Fatalf("Expected %#v, got %#v instead.",
expected, h)
}
}
func TestCountHookPostDiff_ChangeOnly(t *testing.T) {
h := new(CountHook)
resources := map[string]*terraform.InstanceDiff{
"foo": &terraform.InstanceDiff{
Destroy: false,
Attributes: map[string]*terraform.ResourceAttrDiff{
"foo": &terraform.ResourceAttrDiff{},
},
},
"bar": &terraform.InstanceDiff{
Destroy: false,
Attributes: map[string]*terraform.ResourceAttrDiff{
"foo": &terraform.ResourceAttrDiff{},
},
},
"lorem": &terraform.InstanceDiff{
Destroy: false,
Attributes: map[string]*terraform.ResourceAttrDiff{
"foo": &terraform.ResourceAttrDiff{},
},
},
}
n := &terraform.InstanceInfo{}
for _, d := range resources {
h.PostDiff(n, d)
}
expected := new(CountHook)
expected.ToAdd = 0
expected.ToChange = 3
expected.ToRemoveAndAdd = 0
expected.ToRemove = 0
if !reflect.DeepEqual(expected, h) {
t.Fatalf("Expected %#v, got %#v instead.",
expected, h)
}
}
func TestCountHookPostDiff_Mixed(t *testing.T) {
h := new(CountHook)
resources := map[string]*terraform.InstanceDiff{
"foo": &terraform.InstanceDiff{
Destroy: true,
},
"bar": &terraform.InstanceDiff{},
"lorem": &terraform.InstanceDiff{
Destroy: false,
Attributes: map[string]*terraform.ResourceAttrDiff{
"foo": &terraform.ResourceAttrDiff{},
},
},
"ipsum": &terraform.InstanceDiff{Destroy: true},
}
n := &terraform.InstanceInfo{}
for _, d := range resources {
h.PostDiff(n, d)
}
expected := new(CountHook)
expected.ToAdd = 0
expected.ToChange = 1
expected.ToRemoveAndAdd = 0
expected.ToRemove = 2
if !reflect.DeepEqual(expected, h) {
t.Fatalf("Expected %#v, got %#v instead.",
expected, h)
}
}
func TestCountHookPostDiff_NoChange(t *testing.T) {
h := new(CountHook)
resources := map[string]*terraform.InstanceDiff{
"foo": &terraform.InstanceDiff{},
"bar": &terraform.InstanceDiff{},
"lorem": &terraform.InstanceDiff{},
"ipsum": &terraform.InstanceDiff{},
}
n := &terraform.InstanceInfo{}
for _, d := range resources {
h.PostDiff(n, d)
}
expected := new(CountHook)
expected.ToAdd = 0
expected.ToChange = 0
expected.ToRemoveAndAdd = 0
expected.ToRemove = 0
if !reflect.DeepEqual(expected, h) {
t.Fatalf("Expected %#v, got %#v instead.",
expected, h)
}
}
func TestCountHookPostDiff_DataSource(t *testing.T) {
h := new(CountHook)
resources := map[string]*terraform.InstanceDiff{
"data.foo": &terraform.InstanceDiff{
Destroy: true,
},
"data.bar": &terraform.InstanceDiff{},
"data.lorem": &terraform.InstanceDiff{
Destroy: false,
Attributes: map[string]*terraform.ResourceAttrDiff{
"foo": &terraform.ResourceAttrDiff{},
},
},
"data.ipsum": &terraform.InstanceDiff{Destroy: true},
}
for k, d := range resources {
n := &terraform.InstanceInfo{Id: k}
h.PostDiff(n, d)
}
expected := new(CountHook)
expected.ToAdd = 0
expected.ToChange = 0
expected.ToRemoveAndAdd = 0
expected.ToRemove = 0
if !reflect.DeepEqual(expected, h) {
t.Fatalf("Expected %#v, got %#v instead.",
expected, h)
}
}