diff --git a/helper/schema/field_reader.go b/helper/schema/field_reader.go index 1ca721d1657c..c3a6c76fa08f 100644 --- a/helper/schema/field_reader.go +++ b/helper/schema/field_reader.go @@ -130,6 +130,60 @@ func addrToSchema(addr []string, schemaMap map[string]*Schema) []*Schema { return result } +// readListField is a generic method for reading a list field out of a +// a FieldReader. It does this based on the assumption that there is a key +// "foo.#" for a list "foo" and that the indexes are "foo.0", "foo.1", etc. +// after that point. +func readListField( + r FieldReader, addr []string, schema *Schema) (FieldReadResult, error) { + addrPadded := make([]string, len(addr)+1) + copy(addrPadded, addr) + addrPadded[len(addrPadded)-1] = "#" + + // Get the number of elements in the list + countResult, err := r.ReadField(addrPadded) + if err != nil { + return FieldReadResult{}, err + } + if !countResult.Exists { + // No count, means we have no list + countResult.Value = 0 + } + + // If we have an empty list, then return an empty list + if countResult.Computed || countResult.Value.(int) == 0 { + return FieldReadResult{ + Value: []interface{}{}, + Exists: countResult.Exists, + Computed: countResult.Computed, + }, nil + } + + // Go through each count, and get the item value out of it + result := make([]interface{}, countResult.Value.(int)) + for i, _ := range result { + is := strconv.FormatInt(int64(i), 10) + addrPadded[len(addrPadded)-1] = is + rawResult, err := r.ReadField(addrPadded) + if err != nil { + return FieldReadResult{}, err + } + if !rawResult.Exists { + // This should never happen, because by the time the data + // gets to the FieldReaders, all the defaults should be set by + // Schema. + rawResult.Value = nil + } + + result[i] = rawResult.Value + } + + return FieldReadResult{ + Value: result, + Exists: true, + }, nil +} + // readObjectField is a generic method for reading objects out of FieldReaders // based on the assumption that building an address of []string{k, FIELD} // will result in the proper field data. diff --git a/helper/schema/field_reader_config.go b/helper/schema/field_reader_config.go index c11dff795724..0d4c2a97c9bb 100644 --- a/helper/schema/field_reader_config.go +++ b/helper/schema/field_reader_config.go @@ -83,7 +83,7 @@ func (r *ConfigFieldReader) readField( case TypeBool, TypeFloat, TypeInt, TypeString: return r.readPrimitive(k, schema) case TypeList: - return r.readList(address, schema) + return readListField(&nestedConfigFieldReader{r}, address, schema) case TypeMap: return r.readMap(k) case TypeSet: @@ -216,65 +216,13 @@ func (r *ConfigFieldReader) readPrimitive( }, nil } -func (r *ConfigFieldReader) readList( - address []string, schema *Schema) (FieldReadResult, error) { - - addrPadded := make([]string, len(address)+1) - copy(addrPadded, address) - - // Get the number of elements in the list - addrPadded[len(addrPadded)-1] = "#" - countResult, err := r.readPrimitive( - strings.Join(addrPadded, "."), &Schema{Type: TypeInt}) - if err != nil { - return FieldReadResult{}, err - } - if !countResult.Exists { - // No count, means we have no list - countResult.Value = 0 - } - - // If we have an empty list, then return an empty list - if countResult.Computed || countResult.Value.(int) == 0 { - return FieldReadResult{ - Value: []interface{}{}, - Exists: countResult.Exists, - Computed: countResult.Computed, - }, nil - } - - // Go through each count, and get the item value out of it - result := make([]interface{}, countResult.Value.(int)) - for i, _ := range result { - idx := strconv.Itoa(i) - addrPadded[len(addrPadded)-1] = idx - rawResult, err := r.readField(addrPadded, true) - if err != nil { - return FieldReadResult{}, err - } - if !rawResult.Exists { - // This should never happen, because by the time the data - // gets to the FieldReaders, all the defaults should be set by - // Schema. - panic("missing field in list: " + strings.Join(addrPadded, ".")) - } - - result[i] = rawResult.Value - } - - return FieldReadResult{ - Value: result, - Exists: true, - }, nil -} - func (r *ConfigFieldReader) readSet( address []string, schema *Schema) (FieldReadResult, error) { indexMap := make(map[string]int) // Create the set that will be our result set := schema.ZeroValue().(*Set) - raw, err := r.readList(address, schema) + raw, err := readListField(&nestedConfigFieldReader{r}, address, schema) if err != nil { return FieldReadResult{}, err } diff --git a/helper/schema/field_reader_diff.go b/helper/schema/field_reader_diff.go index 253e920488d9..661c5687c28b 100644 --- a/helper/schema/field_reader_diff.go +++ b/helper/schema/field_reader_diff.go @@ -2,8 +2,6 @@ package schema import ( "fmt" - "sort" - "strconv" "strings" "github.com/hashicorp/terraform/terraform" @@ -14,8 +12,8 @@ import ( // // It also requires access to a Reader that reads fields from the structure // that the diff was derived from. This is usually the state. This is required -// because a diff on its own doesn't have complete data about non-primitive -// objects such as maps, lists and sets. +// because a diff on its own doesn't have complete data about full objects +// such as maps. // // The Source MUST be the data that the diff was derived from. If it isn't, // the behavior of this struct is undefined. @@ -44,7 +42,7 @@ func (r *DiffFieldReader) ReadField(address []string) (FieldReadResult, error) { case TypeBool, TypeInt, TypeFloat, TypeString: return r.readPrimitive(address, schema) case TypeList: - return r.readList(address, schema) + return readListField(r, address, schema) case TypeMap: return r.readMap(address, schema) case TypeSet: @@ -59,7 +57,7 @@ func (r *DiffFieldReader) ReadField(address []string) (FieldReadResult, error) { func (r *DiffFieldReader) readMap( address []string, schema *Schema) (FieldReadResult, error) { result := make(map[string]interface{}) - exists := false + resultSet := false // First read the map from the underlying source source, err := r.Source.ReadField(address) @@ -68,7 +66,7 @@ func (r *DiffFieldReader) readMap( } if source.Exists { result = source.Value.(map[string]interface{}) - exists = true + resultSet = true } // Next, read all the elements we have in our diff, and apply @@ -83,7 +81,7 @@ func (r *DiffFieldReader) readMap( continue } - exists = true + resultSet = true k = k[len(prefix):] if v.NewRemoved { @@ -95,13 +93,13 @@ func (r *DiffFieldReader) readMap( } var resultVal interface{} - if exists { + if resultSet { resultVal = result } return FieldReadResult{ Value: resultVal, - Exists: exists, + Exists: resultSet, }, nil } @@ -138,99 +136,6 @@ func (r *DiffFieldReader) readPrimitive( return result, nil } -func (r *DiffFieldReader) readList( - address []string, schema *Schema) (FieldReadResult, error) { - prefix := strings.Join(address, ".") + "." - - addrPadded := make([]string, len(address)+1) - copy(addrPadded, address) - - // Get the number of elements in the list - addrPadded[len(addrPadded)-1] = "#" - countResult, err := r.readPrimitive(addrPadded, &Schema{Type: TypeInt}) - if err != nil { - return FieldReadResult{}, err - } - if !countResult.Exists { - // No count, means we have no list - countResult.Value = 0 - } - // If we have an empty list, then return an empty list - if countResult.Computed || countResult.Value.(int) == 0 { - return FieldReadResult{ - Value: []interface{}{}, - Exists: countResult.Exists, - Computed: countResult.Computed, - }, nil - } - - // Bail out if diff doesn't contain the given field at all - // This has to be a separate loop because we're only - // iterating over raw list items (list.idx). - // Other fields (list.idx.*) are left for other read* methods - // which can deal with these fields appropriately. - diffContainsField := false - for k, _ := range r.Diff.Attributes { - if strings.HasPrefix(k, address[0]+".") { - diffContainsField = true - } - } - if !diffContainsField { - return FieldReadResult{ - Value: []interface{}{}, - Exists: false, - }, nil - } - - // Create the list that will be our result - list := []interface{}{} - - // Go through the diff and find all the list items - // We are not iterating over the diff directly as some indexes - // may be missing and we expect the whole list to be returned. - for i := 0; i < countResult.Value.(int); i++ { - idx := strconv.Itoa(i) - addrString := prefix + idx - - d, ok := r.Diff.Attributes[addrString] - if ok && d.NewRemoved { - // If the field is being removed, we ignore it - continue - } - - addrPadded[len(addrPadded)-1] = idx - raw, err := r.ReadField(addrPadded) - if err != nil { - return FieldReadResult{}, err - } - if !raw.Exists { - // This should never happen, because by the time the data - // gets to the FieldReaders, all the defaults should be set by - // Schema. - panic("missing field in set: " + addrString + "." + idx) - } - list = append(list, raw.Value) - } - - // Determine if the list "exists". It exists if there are items or if - // the diff explicitly wanted it empty. - exists := len(list) > 0 - if !exists { - // We could check if the diff value is "0" here but I think the - // existence of "#" on its own is enough to show it existed. This - // protects us in the future from the zero value changing from - // "0" to "" breaking us (if that were to happen). - if _, ok := r.Diff.Attributes[prefix+"#"]; ok { - exists = true - } - } - - return FieldReadResult{ - Value: list, - Exists: exists, - }, nil -} - func (r *DiffFieldReader) readSet( address []string, schema *Schema) (FieldReadResult, error) { prefix := strings.Join(address, ".") + "." @@ -238,60 +143,10 @@ func (r *DiffFieldReader) readSet( // Create the set that will be our result set := schema.ZeroValue().(*Set) - // Check if we're supposed to remove it - v, ok := r.Diff.Attributes[prefix+"#"] - if ok && v.New == "0" { - // I'm not entirely sure what's the point of - // returning empty set w/ Exists: true - return FieldReadResult{ - Value: set, - Exists: true, - }, nil - } - - // Compose list of all keys (diff + source) - var keys []string - - // Add keys from diff - diffContainsField := false - for k, _ := range r.Diff.Attributes { - if strings.HasPrefix(k, address[0]+".") { - diffContainsField = true - } - keys = append(keys, k) - } - // Bail out if diff doesn't contain the given field at all - if !diffContainsField { - return FieldReadResult{ - Value: set, - Exists: false, - }, nil - } - // Add keys from source - sourceResult, err := r.Source.ReadField(address) - if err == nil && sourceResult.Exists { - sourceSet := sourceResult.Value.(*Set) - sourceMap := sourceSet.Map() - - for k, _ := range sourceMap { - key := prefix + k - _, ok := r.Diff.Attributes[key] - if !ok { - keys = append(keys, key) - } - } - } - - // Keep the order consistent for hashing functions - sort.Strings(keys) - // Go through the map and find all the set items - // We are not iterating over the diff directly as some indexes - // may be missing and we expect the whole set to be returned. - for _, k := range keys { - d, ok := r.Diff.Attributes[k] - if ok && d.NewRemoved { - // If the field is being removed, we ignore it + for k, d := range r.Diff.Attributes { + if d.NewRemoved { + // If the field is removed, we always ignore it continue } if !strings.HasPrefix(k, prefix) { diff --git a/helper/schema/field_reader_diff_test.go b/helper/schema/field_reader_diff_test.go index f01636c3f01a..cfd329492b9f 100644 --- a/helper/schema/field_reader_diff_test.go +++ b/helper/schema/field_reader_diff_test.go @@ -245,7 +245,7 @@ func TestDiffFieldReader_extra(t *testing.T) { out.Value = s.List() } if !reflect.DeepEqual(tc.Result, out) { - t.Fatalf("Case %q:\ngiven: %#v\nexpected: %#v", name, out, tc.Result) + t.Fatalf("%s: bad: %#v", name, out) } } } @@ -376,616 +376,3 @@ func TestDiffFieldReader(t *testing.T) { } }) } - -func TestDiffFieldReader_SetInSet(t *testing.T) { - schema := map[string]*Schema{ - "main_set": &Schema{ - Type: TypeSet, - Optional: true, - Elem: &Resource{ - Schema: map[string]*Schema{ - "inner_string_set": &Schema{ - Type: TypeSet, - Required: true, - Set: HashString, - Elem: &Schema{Type: TypeString}, - }, - "inner_int": &Schema{ - Type: TypeInt, - Required: true, - }, - }, - }, - }, - "main_int": &Schema{ - Type: TypeInt, - Optional: true, - }, - } - - var readers = make(map[string]FieldReader) - readers["state"] = &MapFieldReader{ - Schema: schema, - Map: BasicMapReader(map[string]string{ - "id": "8395051352714003426", - "main_int": "9", - "main_set.#": "1", - "main_set.2476980464.inner_string_set.#": "2", - "main_set.2476980464.inner_string_set.2654390964": "blue", - "main_set.2476980464.inner_string_set.3499814433": "green", - "main_set.2476980464.inner_int": "4", - }), - } - - // If we're only changing main_int - dfr := &DiffFieldReader{ - Schema: schema, - Diff: &terraform.InstanceDiff{ - Attributes: map[string]*terraform.ResourceAttrDiff{ - "main_int": &terraform.ResourceAttrDiff{ - Old: "9", - New: "2", - }, - }, - }, - Source: &MultiLevelFieldReader{ - Levels: []string{"state", "config"}, - Readers: readers, - }, - } - - // main_list should NOT be in the diff at all - result, err := dfr.ReadField([]string{"main_set"}) - if err != nil { - t.Fatalf("ReadField failed: %s", err) - } - expectedResult := NewSet(HashString, []interface{}{}) - if !expectedResult.Equal(result.Value) { - t.Fatalf("ReadField returned unexpected result.\nGiven: %#v\nexpected: %#v", - result, expectedResult) - } -} - -func TestDiffFieldReader_SetInList(t *testing.T) { - schema := map[string]*Schema{ - "main_list": &Schema{ - Type: TypeList, - Optional: true, - Elem: &Resource{ - Schema: map[string]*Schema{ - "inner_string_set": &Schema{ - Type: TypeSet, - Required: true, - Set: HashString, - Elem: &Schema{Type: TypeString}, - }, - "inner_int": &Schema{ - Type: TypeInt, - Required: true, - }, - }, - }, - }, - "main_int": &Schema{ - Type: TypeInt, - Optional: true, - }, - } - - var readers = make(map[string]FieldReader) - readers["state"] = &MapFieldReader{ - Schema: schema, - Map: BasicMapReader(map[string]string{ - "id": "8395051352714003426", - "main_int": "9", - "main_list.#": "1", - "main_list.0.inner_string_set.#": "2", - "main_list.0.inner_string_set.2654390964": "blue", - "main_list.0.inner_string_set.3499814433": "green", - "main_list.0.inner_int": "4", - }), - } - - // If we're only changing main_int - dfr := &DiffFieldReader{ - Schema: schema, - Diff: &terraform.InstanceDiff{ - Attributes: map[string]*terraform.ResourceAttrDiff{ - "main_int": &terraform.ResourceAttrDiff{ - Old: "9", - New: "2", - }, - }, - }, - Source: &MultiLevelFieldReader{ - Levels: []string{"state", "config"}, - Readers: readers, - }, - } - - // main_list should NOT be in the diff at all - result, err := dfr.ReadField([]string{"main_list"}) - if err != nil { - t.Fatalf("ReadField failed: %s", err) - } - expectedResult := FieldReadResult{ - Value: []interface{}{}, - ValueProcessed: nil, - Exists: false, - Computed: false, - } - if !reflect.DeepEqual(result, expectedResult) { - t.Fatalf("ReadField returned unexpected result.\nGiven: %#v\nexpected: %#v", - result, expectedResult) - } -} - -func TestDiffFieldReader_SetInList_singleInstance(t *testing.T) { - schema := map[string]*Schema{ - "main_list": &Schema{ - Type: TypeList, - Optional: true, - MaxItems: 1, - Elem: &Resource{ - Schema: map[string]*Schema{ - "inner_string_set": &Schema{ - Type: TypeSet, - Required: true, - Set: HashString, - Elem: &Schema{Type: TypeString}, - }, - "inner_int": &Schema{ - Type: TypeInt, - Required: true, - }, - }, - }, - }, - "main_int": &Schema{ - Type: TypeInt, - Optional: true, - }, - } - - var readers = make(map[string]FieldReader) - readers["state"] = &MapFieldReader{ - Schema: schema, - Map: BasicMapReader(map[string]string{ - "id": "8395051352714003426", - "main_int": "9", - "main_list.#": "1", - "main_list.0.inner_string_set.#": "2", - "main_list.0.inner_string_set.2654390964": "blue", - "main_list.0.inner_string_set.3499814433": "green", - "main_list.0.inner_int": "4", - }), - } - - // 1. NEGATIVE (diff doesn't contain list) - // If we're only changing main_int - dfrNegative := &DiffFieldReader{ - Schema: schema, - Diff: &terraform.InstanceDiff{ - Attributes: map[string]*terraform.ResourceAttrDiff{ - "main_int": &terraform.ResourceAttrDiff{ - Old: "9", - New: "2", - }, - }, - }, - Source: &MultiLevelFieldReader{ - Levels: []string{"state", "config"}, - Readers: readers, - }, - } - // main_list should NOT be in the diff at all - resultNegative, err := dfrNegative.ReadField([]string{"main_list"}) - if err != nil { - t.Fatalf("ReadField failed: %s", err) - } - expectedNegativeResult := FieldReadResult{ - Value: []interface{}{}, - ValueProcessed: nil, - Exists: false, - Computed: false, - } - if !reflect.DeepEqual(resultNegative, expectedNegativeResult) { - t.Fatalf("ReadField returned unexpected resultNegative.\nGiven: %#v\nexpected: %#v", - resultNegative, expectedNegativeResult) - } - - // 1. POSITIVE (diff contains list) - dfrPositive := &DiffFieldReader{ - Schema: schema, - Diff: &terraform.InstanceDiff{ - Attributes: map[string]*terraform.ResourceAttrDiff{ - "main_list.0.inner_int": &terraform.ResourceAttrDiff{ - Old: "4", - New: "2", - }, - }, - }, - Source: &MultiLevelFieldReader{ - Levels: []string{"state", "config"}, - Readers: readers, - }, - } - resultPositive, err := dfrPositive.ReadField([]string{"main_list"}) - if err != nil { - t.Fatalf("ReadField failed: %s", err) - } - if !resultPositive.Exists { - t.Fatal("Expected resultPositive to exist") - } - list := resultPositive.Value.([]interface{}) - if len(list) != 1 { - t.Fatalf("Expected exactly 1 list instance, %d given", len(list)) - } - - m := list[0].(map[string]interface{}) - - m_expectedInnerInt := 2 - m_innerInt, ok := m["inner_int"] - if !ok { - t.Fatal("Expected inner_int key to exist in map") - } - if m_innerInt != m_expectedInnerInt { - t.Fatalf("Expected inner_int (%d) doesn't match w/ given: %d", m_expectedInnerInt, m_innerInt) - } - - m_expectedStringSet := NewSet(HashString, []interface{}{"blue", "green"}) - m_StringSet, ok := m["inner_string_set"] - if !ok { - t.Fatal("Expected inner_string_set key to exist in map") - } - if !m_expectedStringSet.Equal(m_StringSet) { - t.Fatalf("Expected inner_string_set (%q) doesn't match w/ given: %q", - m_expectedStringSet.List(), m_StringSet.(*Set).List()) - } -} - -func TestDiffFieldReader_SetInList_multipleInstances(t *testing.T) { - schema := map[string]*Schema{ - "main_list": &Schema{ - Type: TypeList, - Optional: true, - Elem: &Resource{ - Schema: map[string]*Schema{ - "inner_string_set": &Schema{ - Type: TypeSet, - Required: true, - Set: HashString, - Elem: &Schema{Type: TypeString}, - }, - "inner_int": &Schema{ - Type: TypeInt, - Required: true, - }, - }, - }, - }, - "main_int": &Schema{ - Type: TypeInt, - Optional: true, - }, - } - - var readers = make(map[string]FieldReader) - readers["state"] = &MapFieldReader{ - Schema: schema, - Map: BasicMapReader(map[string]string{ - "id": "8395051352714003426", - "main_int": "9", - "main_list.#": "3", - "main_list.0.inner_string_set.#": "2", - "main_list.0.inner_string_set.2654390964": "blue", - "main_list.0.inner_string_set.3499814433": "green", - "main_list.0.inner_int": "4", - "main_list.1.inner_string_set.#": "2", - "main_list.1.inner_string_set.1830392916": "brown", - "main_list.1.inner_string_set.4200685455": "red", - "main_list.1.inner_int": "4", - "main_list.2.inner_string_set.#": "3", - "main_list.2.inner_string_set.2053932785": "one", - "main_list.2.inner_string_set.298486374": "two", - "main_list.2.inner_string_set.1187371253": "three", - "main_list.2.inner_int": "914", - }), - } - - dfr := &DiffFieldReader{ - Schema: schema, - Diff: &terraform.InstanceDiff{ - Attributes: map[string]*terraform.ResourceAttrDiff{ - "main_list.0.inner_int": &terraform.ResourceAttrDiff{ - Old: "4", - New: "5", - }, - "main_list.1.inner_int": &terraform.ResourceAttrDiff{ - Old: "4", - New: "34", - }, - }, - }, - Source: &MultiLevelFieldReader{ - Levels: []string{"state", "config"}, - Readers: readers, - }, - } - - result, err := dfr.ReadField([]string{"main_list"}) - if err != nil { - t.Fatalf("ReadField 2 failed: %s", err) - } - if !result.Exists { - t.Fatal("Expected result to exist") - } - list := result.Value.([]interface{}) - if len(list) != 3 { - t.Fatalf("Expected exactly 3 list instances, %d given", len(list)) - } - - // First - m1 := list[0].(map[string]interface{}) - - m1_expectedInnerInt := 5 - m1_innerInt, ok := m1["inner_int"] - if !ok { - t.Fatal("Expected 1st inner_int key to exist in map") - } - if m1_innerInt != m1_expectedInnerInt { - t.Fatalf("Expected 1st inner_int (%d) doesn't match w/ given: %d", m1_expectedInnerInt, m1_innerInt) - } - - m1_expectedStringSet := NewSet(HashString, []interface{}{"blue", "green"}) - m1_StringSet, ok := m1["inner_string_set"] - if !ok { - t.Fatal("Expected 1st inner_string_set key to exist in map") - } - if !m1_expectedStringSet.Equal(m1_StringSet) { - t.Fatalf("Expected 1st inner_string_set (%q) doesn't match w/ given: %q", - m1_expectedStringSet.List(), m1_StringSet.(*Set).List()) - } - - // Second - m2 := list[1].(map[string]interface{}) - - m2_expectedInnerInt := 34 - m2_innerInt, ok := m2["inner_int"] - if !ok { - t.Fatal("Expected 2nd inner_int key to exist in map") - } - if m2_innerInt != m2_expectedInnerInt { - t.Fatalf("Expected 2nd inner_int (%d) doesn't match w/ given: %d", m2_expectedInnerInt, m2_innerInt) - } - - m2_expectedStringSet := NewSet(HashString, []interface{}{"brown", "red"}) - m2_StringSet, ok := m2["inner_string_set"].(*Set) - if !ok { - t.Fatal("Expected 2nd inner_string_set key to exist in map") - } - if !m2_expectedStringSet.Equal(m2_StringSet) { - t.Fatalf("Expected 2nd inner_string_set (%q) doesn't match w/ given: %q", - m2_expectedStringSet.List(), m2_StringSet.List()) - } - - // Third - m3 := list[2].(map[string]interface{}) - - m3_expectedInnerInt := 914 - m3_innerInt, ok := m3["inner_int"] - if !ok { - t.Fatal("Expected 3rd inner_int key to exist in map") - } - if m3_innerInt != m3_expectedInnerInt { - t.Fatalf("Expected 3rd inner_int (%d) doesn't match w/ given: %d", m3_expectedInnerInt, m3_innerInt) - } - - m3_expectedStringSet := NewSet(HashString, []interface{}{"one", "two", "three"}) - m3_StringSet, ok := m3["inner_string_set"].(*Set) - if !ok { - t.Fatal("Expected 3rd inner_string_set key to exist in map") - } - if !m3_expectedStringSet.Equal(m3_StringSet) { - t.Fatalf("Expected 3rd inner_string_set (%q) doesn't match w/ given: %q", - m3_expectedStringSet.List(), m3_StringSet.List()) - } -} - -func TestDiffFieldReader_SetInList_deeplyNested_singleInstance(t *testing.T) { - inInnerSetResource := &Resource{ - Schema: map[string]*Schema{ - "in_in_inner_string": &Schema{ - Type: TypeString, - Required: true, - }, - "in_in_inner_list": &Schema{ - Type: TypeList, - Optional: true, - Elem: &Schema{Type: TypeString}, - }, - }, - } - innerSetResource := &Resource{ - Schema: map[string]*Schema{ - "in_inner_set": &Schema{ - Type: TypeSet, - Required: true, - MaxItems: 1, - Elem: inInnerSetResource, - }, - "in_inner_string_list": &Schema{ - Type: TypeList, - Optional: true, - Elem: &Schema{Type: TypeString}, - }, - "in_inner_bool": &Schema{ - Type: TypeBool, - Required: true, - }, - }, - } - schema := map[string]*Schema{ - "main_list": &Schema{ - Type: TypeList, - Optional: true, - Elem: &Resource{ - Schema: map[string]*Schema{ - "inner_string_set": &Schema{ - Type: TypeSet, - Required: true, - Set: HashString, - Elem: &Schema{Type: TypeString}, - }, - "inner_set": &Schema{ - Type: TypeSet, - Required: true, - MaxItems: 1, - Elem: innerSetResource, - }, - "inner_bool": &Schema{ - Type: TypeBool, - Optional: true, - Default: false, - }, - "inner_int": &Schema{ - Type: TypeInt, - Required: true, - }, - }, - }, - }, - "main_int": &Schema{ - Type: TypeInt, - Optional: true, - }, - } - - var readers = make(map[string]FieldReader) - readers["state"] = &MapFieldReader{ - Schema: schema, - Map: BasicMapReader(map[string]string{ - "id": "8395051352714003426", - "main_int": "5", - "main_list.#": "1", - "main_list.0.inner_bool": "true", - "main_list.0.inner_int": "2", - "main_list.0.inner_set.#": "1", - "main_list.0.inner_set.2496801729.in_inner_bool": "false", - "main_list.0.inner_set.2496801729.in_inner_set.#": "1", - "main_list.0.inner_set.2496801729.in_inner_set.1989773763.in_in_inner_list.#": "1", - "main_list.0.inner_set.2496801729.in_inner_set.1989773763.in_in_inner_list.0": "alpha", - "main_list.0.inner_set.2496801729.in_inner_set.1989773763.in_in_inner_string": "delta", - "main_list.0.inner_set.2496801729.in_inner_string_list.#": "3", - "main_list.0.inner_set.2496801729.in_inner_string_list.0": "one", - "main_list.0.inner_set.2496801729.in_inner_string_list.1": "two", - "main_list.0.inner_set.2496801729.in_inner_string_list.2": "three", - "main_list.0.inner_string_set.#": "2", - "main_list.0.inner_string_set.1830392916": "brown", - "main_list.0.inner_string_set.4200685455": "red", - }), - } - - // If we're only changing main_int - dfr := &DiffFieldReader{ - Schema: schema, - Diff: &terraform.InstanceDiff{ - Attributes: map[string]*terraform.ResourceAttrDiff{ - "main_list.0.inner_int": &terraform.ResourceAttrDiff{ - Old: "2", - New: "78", - }, - }, - }, - Source: &MultiLevelFieldReader{ - Levels: []string{"state", "config"}, - Readers: readers, - }, - } - - // main_list should NOT be in the diff at all - result, err := dfr.ReadField([]string{"main_list"}) - if err != nil { - t.Fatalf("ReadField failed: %s", err) - } - if !result.Exists { - t.Fatal("Expected result to exist") - } - list := result.Value.([]interface{}) - if len(list) != 1 { - t.Fatalf("Expected exactly 1 list instance, %d given", len(list)) - } - - // One day we may have a custom comparison function for nested sets - // Until that day comes it will look as ridiculous as below - m1 := list[0].(map[string]interface{}) - - m1_expectedInnerInt := 78 - m1_innerInt, ok := m1["inner_int"] - if !ok { - t.Fatal("Expected inner_int key to exist in map") - } - if m1_innerInt != m1_expectedInnerInt { - t.Fatalf("Expected inner_int (%d) doesn't match w/ given: %d", m1_expectedInnerInt, m1_innerInt) - } - - m1_expectedInnerBool := true - m1_innerBool, ok := m1["inner_bool"] - if !ok { - t.Fatal("Expected inner_bool key to exist in map") - } - if m1_innerBool != m1_expectedInnerBool { - t.Fatalf("Expected inner_bool (%t) doesn't match w/ given: %t", m1_expectedInnerBool, m1_innerBool) - } - - m1_expectedStringSet := NewSet(HashString, []interface{}{"brown", "red"}) - m1_StringSet, ok := m1["inner_string_set"] - if !ok { - t.Fatal("Expected inner_string_set key to exist in map") - } - if !m1_expectedStringSet.Equal(m1_StringSet) { - t.Fatalf("Expected inner_string_set (%q) doesn't match w/ given: %q", - m1_expectedStringSet.List(), m1_StringSet.(*Set).List()) - } - - m1_InnerSet, ok := m1["inner_set"] - if !ok { - t.Fatal("Expected inner_set key to exist in map") - } - m1_InnerSet_list := m1_InnerSet.(*Set).List() - m := m1_InnerSet_list[0].(map[string]interface{}) - - expectedInInnerBool := false - inInnerBool, ok := m["in_inner_bool"] - if !ok { - t.Fatal("Expected in_inner_bool key to exist in map") - } - if inInnerBool != expectedInInnerBool { - t.Fatalf("Expected inner_set[0].in_inner_bool (%#v) doesn't match w/ given: %#v", - expectedInInnerBool, inInnerBool) - } - expectedInInnerStringList := []interface{}{"one", "two", "three"} - inInnerStringList, ok := m["in_inner_string_list"] - if !ok { - t.Fatal("Expected in_inner_string_list key to exist in map") - } - if !reflect.DeepEqual(inInnerStringList, expectedInInnerStringList) { - t.Fatalf("Expected inner_set[0].in_inner_string_list (%#v) doesn't match w/ given: %#v", - expectedInInnerStringList, inInnerStringList) - } - - expectedInInnerSet := map[string]interface{}{ - "in_in_inner_string": "delta", - "in_in_inner_list": []interface{}{"alpha"}, - } - inInnerSet, ok := m["in_inner_set"] - if !ok { - t.Fatal("Expected in_inner_set key to exist in map") - } - inInnerSet_list := inInnerSet.(*Set).List() - m2 := inInnerSet_list[0].(map[string]interface{}) - if !reflect.DeepEqual(expectedInInnerSet, m2) { - t.Fatalf("Expected in_inner_set to match:\nGiven: %#v\nExpected: %#v\n", - m2, expectedInInnerSet) - } -} diff --git a/helper/schema/field_reader_map.go b/helper/schema/field_reader_map.go index 837646d0c0c5..fc3b5a02f593 100644 --- a/helper/schema/field_reader_map.go +++ b/helper/schema/field_reader_map.go @@ -2,7 +2,6 @@ package schema import ( "fmt" - "strconv" "strings" ) @@ -25,7 +24,7 @@ func (r *MapFieldReader) ReadField(address []string) (FieldReadResult, error) { case TypeBool, TypeInt, TypeFloat, TypeString: return r.readPrimitive(address, schema) case TypeList: - return r.readList(address, schema) + return readListField(r, address, schema) case TypeMap: return r.readMap(k) case TypeSet: @@ -92,57 +91,6 @@ func (r *MapFieldReader) readPrimitive( }, nil } -func (r *MapFieldReader) readList( - address []string, schema *Schema) (FieldReadResult, error) { - - addrPadded := make([]string, len(address)+1) - copy(addrPadded, address) - - // Get the number of elements in the list - addrPadded[len(addrPadded)-1] = "#" - countResult, err := r.readPrimitive(addrPadded, &Schema{Type: TypeInt}) - if err != nil { - return FieldReadResult{}, err - } - if !countResult.Exists { - // No count, means we have no list - countResult.Value = 0 - } - - // If we have an empty list, then return an empty list - if countResult.Computed || countResult.Value.(int) == 0 { - return FieldReadResult{ - Value: []interface{}{}, - Exists: countResult.Exists, - Computed: countResult.Computed, - }, nil - } - - // Go through each count, and get the item value out of it - result := make([]interface{}, countResult.Value.(int)) - for i, _ := range result { - idx := strconv.Itoa(i) - addrPadded[len(addrPadded)-1] = idx - rawResult, err := r.ReadField(addrPadded) - if err != nil { - return FieldReadResult{}, err - } - if !rawResult.Exists { - // This should never happen, because by the time the data - // gets to the FieldReaders, all the defaults should be set by - // Schema. - panic("missing field in list: " + strings.Join(addrPadded, ".")) - } - - result[i] = rawResult.Value - } - - return FieldReadResult{ - Value: result, - Exists: true, - }, nil -} - func (r *MapFieldReader) readSet( address []string, schema *Schema) (FieldReadResult, error) { // Get the number of elements in the list diff --git a/helper/schema/field_reader_map_test.go b/helper/schema/field_reader_map_test.go index aab8588a2076..279b9145bdea 100644 --- a/helper/schema/field_reader_map_test.go +++ b/helper/schema/field_reader_map_test.go @@ -106,252 +106,3 @@ func TestMapFieldReader_extra(t *testing.T) { } } } - -func TestMapFieldReader_SetInSet(t *testing.T) { - schema := map[string]*Schema{ - "main_set": &Schema{ - Type: TypeSet, - Optional: true, - Elem: &Resource{ - Schema: map[string]*Schema{ - "inner_string_set": &Schema{ - Type: TypeSet, - Required: true, - Set: HashString, - Elem: &Schema{Type: TypeString}, - }, - }, - }, - }, - "main_int": &Schema{ - Type: TypeInt, - Optional: true, - }, - } - - r := &MapFieldReader{ - Schema: schema, - Map: BasicMapReader(map[string]string{ - "id": "8395051352714003426", - "main_int": "9", - "main_set.#": "1", - "main_set.2813616083.inner_string_set.#": "2", - "main_set.2813616083.inner_string_set.2654390964": "blue", - "main_set.2813616083.inner_string_set.3499814433": "green", - }), - } - - result, err := r.ReadField([]string{"main_set"}) - if err != nil { - t.Fatalf("ReadField failed: %#v", err) - } - - v := result.Value - if v == nil { - t.Fatal("Expected Value to be not nil") - } - list := v.(*Set).List() - if len(list) != 1 { - t.Fatalf("Expected exactly 1 instance, got %d", len(list)) - } - if list[0] == nil { - t.Fatalf("Expected value to be not nil: %#v", list) - } - - m := list[0].(map[string]interface{}) - set := m["inner_string_set"].(*Set).List() - - expectedSet := NewSet(HashString, []interface{}{"blue", "green"}).List() - - if !reflect.DeepEqual(set, expectedSet) { - t.Fatalf("Given: %#v\n\nExpected: %#v", set, expectedSet) - } -} - -func TestMapFieldReader_SetInList(t *testing.T) { - schema := map[string]*Schema{ - "main_list": &Schema{ - Type: TypeList, - Optional: true, - Elem: &Resource{ - Schema: map[string]*Schema{ - "inner_string_set": &Schema{ - Type: TypeSet, - Required: true, - Set: HashString, - Elem: &Schema{Type: TypeString}, - }, - }, - }, - }, - "main_int": &Schema{ - Type: TypeInt, - Optional: true, - }, - } - - r := &MapFieldReader{ - Schema: schema, - Map: BasicMapReader(map[string]string{ - "id": "8395051352714003426", - "main_int": "9", - "main_list.#": "1", - "main_list.0.inner_string_set.#": "2", - "main_list.0.inner_string_set.2654390964": "blue", - "main_list.0.inner_string_set.3499814433": "green", - }), - } - - result, err := r.ReadField([]string{"main_list"}) - if err != nil { - t.Fatalf("ReadField failed: %#v", err) - } - - v := result.Value - if v == nil { - t.Fatal("Expected Value to be not nil") - } - list := v.([]interface{}) - if len(list) != 1 { - t.Fatalf("Expected exactly 1 instance, got %d", len(list)) - } - if list[0] == nil { - t.Fatalf("Expected value to be not nil: %#v", list) - } - - m := list[0].(map[string]interface{}) - set := m["inner_string_set"].(*Set).List() - - expectedSet := NewSet(HashString, []interface{}{"blue", "green"}).List() - - if !reflect.DeepEqual(set, expectedSet) { - t.Fatalf("Given: %#v\n\nExpected: %#v", set, expectedSet) - } -} - -func TestMapFieldReader_SetInList_complex(t *testing.T) { - schema := map[string]*Schema{ - "main_list": &Schema{ - Type: TypeList, - Optional: true, - Elem: &Resource{ - Schema: map[string]*Schema{ - "inner_string_set": &Schema{ - Type: TypeSet, - Required: true, - Set: HashString, - Elem: &Schema{Type: TypeString}, - }, - "inner_int": &Schema{ - Type: TypeInt, - Required: true, - }, - }, - }, - }, - "main_int": &Schema{ - Type: TypeInt, - Optional: true, - }, - } - - r := &MapFieldReader{ - Schema: schema, - Map: BasicMapReader(map[string]string{ - "id": "8395051352714003426", - "main_int": "9", - "main_list.#": "1", - "main_list.0.inner_string_set.#": "2", - "main_list.0.inner_string_set.2654390964": "blue", - "main_list.0.inner_string_set.3499814433": "green", - "main_list.0.inner_int": "4", - }), - } - - result, err := r.ReadField([]string{"main_list"}) - if err != nil { - t.Fatalf("ReadField failed: %#v", err) - } - - v := result.Value - if v == nil { - t.Fatal("Expected Value to be not nil") - } - list := v.([]interface{}) - if len(list) != 1 { - t.Fatalf("Expected exactly 1 instance, got %d", len(list)) - } - if list[0] == nil { - t.Fatalf("Expected value to be not nil: %#v", list) - } - - m := list[0].(map[string]interface{}) - set := m["inner_string_set"].(*Set).List() - - expectedSet := NewSet(HashString, []interface{}{"blue", "green"}).List() - - if !reflect.DeepEqual(set, expectedSet) { - t.Fatalf("Given: %#v\n\nExpected: %#v", set, expectedSet) - } -} - -func TestMapFieldReader_readSet_SetInSet(t *testing.T) { - schema := map[string]*Schema{ - "main_set": &Schema{ - Type: TypeSet, - Optional: true, - Elem: &Resource{ - Schema: map[string]*Schema{ - "inner_string_set": &Schema{ - Type: TypeSet, - Required: true, - Set: HashString, - Elem: &Schema{Type: TypeString}, - }, - }, - }, - }, - "main_int": &Schema{ - Type: TypeInt, - Optional: true, - }, - } - - r := &MapFieldReader{ - Schema: schema, - Map: BasicMapReader(map[string]string{ - "id": "8395051352714003426", - "main_int": "9", - "main_set.#": "1", - "main_set.2813616083.inner_string_set.#": "2", - "main_set.2813616083.inner_string_set.2654390964": "blue", - "main_set.2813616083.inner_string_set.3499814433": "green", - }), - } - - result, err := r.readSet([]string{"main_set"}, schema["main_set"]) - if err != nil { - t.Fatalf("readSet failed: %#v", err) - } - - v := result.Value - if v == nil { - t.Fatal("Expected Value to be not nil") - } - list := v.(*Set).List() - if len(list) != 1 { - t.Fatalf("Expected exactly 1 instance, got %d", len(list)) - } - if list[0] == nil { - t.Fatalf("Expected value to be not nil: %#v", list) - } - - m := list[0].(map[string]interface{}) - set := m["inner_string_set"].(*Set).List() - - expectedSet := NewSet(HashString, []interface{}{"blue", "green"}).List() - - if !reflect.DeepEqual(set, expectedSet) { - t.Fatalf("Given: %#v\n\nExpected: %#v", set, expectedSet) - } -} diff --git a/helper/schema/field_reader_multi_test.go b/helper/schema/field_reader_multi_test.go index 1b482083d276..85286a66ed3d 100644 --- a/helper/schema/field_reader_multi_test.go +++ b/helper/schema/field_reader_multi_test.go @@ -264,361 +264,7 @@ func TestMultiLevelFieldReaderReadFieldMerge(t *testing.T) { } if !reflect.DeepEqual(tc.Result, out) { - t.Fatalf("Case %s:\ngiven: %#v\nexpected: %#v", name, out, tc.Result) + t.Fatalf("%s: bad: %#v", name, out) } } } - -func TestMultiLevelFieldReader_ReadField_SetInSet(t *testing.T) { - schema := map[string]*Schema{ - "main_set": &Schema{ - Type: TypeSet, - Optional: true, - Elem: &Resource{ - Schema: map[string]*Schema{ - "inner_string_set": &Schema{ - Type: TypeSet, - Required: true, - Set: HashString, - Elem: &Schema{Type: TypeString}, - }, - }, - }, - }, - "main_int": &Schema{ - Type: TypeInt, - Optional: true, - }, - } - - var readers = make(map[string]FieldReader) - readers["state"] = &MapFieldReader{ - Schema: schema, - Map: BasicMapReader(map[string]string{ - "id": "8395051352714003426", - "main_int": "9", - "main_set.#": "1", - "main_set.2813616083.inner_string_set.#": "2", - "main_set.2813616083.inner_string_set.2654390964": "blue", - "main_set.2813616083.inner_string_set.3499814433": "green", - }), - } - readers["diff"] = &DiffFieldReader{ - Schema: schema, - Diff: &terraform.InstanceDiff{ - Attributes: map[string]*terraform.ResourceAttrDiff{ - "main_int": &terraform.ResourceAttrDiff{ - Old: "9", - New: "2", - }, - }, - }, - Source: &MultiLevelFieldReader{ - Levels: []string{"state", "config"}, - Readers: readers, - }, - } - - mr := &MultiLevelFieldReader{ - Levels: []string{ - "state", - "diff", - }, - - Readers: readers, - } - - result, err := mr.ReadField([]string{"main_set"}) - if err != nil { - t.Fatalf("ReadField failed: %#v", err) - } - - v := result.Value - if v == nil { - t.Fatal("Expected Value to be not nil") - } - list := v.(*Set).List() - if len(list) != 1 { - t.Fatalf("Expected exactly 1 instance, got %d", len(list)) - } - if list[0] == nil { - t.Fatalf("Expected value to be not nil: %#v", list) - } - - m := list[0].(map[string]interface{}) - set := m["inner_string_set"].(*Set).List() - - expectedSet := NewSet(HashString, []interface{}{"blue", "green"}).List() - - if !reflect.DeepEqual(set, expectedSet) { - t.Fatalf("Given: %#v\n\nExpected: %#v", set, expectedSet) - } -} - -func TestMultiLevelFieldReader_ReadField_SetInSet_complex(t *testing.T) { - schema := map[string]*Schema{ - "main_set": &Schema{ - Type: TypeSet, - Optional: true, - Elem: &Resource{ - Schema: map[string]*Schema{ - "inner_string_set": &Schema{ - Type: TypeSet, - Required: true, - Set: HashString, - Elem: &Schema{Type: TypeString}, - }, - "inner_int": &Schema{ - Type: TypeInt, - Required: true, - }, - }, - }, - }, - "main_int": &Schema{ - Type: TypeInt, - Optional: true, - }, - } - - var readers = make(map[string]FieldReader) - readers["state"] = &MapFieldReader{ - Schema: schema, - Map: BasicMapReader(map[string]string{ - "id": "8395051352714003426", - "main_int": "9", - "main_set.#": "1", - "main_set.2476980464.inner_string_set.#": "2", - "main_set.2476980464.inner_string_set.2654390964": "blue", - "main_set.2476980464.inner_string_set.3499814433": "green", - "main_set.2476980464.inner_int": "4", - }), - } - readers["diff"] = &DiffFieldReader{ - Schema: schema, - Diff: &terraform.InstanceDiff{ - Attributes: map[string]*terraform.ResourceAttrDiff{ - "main_int": &terraform.ResourceAttrDiff{ - Old: "9", - New: "2", - }, - }, - }, - Source: &MultiLevelFieldReader{ - Levels: []string{"state", "config"}, - Readers: readers, - }, - } - - mr := &MultiLevelFieldReader{ - Levels: []string{ - "state", - "diff", - }, - - Readers: readers, - } - - result, err := mr.ReadFieldMerge([]string{"main_set"}, "diff") - if err != nil { - t.Fatalf("ReadFieldMerge failed: %#v", err) - } - - v := result.Value - if v == nil { - t.Fatal("Expected Value to be not nil") - } - list := v.(*Set).List() - if len(list) != 1 { - t.Fatalf("Expected exactly 1 instance, got %d", len(list)) - } - if list[0] == nil { - t.Fatalf("Expected value to be not nil: %#v", list) - } - - m := list[0].(map[string]interface{}) - set := m["inner_string_set"].(*Set).List() - - expectedSet := NewSet(HashString, []interface{}{"blue", "green"}).List() - - if !reflect.DeepEqual(set, expectedSet) { - t.Fatalf("Given: %#v\n\nExpected: %#v", set, expectedSet) - } -} - -func TestMultiLevelFieldReader_ReadField_SetInList_simple(t *testing.T) { - schema := map[string]*Schema{ - "main_list": &Schema{ - Type: TypeList, - Optional: true, - Elem: &Resource{ - Schema: map[string]*Schema{ - "inner_string_set": &Schema{ - Type: TypeSet, - Required: true, - Set: HashString, - Elem: &Schema{Type: TypeString}, - }, - }, - }, - }, - "main_int": &Schema{ - Type: TypeInt, - Optional: true, - }, - } - - var readers = make(map[string]FieldReader) - readers["state"] = &MapFieldReader{ - Schema: schema, - Map: BasicMapReader(map[string]string{ - "id": "8395051352714003426", - "main_int": "9", - "main_list.#": "1", - "main_list.0.inner_string_set.#": "2", - "main_list.0.inner_string_set.2654390964": "blue", - "main_list.0.inner_string_set.3499814433": "green", - }), - } - readers["diff"] = &DiffFieldReader{ - Schema: schema, - Diff: &terraform.InstanceDiff{ - Attributes: map[string]*terraform.ResourceAttrDiff{ - "main_int": &terraform.ResourceAttrDiff{ - Old: "9", - New: "2", - }, - }, - }, - Source: &MultiLevelFieldReader{ - Levels: []string{"state", "config"}, - Readers: readers, - }, - } - - mr := &MultiLevelFieldReader{ - Levels: []string{ - "state", - "diff", - }, - - Readers: readers, - } - - result, err := mr.ReadField([]string{"main_list"}) - if err != nil { - t.Fatalf("ReadField failed: %#v", err) - } - - v := result.Value - if v == nil { - t.Fatal("Expected Value to be not nil") - } - list := v.([]interface{}) - if len(list) != 1 { - t.Fatalf("Expected exactly 1 instance, got %d", len(list)) - } - if list[0] == nil { - t.Fatalf("Expected value to be not nil: %#v", list) - } - - m := list[0].(map[string]interface{}) - set := m["inner_string_set"].(*Set).List() - - expectedSet := NewSet(HashString, []interface{}{"blue", "green"}).List() - - if !reflect.DeepEqual(set, expectedSet) { - t.Fatalf("Given: %#v\n\nExpected: %#v", set, expectedSet) - } -} - -func TestMultiLevelFieldReader_ReadField_SetInList_complex(t *testing.T) { - schema := map[string]*Schema{ - "main_list": &Schema{ - Type: TypeList, - Optional: true, - Elem: &Resource{ - Schema: map[string]*Schema{ - "inner_string_set": &Schema{ - Type: TypeSet, - Required: true, - Set: HashString, - Elem: &Schema{Type: TypeString}, - }, - "inner_int": &Schema{ - Type: TypeInt, - Required: true, - }, - }, - }, - }, - "main_int": &Schema{ - Type: TypeInt, - Optional: true, - }, - } - - var readers = make(map[string]FieldReader) - readers["state"] = &MapFieldReader{ - Schema: schema, - Map: BasicMapReader(map[string]string{ - "id": "8395051352714003426", - "main_int": "9", - "main_list.#": "1", - "main_list.0.inner_string_set.#": "2", - "main_list.0.inner_string_set.2654390964": "blue", - "main_list.0.inner_string_set.3499814433": "green", - "main_list.0.inner_int": "4", - }), - } - readers["diff"] = &DiffFieldReader{ - Schema: schema, - Diff: &terraform.InstanceDiff{ - Attributes: map[string]*terraform.ResourceAttrDiff{ - "main_int": &terraform.ResourceAttrDiff{ - Old: "9", - New: "2", - }, - }, - }, - Source: &MultiLevelFieldReader{ - Levels: []string{"state", "config"}, - Readers: readers, - }, - } - - mr := &MultiLevelFieldReader{ - Levels: []string{ - "state", - "diff", - }, - - Readers: readers, - } - - result, err := mr.ReadFieldMerge([]string{"main_list"}, "diff") - if err != nil { - t.Fatalf("ReadFieldMerge failed: %#v", err) - } - - v := result.Value - if v == nil { - t.Fatal("Expected Value to be not nil") - } - list := v.([]interface{}) - if len(list) != 1 { - t.Fatalf("Expected exactly 1 instance, got %d", len(list)) - } - if list[0] == nil { - t.Fatalf("Expected value to be not nil: %#v", list) - } - - m := list[0].(map[string]interface{}) - set := m["inner_string_set"].(*Set).List() - - expectedSet := NewSet(HashString, []interface{}{"blue", "green"}).List() - - if !reflect.DeepEqual(set, expectedSet) { - t.Fatalf("Given: %#v\n\nExpected: %#v", set, expectedSet) - } -} diff --git a/helper/schema/field_reader_test.go b/helper/schema/field_reader_test.go index 003c98c37995..c61fb8eb7323 100644 --- a/helper/schema/field_reader_test.go +++ b/helper/schema/field_reader_test.go @@ -395,68 +395,7 @@ func testFieldReader(t *testing.T, f func(map[string]*Schema) FieldReader) { out.Value = s.List() } if !reflect.DeepEqual(tc.Result, out) { - t.Fatalf("%s: Unexpected field result:\nGiven: %#v\nExpected: %#v", name, out, tc.Result) + t.Fatalf("%s: bad: %#v", name, out) } } } - -func TestReadList_SetInList(t *testing.T) { - schema := map[string]*Schema{ - "main_list": &Schema{ - Type: TypeList, - Optional: true, - Elem: &Resource{ - Schema: map[string]*Schema{ - "inner_string_set": &Schema{ - Type: TypeSet, - Required: true, - Set: HashString, - Elem: &Schema{Type: TypeString}, - }, - }, - }, - }, - "main_int": &Schema{ - Type: TypeInt, - Optional: true, - }, - } - - r := &MapFieldReader{ - Schema: schema, - Map: BasicMapReader(map[string]string{ - "id": "8395051352714003426", - "main_int": "9", - "main_list.#": "1", - "main_list.0.inner_string_set.#": "2", - "main_list.0.inner_string_set.2654390964": "blue", - "main_list.0.inner_string_set.3499814433": "green", - }), - } - - result, err := r.readList([]string{"main_list"}, schema["main_list"]) - if err != nil { - t.Fatalf("readListField failed: %#v", err) - } - - v := result.Value - if v == nil { - t.Fatal("Expected Value to be not nil") - } - list := v.([]interface{}) - if len(list) != 1 { - t.Fatalf("Expected exactly 1 instance, got %d", len(list)) - } - if list[0] == nil { - t.Fatalf("Expected value to be not nil: %#v", list) - } - - m := list[0].(map[string]interface{}) - set := m["inner_string_set"].(*Set).List() - - expectedSet := NewSet(HashString, []interface{}{"blue", "green"}).List() - - if !reflect.DeepEqual(set, expectedSet) { - t.Fatalf("Given: %#v\n\nExpected: %#v", set, expectedSet) - } -} diff --git a/helper/schema/resource_data_test.go b/helper/schema/resource_data_test.go index 1f54eda4a4ce..0e6d1b2dc396 100644 --- a/helper/schema/resource_data_test.go +++ b/helper/schema/resource_data_test.go @@ -751,212 +751,6 @@ func TestResourceDataGet(t *testing.T) { } } -func TestSetInsideSet(t *testing.T) { - _schema := map[string]*Schema{ - "main_set": &Schema{ - Type: TypeSet, - Optional: true, - Elem: &Resource{ - Schema: map[string]*Schema{ - "inner_string_set": &Schema{ - Type: TypeSet, - Required: true, - Set: HashString, - Elem: &Schema{Type: TypeString}, - }, - }, - }, - }, - "main_int": &Schema{ - Type: TypeInt, - Optional: true, - }, - } - - existingState := &terraform.InstanceState{ - ID: "8395051352714003426", - Attributes: map[string]string{ - "id": "8395051352714003426", - "main_int": "9", - "main_set.#": "1", - "main_set.2813616083.inner_string_set.#": "2", - "main_set.2813616083.inner_string_set.2654390964": "blue", - "main_set.2813616083.inner_string_set.3499814433": "green", - }, - Meta: map[string]string{}, - Tainted: false, - } - - suggestedDiff := &terraform.InstanceDiff{ - Attributes: map[string]*terraform.ResourceAttrDiff{ - "main_int": &terraform.ResourceAttrDiff{ - Old: "9", - New: "2", - }, - }, - } - - d := &ResourceData{ - schema: _schema, - state: existingState, - diff: suggestedDiff, - } - - v := d.Get("main_set").(*Set).List() - if len(v) != 1 { - t.Fatalf("Expected exactly 1 instance of main_set, got %d", len(v)) - } - if v[0] == nil { - t.Fatalf("Expected main_set to be not nil: %#v", v) - } - - m := v[0].(map[string]interface{}) - set := m["inner_string_set"].(*Set).List() - expectedSet := NewSet(HashString, []interface{}{"blue", "green"}).List() - if !reflect.DeepEqual(set, expectedSet) { - t.Fatalf("Given: %#v\n\nExpected: %#v", set, expectedSet) - } -} - -func TestSetInsideList_simple(t *testing.T) { - _schema := map[string]*Schema{ - "main_list": &Schema{ - Type: TypeList, - Optional: true, - Elem: &Resource{ - Schema: map[string]*Schema{ - "inner_string_set": &Schema{ - Type: TypeSet, - Required: true, - Set: HashString, - Elem: &Schema{Type: TypeString}, - }, - }, - }, - }, - "main_int": &Schema{ - Type: TypeInt, - Optional: true, - }, - } - - existingState := &terraform.InstanceState{ - ID: "8395051352714003426", - Attributes: map[string]string{ - "id": "8395051352714003426", - "main_int": "9", - "main_list.#": "1", - "main_list.0.inner_string_set.#": "2", - "main_list.0.inner_string_set.2654390964": "blue", - "main_list.0.inner_string_set.3499814433": "green", - }, - Meta: map[string]string{}, - Tainted: false, - } - - suggestedDiff := &terraform.InstanceDiff{ - Attributes: map[string]*terraform.ResourceAttrDiff{ - "main_int": &terraform.ResourceAttrDiff{ - Old: "9", - New: "2", - }, - }, - } - - d := &ResourceData{ - schema: _schema, - state: existingState, - diff: suggestedDiff, - } - - v := d.Get("main_list").([]interface{}) - if len(v) != 1 { - t.Fatalf("Expected exactly 1 instance of main_list, got %d", len(v)) - } - if v[0] == nil { - t.Fatalf("Expected main_list to be not nil: %#v", v) - } - - m := v[0].(map[string]interface{}) - set := m["inner_string_set"].(*Set).List() - expectedSet := NewSet(HashString, []interface{}{"blue", "green"}).List() - if !reflect.DeepEqual(set, expectedSet) { - t.Fatalf("Given: %#v\n\nExpected: %#v", set, expectedSet) - } -} - -func TestSetInsideList_complex(t *testing.T) { - _schema := map[string]*Schema{ - "main_list": &Schema{ - Type: TypeList, - Optional: true, - Elem: &Resource{ - Schema: map[string]*Schema{ - "inner_string_set": &Schema{ - Type: TypeSet, - Required: true, - Set: HashString, - Elem: &Schema{Type: TypeString}, - }, - "inner_int": &Schema{ - Type: TypeInt, - Required: true, - }, - }, - }, - }, - "main_int": &Schema{ - Type: TypeInt, - Optional: true, - }, - } - - existingState := &terraform.InstanceState{ - ID: "8395051352714003426", - Attributes: map[string]string{ - "id": "8395051352714003426", - "main_int": "9", - "main_list.#": "1", - "main_list.0.inner_string_set.#": "2", - "main_list.0.inner_string_set.2654390964": "blue", - "main_list.0.inner_string_set.3499814433": "green", - "main_list.0.inner_int": "4", - }, - Meta: map[string]string{}, - Tainted: false, - } - - suggestedDiff := &terraform.InstanceDiff{ - Attributes: map[string]*terraform.ResourceAttrDiff{ - "main_int": &terraform.ResourceAttrDiff{ - Old: "9", - New: "2", - }, - }, - } - - d := &ResourceData{ - schema: _schema, - state: existingState, - diff: suggestedDiff, - } - - v := d.Get("main_list").([]interface{}) - if len(v) != 1 { - t.Fatalf("Expected exactly 1 instance of main_list, got %d", len(v)) - } - if v[0] == nil { - t.Fatalf("Expected main_list to be not nil: %#v", v) - } - - m := v[0].(map[string]interface{}) - set := m["inner_string_set"].(*Set).List() - expectedSet := NewSet(HashString, []interface{}{"blue", "green"}).List() - if !reflect.DeepEqual(set, expectedSet) { - t.Fatalf("Given: %#v\n\nExpected: %#v", set, expectedSet) - } -} - func TestResourceDataGetChange(t *testing.T) { cases := []struct { Schema map[string]*Schema diff --git a/helper/schema/set.go b/helper/schema/set.go index 0d5bebd7c01a..de05f40eed91 100644 --- a/helper/schema/set.go +++ b/helper/schema/set.go @@ -98,10 +98,6 @@ func (s *Set) List() []interface{} { return result } -func (s *Set) Map() map[string]interface{} { - return s.m -} - // Difference performs a set difference of the two sets, returning // a new third set that has only the elements unique to this set. func (s *Set) Difference(other *Set) *Set {