@ -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" ,
"foo" : & terraform . ResourceAttrDiff {
Old : fmt . Sprintf ( "%sbar" , oldPrefix ) ,
New : func ( ) string {
if computed {
return ""
}
return "baz"
} ( ) ,
NewComputed : computed ,
} ,
"top.5.bar" : & terraform . ResourceAttrDiff {
Old : "" ,
New : "4" ,
} ,
} ,
} ,
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" ,
} ,
"top.25.foo" : & terraform . ResourceAttrDiff {
Old : "" ,
New : "13" ,
} ,
} ,
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 ( tc . Name , func ( t * testing . T ) {
m := schemaMap ( tc . Schema )
d := newResourceDiff ( tc . Schema , nil , tc . State , tc . Diff )
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" ,
} ,
"top.25.bar" : & terraform . ResourceAttrDiff {
Old : "" ,
New : "12" ,
} ,
} ,
Key : "foo" ,
Expected : & terraform . InstanceDiff {
Attributes : map [ string ] * terraform . ResourceAttrDiff {
"foo" : & terraform . ResourceAttrDiff {
Old : "bar" ,
New : "baz" ,
RequiresNew : true ,
} ,
"top.43.foo" : & terraform . ResourceAttrDiff {
Old : "" ,
New : "21" ,
} ,
} ,
} ,
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" ,
} ,
"top.43.bar" : & terraform . ResourceAttrDiff {
Old : "" ,
New : "22" ,
} ,
} ,
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 ) )
}
} )
}
}
for _ , tc := range testCases {
t . Run ( fmt . Sprintf ( "%s" , tc . Name ) , func ( t * testing . T ) {
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 ( tc . Schema , nil , tc . State , tc . Diff )
if err := d . SetNew ( tc . Key , tc . NewValue ) ; err != nil {
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 {