github.com/ndarilek/terraform@v0.3.8-0.20150320140257-d3135c1b2bac/helper/schema/field_reader_config_test.go (about)

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