helper/schema: Final set of ResourceDiff tests, bug fixes
Final set of coverage for ResourceDiff and bug fixes to correct issues the test cases brought up. Will be dropping ClearAll in next commit, as with how this interface is intended to be used, it does not really make much sense.
This commit is contained in:
parent
a5fc664ea6
commit
22220fd0f7
|
@ -32,7 +32,7 @@ func (w *newValueWriter) WriteField(address []string, value interface{}, compute
|
|||
|
||||
w.lock.Lock()
|
||||
defer w.lock.Unlock()
|
||||
if w.result == nil {
|
||||
if w.computedKeys == nil {
|
||||
w.computedKeys = make(map[string]bool)
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@ func (w *newValueWriter) WriteField(address []string, value interface{}, compute
|
|||
func (w *newValueWriter) ComputedKeysMap() map[string]bool {
|
||||
w.lock.Lock()
|
||||
defer w.lock.Unlock()
|
||||
if w.result == nil {
|
||||
if w.computedKeys == nil {
|
||||
w.computedKeys = make(map[string]bool)
|
||||
}
|
||||
return w.computedKeys
|
||||
|
@ -65,12 +65,22 @@ type newValueReader struct {
|
|||
// ReadField reads the values from the underlying writer, returning the
|
||||
// computed value if it is found as well.
|
||||
func (r *newValueReader) ReadField(address []string) (FieldReadResult, error) {
|
||||
addrKey := strings.Join(address, ".")
|
||||
v, err := r.MapFieldReader.ReadField(address)
|
||||
if err != nil {
|
||||
return FieldReadResult{}, err
|
||||
}
|
||||
if _, ok := r.computedKeys[strings.Join(address, ".")]; ok {
|
||||
v.Computed = true
|
||||
for computedKey := range r.computedKeys {
|
||||
if strings.HasPrefix(addrKey, computedKey) {
|
||||
if strings.HasSuffix(addrKey, ".#") {
|
||||
// This is a count value for a list or set that has been marked as
|
||||
// computed, or a sub-list/sub-set of a complex resource that has
|
||||
// been marked as computed. We need to pass through to other readers
|
||||
// so that an accurate previous count can be fetched for the diff.
|
||||
v.Exists = false
|
||||
}
|
||||
v.Computed = true
|
||||
}
|
||||
}
|
||||
|
||||
return v, nil
|
||||
|
@ -126,13 +136,7 @@ func newResourceDiff(schema map[string]*Schema, config *terraform.ResourceConfig
|
|||
config: config,
|
||||
state: state,
|
||||
diff: diff,
|
||||
}
|
||||
// Duplicate the passed in schema to ensure that any changes we make with
|
||||
// functions like ForceNew don't affect the referenced schema.
|
||||
d.schema = make(map[string]*Schema)
|
||||
for k, v := range schema {
|
||||
newSchema := *v
|
||||
d.schema[k] = &newSchema
|
||||
schema: schema,
|
||||
}
|
||||
|
||||
d.oldWriter = &MapFieldWriter{Schema: d.schema}
|
||||
|
@ -215,8 +219,17 @@ func (d *ResourceDiff) ClearAll() {
|
|||
// any possibility of conflicts, but can be called on its own to just remove a
|
||||
// specific key from the diff completely.
|
||||
//
|
||||
// Note that this does not wipe an override.
|
||||
// Note that this does not wipe an override. This function is only allowed on
|
||||
// computed keys.
|
||||
func (d *ResourceDiff) Clear(key string) error {
|
||||
if !d.schema[key].Computed {
|
||||
return fmt.Errorf("Clear is allowed on computed attributes only - %s is not one", key)
|
||||
}
|
||||
|
||||
return d.clear(key)
|
||||
}
|
||||
|
||||
func (d *ResourceDiff) clear(key string) error {
|
||||
// Check the schema to make sure that this key exists first.
|
||||
if _, ok := d.schema[key]; !ok {
|
||||
return fmt.Errorf("%s is not a valid key", key)
|
||||
|
@ -233,6 +246,7 @@ func (d *ResourceDiff) Clear(key string) error {
|
|||
// from ResourceDiff's own change data, in addition to existing diff, config, and state.
|
||||
func (d *ResourceDiff) diffChange(key string) (interface{}, interface{}, bool, bool) {
|
||||
old, new := d.getChange(key)
|
||||
// log.Printf("\nkey:%s\n\nold:%s\n\nnew:%s\n", key, spew.Sdump(old), spew.Sdump(new))
|
||||
|
||||
if !old.Exists {
|
||||
old.Value = nil
|
||||
|
@ -262,7 +276,7 @@ func (d *ResourceDiff) SetNew(key string, value interface{}) error {
|
|||
//
|
||||
// This function is only allowed on computed keys.
|
||||
func (d *ResourceDiff) SetNewComputed(key string) error {
|
||||
return d.SetDiff(key, d.Get(key), d.schema[key].ZeroValue(), true)
|
||||
return d.SetDiff(key, d.getExact(strings.Split(key, "."), "state").Value, d.schema[key].ZeroValue(), true)
|
||||
}
|
||||
|
||||
// SetDiff allows the setting of both old and new values for the diff
|
||||
|
@ -277,7 +291,11 @@ func (d *ResourceDiff) SetDiff(key string, old, new interface{}, computed bool)
|
|||
return fmt.Errorf("SetNew, SetNewComputed, and SetDiff are allowed on computed attributes only - %s is not one", key)
|
||||
}
|
||||
|
||||
if err := d.Clear(key); err != nil {
|
||||
return d.setDiff(key, old, new, computed)
|
||||
}
|
||||
|
||||
func (d *ResourceDiff) setDiff(key string, old, new interface{}, computed bool) error {
|
||||
if err := d.clear(key); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -298,8 +316,7 @@ func (d *ResourceDiff) SetDiff(key string, old, new interface{}, computed bool)
|
|||
// re-calculates its diff. This function is a no-op/error if there is no diff.
|
||||
//
|
||||
// Note that the change to schema is permanent for the lifecycle of this
|
||||
// specific ResourceDiff instance, until ClearAll or Reset is called to start
|
||||
// anew.
|
||||
// specific ResourceDiff instance.
|
||||
func (d *ResourceDiff) ForceNew(key string) error {
|
||||
if !d.HasChange(key) {
|
||||
return fmt.Errorf("ResourceDiff.ForceNew: No changes for %s", key)
|
||||
|
@ -307,7 +324,7 @@ func (d *ResourceDiff) ForceNew(key string) error {
|
|||
|
||||
old, new := d.GetChange(key)
|
||||
d.schema[key].ForceNew = true
|
||||
return d.SetDiff(key, old, new, false)
|
||||
return d.setDiff(key, old, new, false)
|
||||
}
|
||||
|
||||
// Get hands off to ResourceData.Get.
|
||||
|
|
|
@ -19,19 +19,24 @@ func testSetFunc(v interface{}) int {
|
|||
return m["foo"].(int) + m["bar"].(int)
|
||||
}
|
||||
|
||||
func TestSetNew(t *testing.T) {
|
||||
testCases := []struct {
|
||||
Name string
|
||||
Schema map[string]*Schema
|
||||
State *terraform.InstanceState
|
||||
Config *terraform.ResourceConfig
|
||||
Diff *terraform.InstanceDiff
|
||||
Key string
|
||||
NewValue interface{}
|
||||
Expected *terraform.InstanceDiff
|
||||
ExpectedError bool
|
||||
}{
|
||||
{
|
||||
// resourceDiffTestCase provides a test case struct for SetNew and SetDiff.
|
||||
type resourceDiffTestCase struct {
|
||||
Name string
|
||||
Schema map[string]*Schema
|
||||
State *terraform.InstanceState
|
||||
Config *terraform.ResourceConfig
|
||||
Diff *terraform.InstanceDiff
|
||||
Key string
|
||||
OldValue interface{}
|
||||
NewValue interface{}
|
||||
Expected *terraform.InstanceDiff
|
||||
ExpectedError bool
|
||||
}
|
||||
|
||||
// testDiffCases produces a list of test cases for use with SetNew and SetDiff.
|
||||
func testDiffCases(t *testing.T, oldPrefix string, oldOffset int, computed bool) []resourceDiffTestCase {
|
||||
return []resourceDiffTestCase{
|
||||
resourceDiffTestCase{
|
||||
Name: "basic primitive diff",
|
||||
Schema: map[string]*Schema{
|
||||
"foo": &Schema{
|
||||
|
@ -57,17 +62,24 @@ func TestSetNew(t *testing.T) {
|
|||
},
|
||||
},
|
||||
Key: "foo",
|
||||
OldValue: fmt.Sprintf("%sbar", oldPrefix),
|
||||
NewValue: "qux",
|
||||
Expected: &terraform.InstanceDiff{
|
||||
Attributes: map[string]*terraform.ResourceAttrDiff{
|
||||
"foo": &terraform.ResourceAttrDiff{
|
||||
Old: "bar",
|
||||
New: "qux",
|
||||
Old: fmt.Sprintf("%sbar", oldPrefix),
|
||||
New: func() string {
|
||||
if computed {
|
||||
return ""
|
||||
}
|
||||
return "qux"
|
||||
}(),
|
||||
NewComputed: computed,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
resourceDiffTestCase{
|
||||
Name: "basic set diff",
|
||||
Schema: map[string]*Schema{
|
||||
"foo": &Schema{
|
||||
|
@ -101,22 +113,33 @@ func TestSetNew(t *testing.T) {
|
|||
},
|
||||
},
|
||||
Key: "foo",
|
||||
OldValue: []interface{}{fmt.Sprintf("%sbar", oldPrefix)},
|
||||
NewValue: []interface{}{"qux"},
|
||||
Expected: &terraform.InstanceDiff{
|
||||
Attributes: map[string]*terraform.ResourceAttrDiff{
|
||||
"foo.1996459178": &terraform.ResourceAttrDiff{
|
||||
Old: "bar",
|
||||
New: "",
|
||||
NewRemoved: true,
|
||||
},
|
||||
"foo.2800005064": &terraform.ResourceAttrDiff{
|
||||
Old: "",
|
||||
New: "qux",
|
||||
},
|
||||
},
|
||||
Attributes: func() map[string]*terraform.ResourceAttrDiff {
|
||||
result := map[string]*terraform.ResourceAttrDiff{}
|
||||
if computed {
|
||||
result["foo.#"] = &terraform.ResourceAttrDiff{
|
||||
Old: "1",
|
||||
New: "",
|
||||
NewComputed: true,
|
||||
}
|
||||
} else {
|
||||
result["foo.2800005064"] = &terraform.ResourceAttrDiff{
|
||||
Old: "",
|
||||
New: "qux",
|
||||
}
|
||||
result[fmt.Sprintf("foo.%d", HashString(fmt.Sprintf("%sbar", oldPrefix)))] = &terraform.ResourceAttrDiff{
|
||||
Old: fmt.Sprintf("%sbar", oldPrefix),
|
||||
New: "",
|
||||
NewRemoved: true,
|
||||
}
|
||||
}
|
||||
return result
|
||||
}(),
|
||||
},
|
||||
},
|
||||
{
|
||||
resourceDiffTestCase{
|
||||
Name: "basic list diff",
|
||||
Schema: map[string]*Schema{
|
||||
"foo": &Schema{
|
||||
|
@ -144,17 +167,28 @@ func TestSetNew(t *testing.T) {
|
|||
},
|
||||
},
|
||||
Key: "foo",
|
||||
OldValue: []interface{}{fmt.Sprintf("%sbar", oldPrefix)},
|
||||
NewValue: []interface{}{"qux"},
|
||||
Expected: &terraform.InstanceDiff{
|
||||
Attributes: map[string]*terraform.ResourceAttrDiff{
|
||||
"foo.0": &terraform.ResourceAttrDiff{
|
||||
Old: "bar",
|
||||
New: "qux",
|
||||
},
|
||||
},
|
||||
Attributes: func() map[string]*terraform.ResourceAttrDiff {
|
||||
result := make(map[string]*terraform.ResourceAttrDiff)
|
||||
if computed {
|
||||
result["foo.#"] = &terraform.ResourceAttrDiff{
|
||||
Old: "1",
|
||||
New: "",
|
||||
NewComputed: true,
|
||||
}
|
||||
} else {
|
||||
result["foo.0"] = &terraform.ResourceAttrDiff{
|
||||
Old: fmt.Sprintf("%sbar", oldPrefix),
|
||||
New: "qux",
|
||||
}
|
||||
}
|
||||
return result
|
||||
}(),
|
||||
},
|
||||
},
|
||||
{
|
||||
resourceDiffTestCase{
|
||||
Name: "basic map diff",
|
||||
Schema: map[string]*Schema{
|
||||
"foo": &Schema{
|
||||
|
@ -181,17 +215,33 @@ func TestSetNew(t *testing.T) {
|
|||
},
|
||||
},
|
||||
Key: "foo",
|
||||
OldValue: map[string]interface{}{"bar": fmt.Sprintf("%sbaz", oldPrefix)},
|
||||
NewValue: map[string]interface{}{"bar": "quux"},
|
||||
Expected: &terraform.InstanceDiff{
|
||||
Attributes: map[string]*terraform.ResourceAttrDiff{
|
||||
"foo.bar": &terraform.ResourceAttrDiff{
|
||||
Old: "baz",
|
||||
New: "quux",
|
||||
},
|
||||
},
|
||||
Attributes: func() map[string]*terraform.ResourceAttrDiff {
|
||||
result := make(map[string]*terraform.ResourceAttrDiff)
|
||||
if computed {
|
||||
result["foo.%"] = &terraform.ResourceAttrDiff{
|
||||
Old: "",
|
||||
New: "",
|
||||
NewComputed: true,
|
||||
}
|
||||
result["foo.bar"] = &terraform.ResourceAttrDiff{
|
||||
Old: "baz",
|
||||
New: "",
|
||||
NewRemoved: true,
|
||||
}
|
||||
} else {
|
||||
result["foo.bar"] = &terraform.ResourceAttrDiff{
|
||||
Old: fmt.Sprintf("%sbaz", oldPrefix),
|
||||
New: "quux",
|
||||
}
|
||||
}
|
||||
return result
|
||||
}(),
|
||||
},
|
||||
},
|
||||
{
|
||||
resourceDiffTestCase{
|
||||
Name: "additional diff with primitive",
|
||||
Schema: map[string]*Schema{
|
||||
"foo": &Schema{
|
||||
|
@ -212,7 +262,6 @@ func TestSetNew(t *testing.T) {
|
|||
},
|
||||
Config: testConfig(t, map[string]interface{}{
|
||||
"foo": "baz",
|
||||
"one": "three",
|
||||
}),
|
||||
Diff: &terraform.InstanceDiff{
|
||||
Attributes: map[string]*terraform.ResourceAttrDiff{
|
||||
|
@ -220,13 +269,10 @@ func TestSetNew(t *testing.T) {
|
|||
Old: "bar",
|
||||
New: "baz",
|
||||
},
|
||||
"one": &terraform.ResourceAttrDiff{
|
||||
Old: "two",
|
||||
New: "three",
|
||||
},
|
||||
},
|
||||
},
|
||||
Key: "one",
|
||||
OldValue: fmt.Sprintf("%stwo", oldPrefix),
|
||||
NewValue: "four",
|
||||
Expected: &terraform.InstanceDiff{
|
||||
Attributes: map[string]*terraform.ResourceAttrDiff{
|
||||
|
@ -235,13 +281,19 @@ func TestSetNew(t *testing.T) {
|
|||
New: "baz",
|
||||
},
|
||||
"one": &terraform.ResourceAttrDiff{
|
||||
Old: "two",
|
||||
New: "four",
|
||||
Old: fmt.Sprintf("%stwo", oldPrefix),
|
||||
New: func() string {
|
||||
if computed {
|
||||
return ""
|
||||
}
|
||||
return "four"
|
||||
}(),
|
||||
NewComputed: computed,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
resourceDiffTestCase{
|
||||
Name: "additional diff with primitive computed only",
|
||||
Schema: map[string]*Schema{
|
||||
"foo": &Schema{
|
||||
|
@ -271,6 +323,7 @@ func TestSetNew(t *testing.T) {
|
|||
},
|
||||
},
|
||||
Key: "one",
|
||||
OldValue: fmt.Sprintf("%stwo", oldPrefix),
|
||||
NewValue: "three",
|
||||
Expected: &terraform.InstanceDiff{
|
||||
Attributes: map[string]*terraform.ResourceAttrDiff{
|
||||
|
@ -279,13 +332,19 @@ func TestSetNew(t *testing.T) {
|
|||
New: "baz",
|
||||
},
|
||||
"one": &terraform.ResourceAttrDiff{
|
||||
Old: "two",
|
||||
New: "three",
|
||||
Old: fmt.Sprintf("%stwo", oldPrefix),
|
||||
New: func() string {
|
||||
if computed {
|
||||
return ""
|
||||
}
|
||||
return "three"
|
||||
}(),
|
||||
NewComputed: computed,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
resourceDiffTestCase{
|
||||
Name: "complex-ish set diff",
|
||||
Schema: map[string]*Schema{
|
||||
"top": &Schema{
|
||||
|
@ -351,6 +410,16 @@ func TestSetNew(t *testing.T) {
|
|||
},
|
||||
},
|
||||
Key: "top",
|
||||
OldValue: NewSet(testSetFunc, []interface{}{
|
||||
map[string]interface{}{
|
||||
"foo": 1,
|
||||
"bar": 4 + oldOffset,
|
||||
},
|
||||
map[string]interface{}{
|
||||
"foo": 13 + oldOffset,
|
||||
"bar": 12,
|
||||
},
|
||||
}),
|
||||
NewValue: NewSet(testSetFunc, []interface{}{
|
||||
map[string]interface{}{
|
||||
"foo": 1,
|
||||
|
@ -365,47 +434,429 @@ func TestSetNew(t *testing.T) {
|
|||
"bar": 22,
|
||||
},
|
||||
}),
|
||||
Expected: &terraform.InstanceDiff{
|
||||
Attributes: func() map[string]*terraform.ResourceAttrDiff {
|
||||
result := make(map[string]*terraform.ResourceAttrDiff)
|
||||
if computed {
|
||||
result["top.#"] = &terraform.ResourceAttrDiff{
|
||||
Old: "2",
|
||||
New: "",
|
||||
NewComputed: true,
|
||||
}
|
||||
} else {
|
||||
result["top.#"] = &terraform.ResourceAttrDiff{
|
||||
Old: "2",
|
||||
New: "3",
|
||||
}
|
||||
result["top.5.foo"] = &terraform.ResourceAttrDiff{
|
||||
Old: "",
|
||||
New: "1",
|
||||
}
|
||||
result["top.5.bar"] = &terraform.ResourceAttrDiff{
|
||||
Old: "",
|
||||
New: "4",
|
||||
}
|
||||
result["top.25.foo"] = &terraform.ResourceAttrDiff{
|
||||
Old: "",
|
||||
New: "13",
|
||||
}
|
||||
result["top.25.bar"] = &terraform.ResourceAttrDiff{
|
||||
Old: "",
|
||||
New: "12",
|
||||
}
|
||||
result["top.43.foo"] = &terraform.ResourceAttrDiff{
|
||||
Old: "",
|
||||
New: "21",
|
||||
}
|
||||
result["top.43.bar"] = &terraform.ResourceAttrDiff{
|
||||
Old: "",
|
||||
New: "22",
|
||||
}
|
||||
}
|
||||
return result
|
||||
}(),
|
||||
},
|
||||
},
|
||||
resourceDiffTestCase{
|
||||
Name: "primitive, no diff, no refresh",
|
||||
Schema: map[string]*Schema{
|
||||
"foo": &Schema{
|
||||
Type: TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
State: &terraform.InstanceState{
|
||||
Attributes: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
Config: testConfig(t, map[string]interface{}{}),
|
||||
Diff: &terraform.InstanceDiff{Attributes: map[string]*terraform.ResourceAttrDiff{}},
|
||||
Key: "foo",
|
||||
OldValue: fmt.Sprintf("%sbar", oldPrefix),
|
||||
NewValue: "baz",
|
||||
Expected: &terraform.InstanceDiff{
|
||||
Attributes: map[string]*terraform.ResourceAttrDiff{
|
||||
"top.#": &terraform.ResourceAttrDiff{
|
||||
Old: "2",
|
||||
New: "3",
|
||||
},
|
||||
"top.5.foo": &terraform.ResourceAttrDiff{
|
||||
Old: "",
|
||||
New: "1",
|
||||
},
|
||||
"top.5.bar": &terraform.ResourceAttrDiff{
|
||||
Old: "",
|
||||
New: "4",
|
||||
},
|
||||
"top.25.foo": &terraform.ResourceAttrDiff{
|
||||
Old: "",
|
||||
New: "13",
|
||||
},
|
||||
"top.25.bar": &terraform.ResourceAttrDiff{
|
||||
Old: "",
|
||||
New: "12",
|
||||
},
|
||||
"top.43.foo": &terraform.ResourceAttrDiff{
|
||||
Old: "",
|
||||
New: "21",
|
||||
},
|
||||
"top.43.bar": &terraform.ResourceAttrDiff{
|
||||
Old: "",
|
||||
New: "22",
|
||||
"foo": &terraform.ResourceAttrDiff{
|
||||
Old: fmt.Sprintf("%sbar", oldPrefix),
|
||||
New: func() string {
|
||||
if computed {
|
||||
return ""
|
||||
}
|
||||
return "baz"
|
||||
}(),
|
||||
NewComputed: computed,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
resourceDiffTestCase{
|
||||
Name: "non-computed key, should error",
|
||||
Schema: map[string]*Schema{
|
||||
"foo": &Schema{
|
||||
Type: TypeString,
|
||||
Required: true,
|
||||
},
|
||||
},
|
||||
State: &terraform.InstanceState{
|
||||
Attributes: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
Config: testConfig(t, map[string]interface{}{
|
||||
"foo": "baz",
|
||||
}),
|
||||
Diff: &terraform.InstanceDiff{
|
||||
Attributes: map[string]*terraform.ResourceAttrDiff{
|
||||
"foo": &terraform.ResourceAttrDiff{
|
||||
Old: "bar",
|
||||
New: "baz",
|
||||
},
|
||||
},
|
||||
},
|
||||
Key: "foo",
|
||||
OldValue: fmt.Sprintf("%sbar", oldPrefix),
|
||||
NewValue: "qux",
|
||||
ExpectedError: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetNew(t *testing.T) {
|
||||
testCases := testDiffCases(t, "", 0, false)
|
||||
for _, tc := range testCases {
|
||||
t.Run(fmt.Sprintf("%s", tc.Name), func(t *testing.T) {
|
||||
t.Run(tc.Name, func(t *testing.T) {
|
||||
m := schemaMap(tc.Schema)
|
||||
d := newResourceDiff(tc.Schema, nil, tc.State, tc.Diff)
|
||||
if err := d.SetNew(tc.Key, tc.NewValue); err != nil {
|
||||
err := d.SetNew(tc.Key, tc.NewValue)
|
||||
switch {
|
||||
case err != nil && !tc.ExpectedError:
|
||||
t.Fatalf("bad: %s", err)
|
||||
case err == nil && tc.ExpectedError:
|
||||
t.Fatalf("Expected error, got none")
|
||||
case err != nil && tc.ExpectedError:
|
||||
return
|
||||
}
|
||||
for _, k := range d.UpdatedKeys() {
|
||||
if err := m.diff(k, m[k], tc.Diff, d, false); err != nil {
|
||||
t.Fatalf("bad: %s", err)
|
||||
}
|
||||
}
|
||||
if !reflect.DeepEqual(tc.Expected, tc.Diff) {
|
||||
t.Fatalf("Expected %s, got %s", spew.Sdump(tc.Expected), spew.Sdump(tc.Diff))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetNewComputed(t *testing.T) {
|
||||
testCases := testDiffCases(t, "", 0, true)
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.Name, func(t *testing.T) {
|
||||
m := schemaMap(tc.Schema)
|
||||
d := newResourceDiff(tc.Schema, nil, tc.State, tc.Diff)
|
||||
err := d.SetNewComputed(tc.Key)
|
||||
switch {
|
||||
case err != nil && !tc.ExpectedError:
|
||||
t.Fatalf("bad: %s", err)
|
||||
case err == nil && tc.ExpectedError:
|
||||
t.Fatalf("Expected error, got none")
|
||||
case err != nil && tc.ExpectedError:
|
||||
return
|
||||
}
|
||||
for _, k := range d.UpdatedKeys() {
|
||||
if err := m.diff(k, m[k], tc.Diff, d, false); err != nil {
|
||||
t.Fatalf("bad: %s", err)
|
||||
}
|
||||
}
|
||||
if !reflect.DeepEqual(tc.Expected, tc.Diff) {
|
||||
t.Fatalf("Expected %s, got %s", spew.Sdump(tc.Expected), spew.Sdump(tc.Diff))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetDiff(t *testing.T) {
|
||||
testCases := testDiffCases(t, "testSetDiff", 1, false)
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.Name, func(t *testing.T) {
|
||||
m := schemaMap(tc.Schema)
|
||||
d := newResourceDiff(tc.Schema, nil, tc.State, tc.Diff)
|
||||
err := d.SetDiff(tc.Key, tc.OldValue, tc.NewValue, false)
|
||||
switch {
|
||||
case err != nil && !tc.ExpectedError:
|
||||
t.Fatalf("bad: %s", err)
|
||||
case err == nil && tc.ExpectedError:
|
||||
t.Fatalf("Expected error, got none")
|
||||
case err != nil && tc.ExpectedError:
|
||||
return
|
||||
}
|
||||
for _, k := range d.UpdatedKeys() {
|
||||
if err := m.diff(k, m[k], tc.Diff, d, false); err != nil {
|
||||
t.Fatalf("bad: %s", err)
|
||||
}
|
||||
}
|
||||
if !reflect.DeepEqual(tc.Expected, tc.Diff) {
|
||||
t.Fatalf("Expected %s, got %s", spew.Sdump(tc.Expected), spew.Sdump(tc.Diff))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestForceNew(t *testing.T) {
|
||||
cases := []resourceDiffTestCase{
|
||||
resourceDiffTestCase{
|
||||
Name: "basic primitive diff",
|
||||
Schema: map[string]*Schema{
|
||||
"foo": &Schema{
|
||||
Type: TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
State: &terraform.InstanceState{
|
||||
Attributes: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
Config: testConfig(t, map[string]interface{}{
|
||||
"foo": "baz",
|
||||
}),
|
||||
Diff: &terraform.InstanceDiff{
|
||||
Attributes: map[string]*terraform.ResourceAttrDiff{
|
||||
"foo": &terraform.ResourceAttrDiff{
|
||||
Old: "bar",
|
||||
New: "baz",
|
||||
},
|
||||
},
|
||||
},
|
||||
Key: "foo",
|
||||
Expected: &terraform.InstanceDiff{
|
||||
Attributes: map[string]*terraform.ResourceAttrDiff{
|
||||
"foo": &terraform.ResourceAttrDiff{
|
||||
Old: "bar",
|
||||
New: "baz",
|
||||
RequiresNew: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
resourceDiffTestCase{
|
||||
Name: "no change, should error",
|
||||
Schema: map[string]*Schema{
|
||||
"foo": &Schema{
|
||||
Type: TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
State: &terraform.InstanceState{
|
||||
Attributes: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
Config: testConfig(t, map[string]interface{}{
|
||||
"foo": "bar",
|
||||
}),
|
||||
ExpectedError: true,
|
||||
},
|
||||
resourceDiffTestCase{
|
||||
Name: "basic primitive, non-computed key",
|
||||
Schema: map[string]*Schema{
|
||||
"foo": &Schema{
|
||||
Type: TypeString,
|
||||
Required: true,
|
||||
},
|
||||
},
|
||||
State: &terraform.InstanceState{
|
||||
Attributes: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
Config: testConfig(t, map[string]interface{}{
|
||||
"foo": "baz",
|
||||
}),
|
||||
Diff: &terraform.InstanceDiff{
|
||||
Attributes: map[string]*terraform.ResourceAttrDiff{
|
||||
"foo": &terraform.ResourceAttrDiff{
|
||||
Old: "bar",
|
||||
New: "baz",
|
||||
},
|
||||
},
|
||||
},
|
||||
Key: "foo",
|
||||
Expected: &terraform.InstanceDiff{
|
||||
Attributes: map[string]*terraform.ResourceAttrDiff{
|
||||
"foo": &terraform.ResourceAttrDiff{
|
||||
Old: "bar",
|
||||
New: "baz",
|
||||
RequiresNew: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.Name, func(t *testing.T) {
|
||||
m := schemaMap(tc.Schema)
|
||||
d := newResourceDiff(m, nil, tc.State, tc.Diff)
|
||||
err := d.ForceNew(tc.Key)
|
||||
switch {
|
||||
case err != nil && !tc.ExpectedError:
|
||||
t.Fatalf("bad: %s", err)
|
||||
case err == nil && tc.ExpectedError:
|
||||
t.Fatalf("Expected error, got none")
|
||||
case err != nil && tc.ExpectedError:
|
||||
return
|
||||
}
|
||||
for _, k := range d.UpdatedKeys() {
|
||||
if err := m.diff(k, m[k], tc.Diff, d, false); err != nil {
|
||||
t.Fatalf("bad: %s", err)
|
||||
}
|
||||
}
|
||||
if !reflect.DeepEqual(tc.Expected, tc.Diff) {
|
||||
t.Fatalf("Expected %s, got %s", spew.Sdump(tc.Expected), spew.Sdump(tc.Diff))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestClear(t *testing.T) {
|
||||
cases := []resourceDiffTestCase{
|
||||
resourceDiffTestCase{
|
||||
Name: "basic primitive diff",
|
||||
Schema: map[string]*Schema{
|
||||
"foo": &Schema{
|
||||
Type: TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
State: &terraform.InstanceState{
|
||||
Attributes: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
Config: testConfig(t, map[string]interface{}{
|
||||
"foo": "baz",
|
||||
}),
|
||||
Diff: &terraform.InstanceDiff{
|
||||
Attributes: map[string]*terraform.ResourceAttrDiff{
|
||||
"foo": &terraform.ResourceAttrDiff{
|
||||
Old: "bar",
|
||||
New: "baz",
|
||||
},
|
||||
},
|
||||
},
|
||||
Key: "foo",
|
||||
Expected: &terraform.InstanceDiff{Attributes: map[string]*terraform.ResourceAttrDiff{}},
|
||||
},
|
||||
resourceDiffTestCase{
|
||||
Name: "non-computed key, should error",
|
||||
Schema: map[string]*Schema{
|
||||
"foo": &Schema{
|
||||
Type: TypeString,
|
||||
Required: true,
|
||||
},
|
||||
},
|
||||
State: &terraform.InstanceState{
|
||||
Attributes: map[string]string{
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
Config: testConfig(t, map[string]interface{}{
|
||||
"foo": "baz",
|
||||
}),
|
||||
Diff: &terraform.InstanceDiff{
|
||||
Attributes: map[string]*terraform.ResourceAttrDiff{
|
||||
"foo": &terraform.ResourceAttrDiff{
|
||||
Old: "bar",
|
||||
New: "baz",
|
||||
},
|
||||
},
|
||||
},
|
||||
Key: "foo",
|
||||
ExpectedError: true,
|
||||
},
|
||||
resourceDiffTestCase{
|
||||
Name: "multi-value, one removed",
|
||||
Schema: map[string]*Schema{
|
||||
"foo": &Schema{
|
||||
Type: TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"one": &Schema{
|
||||
Type: TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
State: &terraform.InstanceState{
|
||||
Attributes: map[string]string{
|
||||
"foo": "bar",
|
||||
"one": "two",
|
||||
},
|
||||
},
|
||||
Config: testConfig(t, map[string]interface{}{
|
||||
"foo": "baz",
|
||||
"one": "three",
|
||||
}),
|
||||
Diff: &terraform.InstanceDiff{
|
||||
Attributes: map[string]*terraform.ResourceAttrDiff{
|
||||
"foo": &terraform.ResourceAttrDiff{
|
||||
Old: "bar",
|
||||
New: "baz",
|
||||
},
|
||||
"one": &terraform.ResourceAttrDiff{
|
||||
Old: "two",
|
||||
New: "three",
|
||||
},
|
||||
},
|
||||
},
|
||||
Key: "one",
|
||||
Expected: &terraform.InstanceDiff{
|
||||
Attributes: map[string]*terraform.ResourceAttrDiff{
|
||||
"foo": &terraform.ResourceAttrDiff{
|
||||
Old: "bar",
|
||||
New: "baz",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.Name, func(t *testing.T) {
|
||||
m := schemaMap(tc.Schema)
|
||||
d := newResourceDiff(m, nil, tc.State, tc.Diff)
|
||||
err := d.Clear(tc.Key)
|
||||
switch {
|
||||
case err != nil && !tc.ExpectedError:
|
||||
t.Fatalf("bad: %s", err)
|
||||
case err == nil && tc.ExpectedError:
|
||||
t.Fatalf("Expected error, got none")
|
||||
case err != nil && tc.ExpectedError:
|
||||
return
|
||||
}
|
||||
for _, k := range d.UpdatedKeys() {
|
||||
if err := m.diff(k, m[k], tc.Diff, d, false); err != nil {
|
||||
|
|
|
@ -5022,3 +5022,17 @@ func (e errorSort) Swap(i, j int) { e[i], e[j] = e[j], e[i] }
|
|||
func (e errorSort) Less(i, j int) bool {
|
||||
return e[i].Error() < e[j].Error()
|
||||
}
|
||||
|
||||
func TestSchemaMapDeepCopy(t *testing.T) {
|
||||
schema := map[string]*Schema{
|
||||
"foo": &Schema{
|
||||
Type: TypeString,
|
||||
},
|
||||
}
|
||||
source := schemaMap(schema)
|
||||
dest := source.DeepCopy()
|
||||
dest["foo"].ForceNew = true
|
||||
if reflect.DeepEqual(source, dest) {
|
||||
t.Fatalf("source and dest should not match")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue