terraform: add ResourceState.Taint

This commit is contained in:
Mitchell Hashimoto 2015-02-26 09:58:56 -08:00
parent 341be226f4
commit b3cd1bd5bc
2 changed files with 73 additions and 5 deletions

View File

@ -699,6 +699,19 @@ func (s *ResourceState) Equal(other *ResourceState) bool {
return true
}
// Taint takes the primary state and marks it as tainted. If there is no
// primary state, this does nothing.
func (r *ResourceState) Taint() {
// If there is no primary, nothing to do
if r.Primary == nil {
return
}
// Shuffle to the end of the taint list and set primary to nil
r.Tainted = append(r.Tainted, r.Primary)
r.Primary = nil
}
func (r *ResourceState) init() {
if r.Primary == nil {
r.Primary = &InstanceState{}
@ -710,16 +723,24 @@ func (r *ResourceState) deepcopy() *ResourceState {
if r == nil {
return nil
}
n := &ResourceState{
Type: r.Type,
Dependencies: make([]string, len(r.Dependencies)),
Dependencies: nil,
Primary: r.Primary.deepcopy(),
Tainted: make([]*InstanceState, 0, len(r.Tainted)),
Tainted: nil,
}
copy(n.Dependencies, r.Dependencies)
for _, inst := range r.Tainted {
n.Tainted = append(n.Tainted, inst.deepcopy())
if r.Dependencies != nil {
n.Dependencies = make([]string, len(r.Dependencies))
copy(n.Dependencies, r.Dependencies)
}
if r.Tainted != nil {
n.Tainted = make([]*InstanceState, 0, len(r.Tainted))
for _, inst := range r.Tainted {
n.Tainted = append(n.Tainted, inst.deepcopy())
}
}
return n
}

View File

@ -275,6 +275,53 @@ func TestResourceStateEqual(t *testing.T) {
}
}
func TestResourceStateTaint(t *testing.T) {
cases := map[string]struct {
Input *ResourceState
Output *ResourceState
}{
"no primary": {
&ResourceState{},
&ResourceState{},
},
"primary, no tainted": {
&ResourceState{
Primary: &InstanceState{ID: "foo"},
},
&ResourceState{
Tainted: []*InstanceState{
&InstanceState{ID: "foo"},
},
},
},
"primary, with tainted": {
&ResourceState{
Primary: &InstanceState{ID: "foo"},
Tainted: []*InstanceState{
&InstanceState{ID: "bar"},
},
},
&ResourceState{
Tainted: []*InstanceState{
&InstanceState{ID: "bar"},
&InstanceState{ID: "foo"},
},
},
},
}
for k, tc := range cases {
tc.Input.Taint()
if !reflect.DeepEqual(tc.Input, tc.Output) {
t.Fatalf(
"Failure: %s\n\nExpected: %#v\n\nGot: %#v",
k, tc.Output, tc.Input)
}
}
}
func TestInstanceStateEqual(t *testing.T) {
cases := []struct {
Result bool