Remove 0 counts from flatmap during MergeDiff

When a InstanceState is merged with an InstanceDiff, any maps arrays or
sets that no longer exist are shown as empty with a count of 0. If these
are left in the flatmap structure, they will cause errors during
expansion because their existing in the map affects the counts for
parent structures.
This commit is contained in:
James Bardin 2017-01-17 15:41:57 -05:00
parent 6ac39683ec
commit 2820845f8c
2 changed files with 70 additions and 0 deletions

View File

@ -9,6 +9,7 @@ import (
"io/ioutil"
"log"
"reflect"
"regexp"
"sort"
"strconv"
"strings"
@ -1664,6 +1665,25 @@ func (s *InstanceState) MergeDiff(d *InstanceDiff) *InstanceState {
}
}
// Remove any now empty array, maps or sets because a parent structure
// won't include these entries in the count value.
isCount := regexp.MustCompile(`\.[%#]$`).MatchString
for k, v := range result.Attributes {
if isCount(k) && v == "0" {
delete(result.Attributes, k)
// Sanity check for invalid structures.
// If we removed the primary count key, there should have been no
// other keys left with this prefix.
base := k[:len(k)-2]
for k, _ := range result.Attributes {
if strings.HasPrefix(k, base) {
panic(fmt.Sprintf("empty structure %q has entry %q", base, k))
}
}
}
}
return result
}

View File

@ -1392,6 +1392,56 @@ func TestInstanceState_MergeDiff(t *testing.T) {
}
}
// Make sure we don't leave empty maps or arrays in the flatmapped Attributes,
// since those may affect the counts of a parent structure.
func TestInstanceState_MergeDiffRemoveCounts(t *testing.T) {
is := InstanceState{
ID: "foo",
Attributes: map[string]string{
"all.#": "3",
"all.1111": "x",
"all.1234.#": "1",
"all.1234.0": "a",
"all.5678.%": "1",
"all.5678.key": "val",
},
}
diff := &InstanceDiff{
Attributes: map[string]*ResourceAttrDiff{
"all.#": &ResourceAttrDiff{
Old: "3",
New: "1",
},
"all.1234.0": &ResourceAttrDiff{
NewRemoved: true,
},
"all.1234.#": &ResourceAttrDiff{
Old: "1",
New: "0",
},
"all.5678.key": &ResourceAttrDiff{
NewRemoved: true,
},
"all.5678.%": &ResourceAttrDiff{
Old: "1",
New: "0",
},
},
}
is2 := is.MergeDiff(diff)
expected := map[string]string{
"all.#": "1",
"all.1111": "x",
}
if !reflect.DeepEqual(expected, is2.Attributes) {
t.Fatalf("bad: %#v", is2.Attributes)
}
}
func TestInstanceState_MergeDiff_nil(t *testing.T) {
var is *InstanceState