github.com/andresvia/terraform@v0.6.15-0.20160412045437-d51c75946785/helper/schema/field_reader_config_test.go (about)

     1  package schema
     2  
     3  import (
     4  	"reflect"
     5  	"testing"
     6  
     7  	"github.com/hashicorp/hil/ast"
     8  	"github.com/hashicorp/terraform/config"
     9  	"github.com/hashicorp/terraform/terraform"
    10  )
    11  
    12  func TestConfigFieldReader_impl(t *testing.T) {
    13  	var _ FieldReader = new(ConfigFieldReader)
    14  }
    15  
    16  func TestConfigFieldReader(t *testing.T) {
    17  	testFieldReader(t, func(s map[string]*Schema) FieldReader {
    18  		return &ConfigFieldReader{
    19  			Schema: s,
    20  
    21  			Config: testConfig(t, map[string]interface{}{
    22  				"bool":   true,
    23  				"float":  3.1415,
    24  				"int":    42,
    25  				"string": "string",
    26  
    27  				"list": []interface{}{"foo", "bar"},
    28  
    29  				"listInt": []interface{}{21, 42},
    30  
    31  				"map": map[string]interface{}{
    32  					"foo": "bar",
    33  					"bar": "baz",
    34  				},
    35  
    36  				"set": []interface{}{10, 50},
    37  				"setDeep": []interface{}{
    38  					map[string]interface{}{
    39  						"index": 10,
    40  						"value": "foo",
    41  					},
    42  					map[string]interface{}{
    43  						"index": 50,
    44  						"value": "bar",
    45  					},
    46  				},
    47  			}),
    48  		}
    49  	})
    50  }
    51  
    52  func TestConfigFieldReader_DefaultHandling(t *testing.T) {
    53  	schema := map[string]*Schema{
    54  		"strWithDefault": &Schema{
    55  			Type:    TypeString,
    56  			Default: "ImADefault",
    57  		},
    58  		"strWithDefaultFunc": &Schema{
    59  			Type: TypeString,
    60  			DefaultFunc: func() (interface{}, error) {
    61  				return "FuncDefault", nil
    62  			},
    63  		},
    64  	}
    65  
    66  	cases := map[string]struct {
    67  		Addr   []string
    68  		Result FieldReadResult
    69  		Config *terraform.ResourceConfig
    70  		Err    bool
    71  	}{
    72  		"gets default value when no config set": {
    73  			[]string{"strWithDefault"},
    74  			FieldReadResult{
    75  				Value:    "ImADefault",
    76  				Exists:   true,
    77  				Computed: false,
    78  			},
    79  			testConfig(t, map[string]interface{}{}),
    80  			false,
    81  		},
    82  		"config overrides default value": {
    83  			[]string{"strWithDefault"},
    84  			FieldReadResult{
    85  				Value:    "fromConfig",
    86  				Exists:   true,
    87  				Computed: false,
    88  			},
    89  			testConfig(t, map[string]interface{}{
    90  				"strWithDefault": "fromConfig",
    91  			}),
    92  			false,
    93  		},
    94  		"gets default from function when no config set": {
    95  			[]string{"strWithDefaultFunc"},
    96  			FieldReadResult{
    97  				Value:    "FuncDefault",
    98  				Exists:   true,
    99  				Computed: false,
   100  			},
   101  			testConfig(t, map[string]interface{}{}),
   102  			false,
   103  		},
   104  		"config overrides default function": {
   105  			[]string{"strWithDefaultFunc"},
   106  			FieldReadResult{
   107  				Value:    "fromConfig",
   108  				Exists:   true,
   109  				Computed: false,
   110  			},
   111  			testConfig(t, map[string]interface{}{
   112  				"strWithDefaultFunc": "fromConfig",
   113  			}),
   114  			false,
   115  		},
   116  	}
   117  
   118  	for name, tc := range cases {
   119  		r := &ConfigFieldReader{
   120  			Schema: schema,
   121  			Config: tc.Config,
   122  		}
   123  		out, err := r.ReadField(tc.Addr)
   124  		if err != nil != tc.Err {
   125  			t.Fatalf("%s: err: %s", name, err)
   126  		}
   127  		if s, ok := out.Value.(*Set); ok {
   128  			// If it is a set, convert to a list so its more easily checked.
   129  			out.Value = s.List()
   130  		}
   131  		if !reflect.DeepEqual(tc.Result, out) {
   132  			t.Fatalf("%s: bad: %#v", name, out)
   133  		}
   134  	}
   135  }
   136  
   137  func TestConfigFieldReader_ComputedMap(t *testing.T) {
   138  	schema := map[string]*Schema{
   139  		"map": &Schema{
   140  			Type:     TypeMap,
   141  			Computed: true,
   142  		},
   143  	}
   144  
   145  	cases := map[string]struct {
   146  		Addr   []string
   147  		Result FieldReadResult
   148  		Config *terraform.ResourceConfig
   149  		Err    bool
   150  	}{
   151  		"set, normal": {
   152  			[]string{"map"},
   153  			FieldReadResult{
   154  				Value: map[string]interface{}{
   155  					"foo": "bar",
   156  				},
   157  				Exists:   true,
   158  				Computed: false,
   159  			},
   160  			testConfig(t, map[string]interface{}{
   161  				"map": map[string]interface{}{
   162  					"foo": "bar",
   163  				},
   164  			}),
   165  			false,
   166  		},
   167  
   168  		"computed element": {
   169  			[]string{"map"},
   170  			FieldReadResult{
   171  				Exists:   true,
   172  				Computed: true,
   173  			},
   174  			testConfigInterpolate(t, map[string]interface{}{
   175  				"map": map[string]interface{}{
   176  					"foo": "${var.foo}",
   177  				},
   178  			}, map[string]ast.Variable{
   179  				"var.foo": ast.Variable{
   180  					Value: config.UnknownVariableValue,
   181  					Type:  ast.TypeString,
   182  				},
   183  			}),
   184  			false,
   185  		},
   186  	}
   187  
   188  	for name, tc := range cases {
   189  		r := &ConfigFieldReader{
   190  			Schema: schema,
   191  			Config: tc.Config,
   192  		}
   193  		out, err := r.ReadField(tc.Addr)
   194  		if err != nil != tc.Err {
   195  			t.Fatalf("%s: err: %s", name, err)
   196  		}
   197  		if s, ok := out.Value.(*Set); ok {
   198  			// If it is a set, convert to the raw map
   199  			out.Value = s.m
   200  			if len(s.m) == 0 {
   201  				out.Value = nil
   202  			}
   203  		}
   204  		if !reflect.DeepEqual(tc.Result, out) {
   205  			t.Fatalf("%s: bad: %#v", name, out)
   206  		}
   207  	}
   208  }
   209  
   210  func TestConfigFieldReader_ComputedSet(t *testing.T) {
   211  	schema := map[string]*Schema{
   212  		"strSet": &Schema{
   213  			Type: TypeSet,
   214  			Elem: &Schema{Type: TypeString},
   215  			Set:  HashString,
   216  		},
   217  	}
   218  
   219  	cases := map[string]struct {
   220  		Addr   []string
   221  		Result FieldReadResult
   222  		Config *terraform.ResourceConfig
   223  		Err    bool
   224  	}{
   225  		"set, normal": {
   226  			[]string{"strSet"},
   227  			FieldReadResult{
   228  				Value: map[string]interface{}{
   229  					"2356372769": "foo",
   230  				},
   231  				Exists:   true,
   232  				Computed: false,
   233  			},
   234  			testConfig(t, map[string]interface{}{
   235  				"strSet": []interface{}{"foo"},
   236  			}),
   237  			false,
   238  		},
   239  
   240  		"set, computed element": {
   241  			[]string{"strSet"},
   242  			FieldReadResult{
   243  				Value:    nil,
   244  				Exists:   true,
   245  				Computed: true,
   246  			},
   247  			testConfigInterpolate(t, map[string]interface{}{
   248  				"strSet": []interface{}{"${var.foo}"},
   249  			}, map[string]ast.Variable{
   250  				"var.foo": ast.Variable{
   251  					Value: config.UnknownVariableValue,
   252  					Type:  ast.TypeString,
   253  				},
   254  			}),
   255  			false,
   256  		},
   257  
   258  		"set, computed element substring": {
   259  			[]string{"strSet"},
   260  			FieldReadResult{
   261  				Value:    nil,
   262  				Exists:   true,
   263  				Computed: true,
   264  			},
   265  			testConfigInterpolate(t, map[string]interface{}{
   266  				"strSet": []interface{}{"${var.foo}/32"},
   267  			}, map[string]ast.Variable{
   268  				"var.foo": ast.Variable{
   269  					Value: config.UnknownVariableValue,
   270  					Type:  ast.TypeString,
   271  				},
   272  			}),
   273  			false,
   274  		},
   275  	}
   276  
   277  	for name, tc := range cases {
   278  		r := &ConfigFieldReader{
   279  			Schema: schema,
   280  			Config: tc.Config,
   281  		}
   282  		out, err := r.ReadField(tc.Addr)
   283  		if err != nil != tc.Err {
   284  			t.Fatalf("%s: err: %s", name, err)
   285  		}
   286  		if s, ok := out.Value.(*Set); ok {
   287  			// If it is a set, convert to the raw map
   288  			out.Value = s.m
   289  			if len(s.m) == 0 {
   290  				out.Value = nil
   291  			}
   292  		}
   293  		if !reflect.DeepEqual(tc.Result, out) {
   294  			t.Fatalf("%s: bad: %#v", name, out)
   295  		}
   296  	}
   297  }
   298  
   299  func testConfig(
   300  	t *testing.T, raw map[string]interface{}) *terraform.ResourceConfig {
   301  	return testConfigInterpolate(t, raw, nil)
   302  }
   303  
   304  func testConfigInterpolate(
   305  	t *testing.T,
   306  	raw map[string]interface{},
   307  	vs map[string]ast.Variable) *terraform.ResourceConfig {
   308  	rc, err := config.NewRawConfig(raw)
   309  	if err != nil {
   310  		t.Fatalf("err: %s", err)
   311  	}
   312  	if len(vs) > 0 {
   313  		if err := rc.Interpolate(vs); err != nil {
   314  			t.Fatalf("err: %s", err)
   315  		}
   316  	}
   317  
   318  	return terraform.NewResourceConfig(rc)
   319  }