예제 #1
0
파일: validate.go 프로젝트: hanscj1/mantle
// parseCloudConfig parses the provided config into a node structure and logs
// any parsing issues into the provided report. Unrecoverable errors are
// returned as an error.
func parseCloudConfig(cfg []byte, report *Report) (node, error) {
	yaml.UnmarshalMappingKeyTransform = func(nameIn string) (nameOut string) {
		return nameIn
	}
	// unmarshal the config into an implicitly-typed form. The yaml library
	// will implicitly convert types into their normalized form
	// (e.g. 0744 -> 484, off -> false).
	var weak map[interface{}]interface{}
	if err := yaml.Unmarshal(cfg, &weak); err != nil {
		matches := yamlLineError.FindStringSubmatch(err.Error())
		if len(matches) == 3 {
			line, err := strconv.Atoi(matches[1])
			if err != nil {
				return node{}, err
			}
			msg := matches[2]
			report.Error(line, msg)
			return node{}, nil
		}

		matches = yamlError.FindStringSubmatch(err.Error())
		if len(matches) == 2 {
			report.Error(1, matches[1])
			return node{}, nil
		}

		return node{}, errors.New("couldn't parse yaml error")
	}
	w := NewNode(weak, NewContext(cfg))
	w = normalizeNodeNames(w, report)

	// unmarshal the config into the explicitly-typed form.
	yaml.UnmarshalMappingKeyTransform = func(nameIn string) (nameOut string) {
		return strings.Replace(nameIn, "-", "_", -1)
	}
	var strong config.CloudConfig
	if err := yaml.Unmarshal([]byte(cfg), &strong); err != nil {
		return node{}, err
	}
	s := NewNode(strong, NewContext(cfg))

	// coerceNodes weak nodes and strong nodes. strong nodes replace weak nodes
	// if they are compatible types (this happens when the yaml library
	// converts the input).
	// (e.g. weak 484 is replaced by strong 0744, weak 4 is not replaced by
	// strong false)
	return coerceNodes(w, s), nil
}
예제 #2
0
func (s *S) TestUnmarshalErrors(c *C) {
	for _, item := range unmarshalErrorTests {
		var value interface{}
		err := yaml.Unmarshal([]byte(item.data), &value)
		c.Assert(err, ErrorMatches, item.error, Commentf("Partial unmarshal: %#v", value))
	}
}
예제 #3
0
func (s *S) TestUnmarshal(c *C) {
	for i, item := range unmarshalTests {
		t := reflect.ValueOf(item.value).Type()
		var value interface{}
		switch t.Kind() {
		case reflect.Map:
			value = reflect.MakeMap(t).Interface()
		case reflect.String:
			t := reflect.ValueOf(item.value).Type()
			v := reflect.New(t)
			value = v.Interface()
		default:
			pt := reflect.ValueOf(item.value).Type()
			pv := reflect.New(pt.Elem())
			value = pv.Interface()
		}
		err := yaml.Unmarshal([]byte(item.data), value)
		c.Assert(err, IsNil, Commentf("Item #%d", i))
		if t.Kind() == reflect.String {
			c.Assert(*value.(*string), Equals, item.value, Commentf("Item #%d", i))
		} else {
			c.Assert(value, DeepEquals, item.value, Commentf("Item #%d", i))
		}
	}
}
예제 #4
0
func (s *S) TestUnmarshalWholeDocumentWithSetter(c *C) {
	obj := &typeWithSetter{}
	err := yaml.Unmarshal([]byte(setterTests[0].data), obj)
	c.Assert(err, IsNil)
	c.Assert(obj.tag, Equals, setterTests[0].tag)
	value, ok := obj.value.(map[interface{}]interface{})
	c.Assert(ok, Equals, true)
	c.Assert(value["_"], DeepEquals, setterTests[0].value)
}
예제 #5
0
func (s *S) TestUnmarshalWithValueSetter(c *C) {
	for _, item := range setterTests {
		obj := &setterValueType{}
		err := yaml.Unmarshal([]byte(item.data), obj)
		c.Assert(err, IsNil)
		c.Assert(obj.Field, NotNil, Commentf("Pointer not initialized (%#v)", item.value))
		c.Assert(obj.Field.tag, Equals, item.tag)
		c.Assert(obj.Field.value, DeepEquals, item.value)
	}
}
예제 #6
0
func (s *S) TestUnmarshalNull(c *C) {
	for _, test := range unmarshalNullTests {
		item := test()
		zero := reflect.Zero(reflect.TypeOf(item).Elem()).Interface()
		err := yaml.Unmarshal([]byte("null"), item)
		c.Assert(err, IsNil)
		if reflect.TypeOf(item).Kind() == reflect.Map {
			c.Assert(reflect.ValueOf(item).Interface(), DeepEquals, reflect.MakeMap(reflect.TypeOf(item)).Interface())
		} else {
			c.Assert(reflect.ValueOf(item).Elem().Interface(), DeepEquals, zero)
		}
	}
}
예제 #7
0
func (s *S) TestUnmarshalWithTransform(c *C) {
	data := `{a_b: 1, c-d: 2, e-f_g: 3, h_i-j: 4}`
	expect := map[string]int{
		"a_b":   1,
		"c_d":   2,
		"e_f_g": 3,
		"h_i_j": 4,
	}
	m := map[string]int{}
	yaml.UnmarshalMappingKeyTransform = func(i string) string {
		return strings.Replace(i, "-", "_", -1)
	}
	err := yaml.Unmarshal([]byte(data), m)
	c.Assert(err, IsNil)
	c.Assert(m, DeepEquals, expect)
}
예제 #8
0
func (s *S) TestMergeStruct(c *C) {
	type Data struct {
		X, Y, R int
		Label   string
	}
	want := Data{1, 2, 10, "center/big"}

	var m map[string]Data
	err := yaml.Unmarshal([]byte(mergeTests), &m)
	c.Assert(err, IsNil)
	for name, test := range m {
		if name == "anchors" {
			continue
		}
		c.Assert(test, Equals, want, Commentf("test %q failed", name))
	}
}
예제 #9
0
func (s *S) TestMerge(c *C) {
	var want = map[interface{}]interface{}{
		"x":     1,
		"y":     2,
		"r":     10,
		"label": "center/big",
	}

	var m map[string]interface{}
	err := yaml.Unmarshal([]byte(mergeTests), &m)
	c.Assert(err, IsNil)
	for name, test := range m {
		if name == "anchors" {
			continue
		}
		c.Assert(test, DeepEquals, want, Commentf("test %q failed", name))
	}
}
예제 #10
0
func (s *S) TestUnmarshalWithFalseSetterIgnoresValue(c *C) {
	setterResult[2] = false
	setterResult[4] = false
	defer func() {
		delete(setterResult, 2)
		delete(setterResult, 4)
	}()

	m := map[string]*typeWithSetter{}
	data := `{abc: 1, def: 2, ghi: 3, jkl: 4}`
	err := yaml.Unmarshal([]byte(data), m)
	c.Assert(err, IsNil)
	c.Assert(m["abc"], NotNil)
	c.Assert(m["def"], IsNil)
	c.Assert(m["ghi"], NotNil)
	c.Assert(m["jkl"], IsNil)

	c.Assert(m["abc"].value, Equals, 1)
	c.Assert(m["ghi"].value, Equals, 3)
}
예제 #11
0
func (s *S) TestUnmarshalNaN(c *C) {
	value := map[string]interface{}{}
	err := yaml.Unmarshal([]byte("notanum: .NaN"), &value)
	c.Assert(err, IsNil)
	c.Assert(math.IsNaN(value["notanum"].(float64)), Equals, true)
}