Merge pull request #20348 from hashicorp/jbardin/list-empty-strings

simple list diffs may also have missing elements
This commit is contained in:
James Bardin 2019-02-14 13:36:26 -05:00 committed by GitHub
commit fabdd0db3e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 121 additions and 5 deletions

View File

@ -171,7 +171,7 @@ func testResourceUpdate(d *schema.ResourceData, meta interface{}) error {
if errMsg != "" {
return errors.New(errMsg)
}
return nil
return testResourceRead(d, meta)
}
func testResourceDelete(d *schema.ResourceData, meta interface{}) error {

View File

@ -30,6 +30,13 @@ func testResourceList() *schema.Resource {
Optional: true,
ForceNew: true,
},
"sublist": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"sublist_block": {
Type: schema.TypeList,
Optional: true,

View File

@ -218,3 +218,61 @@ resource "test_resource_list" "foo" {
},
})
}
func TestResourceList_emptyStrings(t *testing.T) {
resource.UnitTest(t, resource.TestCase{
Providers: testAccProviders,
CheckDestroy: testAccCheckResourceDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: strings.TrimSpace(`
resource "test_resource_list" "foo" {
list_block {
sublist = ["a", ""]
}
list_block {
sublist = [""]
}
list_block {
sublist = ["", "c", ""]
}
}
`),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("test_resource_list.foo", "list_block.0.sublist.0", "a"),
resource.TestCheckResourceAttr("test_resource_list.foo", "list_block.0.sublist.1", ""),
resource.TestCheckResourceAttr("test_resource_list.foo", "list_block.1.sublist.0", ""),
resource.TestCheckResourceAttr("test_resource_list.foo", "list_block.2.sublist.0", ""),
resource.TestCheckResourceAttr("test_resource_list.foo", "list_block.2.sublist.1", "c"),
resource.TestCheckResourceAttr("test_resource_list.foo", "list_block.2.sublist.2", ""),
),
},
resource.TestStep{
Config: strings.TrimSpace(`
resource "test_resource_list" "foo" {
list_block {
sublist = [""]
}
list_block {
sublist = []
}
list_block {
sublist = ["", "c"]
}
}
`),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("test_resource_list.foo", "list_block.0.sublist.#", "1"),
resource.TestCheckResourceAttr("test_resource_list.foo", "list_block.0.sublist.0", ""),
resource.TestCheckResourceAttr("test_resource_list.foo", "list_block.1.sublist.#", "0"),
resource.TestCheckResourceAttr("test_resource_list.foo", "list_block.2.sublist.1", "c"),
resource.TestCheckResourceAttr("test_resource_list.foo", "list_block.2.sublist.#", "2"),
),
},
},
})
}

View File

@ -624,7 +624,7 @@ func (d *InstanceDiff) applyBlockDiff(path []string, attrs map[string]string, sc
if err != nil {
// this shouldn't happen since we added these
// ourself, but make note of it just in case.
log.Printf("[ERROR] bas list index in %q: %s", k, err)
log.Printf("[ERROR] bad list index in %q: %s", k, err)
continue
}
if i >= length {
@ -811,10 +811,61 @@ func (d *InstanceDiff) applyCollectionDiff(path []string, attrs map[string]strin
}
}
// Fill in the count value if it was missing for some reason:
if result[name+"."+idx] == "" {
result[name+"."+idx] = countFlatmapContainerValues(name+"."+idx, result)
// Just like in nested list blocks, for simple lists we may need to fill in
// missing empty strings.
countKey := name + "." + idx
count := result[countKey]
length, _ := strconv.Atoi(count)
if count != "" && count != hcl2shim.UnknownVariableValue &&
attrSchema.Type.Equals(cty.List(cty.String)) {
// insert empty strings into missing indexes
for i := 0; i < length; i++ {
key := fmt.Sprintf("%s.%d", name, i)
if _, ok := result[key]; !ok {
result[key] = ""
}
}
}
// now check for truncation in any type of list
if attrSchema.Type.IsListType() {
for key := range result {
if key == countKey {
continue
}
if len(key) <= len(name)+1 {
// not sure what this is, but don't panic
continue
}
index := key[len(name)+1:]
// It is possible to have nested sets or maps, so look for another dot
dot := strings.Index(index, ".")
if dot > 0 {
index = index[:dot]
}
// This shouldn't have any more dots, since the element type is only string.
num, err := strconv.Atoi(index)
if err != nil {
log.Printf("[ERROR] bad list index in %q: %s", currentKey, err)
continue
}
if num >= length {
delete(result, key)
}
}
}
// Fill in the count value if it was missing for some reason:
if result[countKey] == "" {
result[countKey] = countFlatmapContainerValues(countKey, result)
}
return result, nil
}