}
_, err = arvados.NewVocabulary(vd, mk)
if err != nil {
- fmt.Fprintf(stderr, "Error loading vocabulary file %q for cluster %s: %s\n", cc.API.VocabularyPath, id, err)
+ fmt.Fprintf(stderr, "Error loading vocabulary file %q for cluster %s:\n%s\n", cc.API.VocabularyPath, id, err)
return 1
}
}
`
code := CheckCommand.RunCommand("arvados config-check", []string{"-config", "-"}, bytes.NewBufferString(in), &stdout, &stderr)
c.Check(code, check.Equals, 1)
- c.Check(stderr.String(), check.Matches, `(?s).*Error loading vocabulary file.*duplicate JSON key\(s\).*`)
+ c.Check(stderr.String(), check.Matches, `(?s).*Error loading vocabulary file.*for cluster.*\nduplicate JSON key "tags.IDfoo".*`)
}
func (s *CommandSuite) TestCheck_DeprecatedKeys(c *check.C) {
}
return nil, fmt.Errorf("invalid JSON format: %q", err)
}
- // json.Unmarshal() doesn't error out on duplicate keys.
- err = checkJSONDupedKeys(json.NewDecoder(bytes.NewReader(data)), nil, &[]string{})
- if err != nil {
- return nil, err
- }
if reflect.DeepEqual(voc, &Vocabulary{}) {
return nil, fmt.Errorf("JSON data provided doesn't match Vocabulary format: %q", data)
}
+
+ shouldReportErrors := false
+ errors := []string{}
+
+ // json.Unmarshal() doesn't error out on duplicate keys.
+ dupedKeys := []string{}
+ err = checkJSONDupedKeys(json.NewDecoder(bytes.NewReader(data)), nil, &dupedKeys)
+ if err != nil {
+ shouldReportErrors = true
+ for _, dk := range dupedKeys {
+ errors = append(errors, fmt.Sprintf("duplicate JSON key %q", dk))
+ }
+ }
voc.reservedTagKeys = make(map[string]bool)
for _, managedKey := range managedTagKeys {
voc.reservedTagKeys[managedKey] = true
for systemKey := range voc.systemTagKeys() {
voc.reservedTagKeys[systemKey] = true
}
- err = voc.validate()
+ validationErrs, err := voc.validate()
if err != nil {
- return nil, err
+ shouldReportErrors = true
+ errors = append(errors, validationErrs...)
+ }
+ if shouldReportErrors {
+ return nil, fmt.Errorf("%s", strings.Join(errors, "\n"))
}
return voc, nil
}
}
}
if len(path) == 0 && len(*errors) > 0 {
- return fmt.Errorf("duplicate JSON key(s):\n%s", strings.Join(*errors, "\n"))
+ return fmt.Errorf("duplicate JSON key(s) found")
}
return nil
}
-func (v *Vocabulary) validate() error {
+func (v *Vocabulary) validate() ([]string, error) {
if v == nil {
- return nil
+ return nil, nil
}
tagKeys := map[string]string{}
// Checks for Vocabulary strictness
if v.StrictTags && len(v.Tags) == 0 {
- return fmt.Errorf("vocabulary is strict but no tags are defined")
+ return nil, fmt.Errorf("vocabulary is strict but no tags are defined")
}
// Checks for collisions between tag keys, reserved tag keys
// and tag key labels.
}
}
if len(errors) > 0 {
- return fmt.Errorf("invalid vocabulary:\n%s", strings.Join(errors, "\n"))
+ return errors, fmt.Errorf("invalid vocabulary")
}
- return nil
+ return nil, nil
}
func (v *Vocabulary) getLabelsToKeys() (labels map[string]string) {
import (
"encoding/json"
+ "regexp"
+ "strings"
check "gopkg.in/check.v1"
)
},
},
}
- err := s.testVoc.validate()
+ _, err := s.testVoc.validate()
c.Assert(err, check.IsNil)
}
false, `invalid JSON format:.*\(line \d+, column \d+\)`, nil,
},
{
- "Invalid JSON with duplicate keys",
+ "Invalid JSON with duplicate & reserved keys",
`{"tags":{
"type":{
"strict": false,
"labels": []
}
}}`,
- false, "(?s).*tags.type.labels.0.label\ntags.type", nil,
- },
- {
- "Valid data, but uses reserved key",
- `{"tags":{
- "type":{
- "strict": false,
- "labels": [{"label": "Class"}]
- }
- }}`,
- false, "(?s).*tag key.*is reserved", nil,
+ false, "(?s).*duplicate JSON key \"tags.type.labels.0.label\"\nduplicate JSON key \"tags.type\"\ntag key \"type\" is reserved", nil,
},
}
}
for _, tt := range tests {
c.Log(c.TestName()+" ", tt.name)
- err := tt.voc.validate()
+ validationErrs, err := tt.voc.validate()
c.Assert(err, check.NotNil)
for _, errMatch := range tt.errMatches {
- c.Assert(err, check.ErrorMatches, errMatch)
+ seen := false
+ for _, validationErr := range validationErrs {
+ if regexp.MustCompile(errMatch).MatchString(validationErr) {
+ seen = true
+ break
+ }
+ }
+ if len(validationErrs) == 0 {
+ c.Assert(err, check.ErrorMatches, errMatch)
+ } else {
+ c.Assert(seen, check.Equals, true,
+ check.Commentf("Expected to see error matching %q:\n%s",
+ errMatch, strings.Join(validationErrs, "\n")))
+ }
}
}
}