github.com/bigkraig/terraform@v0.6.4-0.20151219155159-c90d1b074e31/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_ComputedMap(t *testing.T) {
   139  	schema := map[string]*Schema{
   140  		"map": &Schema{
   141  			Type:     TypeMap,
   142  			Computed: true,
   143  		},
   144  	}
   145  
   146  	cases := map[string]struct {
   147  		Addr   []string
   148  		Result FieldReadResult
   149  		Config *terraform.ResourceConfig
   150  		Err    bool
   151  	}{
   152  		"set, normal": {
   153  			[]string{"map"},
   154  			FieldReadResult{
   155  				Value: map[string]interface{}{
   156  					"foo": "bar",
   157  				},
   158  				Exists:   true,
   159  				Computed: false,
   160  			},
   161  			testConfig(t, map[string]interface{}{
   162  				"map": map[string]interface{}{
   163  					"foo": "bar",
   164  				},
   165  			}),
   166  			false,
   167  		},
   168  
   169  		"computed element": {
   170  			[]string{"map"},
   171  			FieldReadResult{
   172  				Exists:   true,
   173  				Computed: true,
   174  			},
   175  			testConfigInterpolate(t, map[string]interface{}{
   176  				"map": map[string]interface{}{
   177  					"foo": "${var.foo}",
   178  				},
   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  
   189  	for name, tc := range cases {
   190  		r := &ConfigFieldReader{
   191  			Schema: schema,
   192  			Config: tc.Config,
   193  		}
   194  		out, err := r.ReadField(tc.Addr)
   195  		if err != nil != tc.Err {
   196  			t.Fatalf("%s: err: %s", name, err)
   197  		}
   198  		if s, ok := out.Value.(*Set); ok {
   199  			// If it is a set, convert to the raw map
   200  			out.Value = s.m
   201  			if len(s.m) == 0 {
   202  				out.Value = nil
   203  			}
   204  		}
   205  		if !reflect.DeepEqual(tc.Result, out) {
   206  			t.Fatalf("%s: bad: %#v", name, out)
   207  		}
   208  	}
   209  }
   210  
   211  func TestConfigFieldReader_ComputedSet(t *testing.T) {
   212  	schema := map[string]*Schema{
   213  		"strSet": &Schema{
   214  			Type: TypeSet,
   215  			Elem: &Schema{Type: TypeString},
   216  			Set: func(v interface{}) int {
   217  				return hashcode.String(v.(string))
   218  			},
   219  		},
   220  	}
   221  
   222  	cases := map[string]struct {
   223  		Addr   []string
   224  		Result FieldReadResult
   225  		Config *terraform.ResourceConfig
   226  		Err    bool
   227  	}{
   228  		"set, normal": {
   229  			[]string{"strSet"},
   230  			FieldReadResult{
   231  				Value: map[string]interface{}{
   232  					"2356372769": "foo",
   233  				},
   234  				Exists:   true,
   235  				Computed: false,
   236  			},
   237  			testConfig(t, map[string]interface{}{
   238  				"strSet": []interface{}{"foo"},
   239  			}),
   240  			false,
   241  		},
   242  
   243  		"set, computed element": {
   244  			[]string{"strSet"},
   245  			FieldReadResult{
   246  				Value:    nil,
   247  				Exists:   true,
   248  				Computed: true,
   249  			},
   250  			testConfigInterpolate(t, map[string]interface{}{
   251  				"strSet": []interface{}{"${var.foo}"},
   252  			}, map[string]ast.Variable{
   253  				"var.foo": ast.Variable{
   254  					Value: config.UnknownVariableValue,
   255  					Type:  ast.TypeString,
   256  				},
   257  			}),
   258  			false,
   259  		},
   260  
   261  		"set, computed element substring": {
   262  			[]string{"strSet"},
   263  			FieldReadResult{
   264  				Value:    nil,
   265  				Exists:   true,
   266  				Computed: true,
   267  			},
   268  			testConfigInterpolate(t, map[string]interface{}{
   269  				"strSet": []interface{}{"${var.foo}/32"},
   270  			}, map[string]ast.Variable{
   271  				"var.foo": ast.Variable{
   272  					Value: config.UnknownVariableValue,
   273  					Type:  ast.TypeString,
   274  				},
   275  			}),
   276  			false,
   277  		},
   278  	}
   279  
   280  	for name, tc := range cases {
   281  		r := &ConfigFieldReader{
   282  			Schema: schema,
   283  			Config: tc.Config,
   284  		}
   285  		out, err := r.ReadField(tc.Addr)
   286  		if err != nil != tc.Err {
   287  			t.Fatalf("%s: err: %s", name, err)
   288  		}
   289  		if s, ok := out.Value.(*Set); ok {
   290  			// If it is a set, convert to the raw map
   291  			out.Value = s.m
   292  			if len(s.m) == 0 {
   293  				out.Value = nil
   294  			}
   295  		}
   296  		if !reflect.DeepEqual(tc.Result, out) {
   297  			t.Fatalf("%s: bad: %#v", name, out)
   298  		}
   299  	}
   300  }
   301  
   302  func testConfig(
   303  	t *testing.T, raw map[string]interface{}) *terraform.ResourceConfig {
   304  	return testConfigInterpolate(t, raw, nil)
   305  }
   306  
   307  func testConfigInterpolate(
   308  	t *testing.T,
   309  	raw map[string]interface{},
   310  	vs map[string]ast.Variable) *terraform.ResourceConfig {
   311  	rc, err := config.NewRawConfig(raw)
   312  	if err != nil {
   313  		t.Fatalf("err: %s", err)
   314  	}
   315  	if len(vs) > 0 {
   316  		if err := rc.Interpolate(vs); err != nil {
   317  			t.Fatalf("err: %s", err)
   318  		}
   319  	}
   320  
   321  	return terraform.NewResourceConfig(rc)
   322  }