Merge branch '18298-lsf-no-suitable-hosts'
[arvados.git] / sdk / go / arvados / vocabulary_test.go
index 7986a8252268ac7a20ea7b35d3fd0a8387565e0b..5a5189de2b3e1c9d66d6c818bd1ce1f11554bf17 100644 (file)
@@ -56,7 +56,7 @@ func (s *VocabularySuite) SetUpTest(c *check.C) {
                        },
                },
        }
-       err := s.testVoc.Validate()
+       err := s.testVoc.validate()
        c.Assert(err, check.IsNil)
 }
 
@@ -66,22 +66,122 @@ func (s *VocabularySuite) TestCheck(c *check.C) {
                strictVoc     bool
                props         string
                expectSuccess bool
+               errMatches    string
        }{
                // Check succeeds
-               {"Known key, known value", false, `{"IDTAGANIMALS":"IDVALANIMAL1"}`, true},
-               {"Unknown non-alias key on non-strict vocabulary", false, `{"foo":"bar"}`, true},
-               {"Known non-strict key, unknown non-alias value", false, `{"IDTAGANIMALS":"IDVALANIMAL3"}`, true},
-               {"Undefined but reserved key on strict vocabulary", true, `{"reservedKey":"bar"}`, true},
-               {"Known key, list of known values", false, `{"IDTAGANIMALS":["IDVALANIMAL1","IDVALANIMAL2"]}`, true},
-               {"Known non-strict key, list of unknown non-alias values", false, `{"IDTAGCOMMENT":["hello world","lorem ipsum"]}`, true},
+               {
+                       "Known key, known value",
+                       false,
+                       `{"IDTAGANIMALS":"IDVALANIMAL1"}`,
+                       true,
+                       "",
+               },
+               {
+                       "Unknown non-alias key on non-strict vocabulary",
+                       false,
+                       `{"foo":"bar"}`,
+                       true,
+                       "",
+               },
+               {
+                       "Known non-strict key, unknown non-alias value",
+                       false,
+                       `{"IDTAGANIMALS":"IDVALANIMAL3"}`,
+                       true,
+                       "",
+               },
+               {
+                       "Undefined but reserved key on strict vocabulary",
+                       true,
+                       `{"reservedKey":"bar"}`,
+                       true,
+                       "",
+               },
+               {
+                       "Known key, list of known values",
+                       false,
+                       `{"IDTAGANIMALS":["IDVALANIMAL1","IDVALANIMAL2"]}`,
+                       true,
+                       "",
+               },
+               {
+                       "Known non-strict key, list of unknown non-alias values",
+                       false,
+                       `{"IDTAGCOMMENT":["hello world","lorem ipsum"]}`,
+                       true,
+                       "",
+               },
                // Check fails
-               {"Known first key & value; known 2nd key, unknown 2nd value", false, `{"IDTAGANIMALS":"IDVALANIMAL1", "IDTAGIMPORTANCE": "blah blah"}`, false},
-               {"Unknown non-alias key on strict vocabulary", true, `{"foo":"bar"}`, false},
-               {"Known non-strict key, known value alias", false, `{"IDTAGANIMALS":"Loxodonta"}`, false},
-               {"Known strict key, unknown non-alias value", false, `{"IDTAGIMPORTANCE":"Unimportant"}`, false},
-               {"Known strict key, known value alias", false, `{"IDTAGIMPORTANCE":"High"}`, false},
-               {"Known strict key, list of known alias values", false, `{"IDTAGIMPORTANCE":["Unimportant","High"]}`, false},
-               {"Known strict key, list of unknown non-alias values", false, `{"IDTAGIMPORTANCE":["foo","bar"]}`, false},
+               {
+                       "Known first key & value; known 2nd key, unknown 2nd value",
+                       false,
+                       `{"IDTAGANIMALS":"IDVALANIMAL1", "IDTAGIMPORTANCE": "blah blah"}`,
+                       false,
+                       "tag value.*is not valid for key.*",
+               },
+               {
+                       "Unknown non-alias key on strict vocabulary",
+                       true,
+                       `{"foo":"bar"}`,
+                       false,
+                       "tag key.*is not defined in the vocabulary",
+               },
+               {
+                       "Known non-strict key, known value alias",
+                       false,
+                       `{"IDTAGANIMALS":"Loxodonta"}`,
+                       false,
+                       "tag value.*for key.* is an alias, must be provided as.*",
+               },
+               {
+                       "Known strict key, unknown non-alias value",
+                       false,
+                       `{"IDTAGIMPORTANCE":"Unimportant"}`,
+                       false,
+                       "tag value.*is not valid for key.*",
+               },
+               {
+                       "Known strict key, lowercase value regarded as alias",
+                       false,
+                       `{"IDTAGIMPORTANCE":"idval1"}`,
+                       false,
+                       "tag value.*for key.* is an alias, must be provided as.*",
+               },
+               {
+                       "Known strict key, known value alias",
+                       false,
+                       `{"IDTAGIMPORTANCE":"High"}`,
+                       false,
+                       "tag value.* for key.*is an alias, must be provided as.*",
+               },
+               {
+                       "Known strict key, list of known alias values",
+                       false,
+                       `{"IDTAGIMPORTANCE":["High", "Low"]}`,
+                       false,
+                       "tag value.*for key.*is an alias, must be provided as.*",
+               },
+               {
+                       "Known strict key, list of unknown non-alias values",
+                       false,
+                       `{"IDTAGIMPORTANCE":["foo","bar"]}`,
+                       false,
+                       "tag value.*is not valid for key.*",
+               },
+               {
+                       "Invalid value type",
+                       false,
+                       `{"IDTAGANIMALS":1}`,
+                       false,
+                       "value type for tag key.* was.*, but expected a string or list of strings",
+               },
+               {
+                       "Value list of invalid type",
+                       false,
+                       `{"IDTAGANIMALS":[1]}`,
+                       false,
+                       "value list element type for tag key.* was.*, but expected a string",
+               },
        }
        for _, tt := range tests {
                c.Log(c.TestName()+" ", tt.name)
@@ -95,6 +195,7 @@ func (s *VocabularySuite) TestCheck(c *check.C) {
                        c.Assert(err, check.IsNil)
                } else {
                        c.Assert(err, check.NotNil)
+                       c.Assert(err.Error(), check.Matches, tt.errMatches)
                }
        }
 }
@@ -119,7 +220,8 @@ func (s *VocabularySuite) TestNewVocabulary(c *check.C) {
                                        "labels": [{"label": "Animal"}, {"label": "Creature"}],
                                        "values": {
                                                "IDVALANIMAL1":{"labels":[{"label":"Human"}, {"label":"Homo sapiens"}]},
-                                               "IDVALANIMAL2":{"labels":[{"label":"Elephant"}, {"label":"Loxodonta"}]}
+                                               "IDVALANIMAL2":{"labels":[{"label":"Elephant"}, {"label":"Loxodonta"}]},
+                                               "DOG":{"labels":[{"label":"Dog"}, {"label":"Canis lupus familiaris"}, {"label":"dOg"}]}
                                        }
                                }
                        }}`,
@@ -147,6 +249,9 @@ func (s *VocabularySuite) TestNewVocabulary(c *check.C) {
                                                        "IDVALANIMAL2": {
                                                                Labels: []VocabularyLabel{{Label: "Elephant"}, {Label: "Loxodonta"}},
                                                        },
+                                                       "DOG": {
+                                                               Labels: []VocabularyLabel{{Label: "Dog"}, {Label: "Canis lupus familiaris"}, {Label: "dOg"}},
+                                                       },
                                                },
                                        },
                                },
@@ -193,7 +298,41 @@ func (s *VocabularySuite) TestValidationErrors(c *check.C) {
                        "vocabulary is strict but no tags are defined",
                },
                {
-                       "Duplicated tag keys",
+                       "Collision between tag key and tag key label",
+                       &Vocabulary{
+                               StrictTags: false,
+                               Tags: map[string]VocabularyTag{
+                                       "IDTAGANIMALS": {
+                                               Strict: false,
+                                               Labels: []VocabularyLabel{{Label: "Animal"}, {Label: "Creature"}},
+                                       },
+                                       "IDTAGCOMMENT": {
+                                               Strict: false,
+                                               Labels: []VocabularyLabel{{Label: "Comment"}, {Label: "IDTAGANIMALS"}},
+                                       },
+                               },
+                       },
+                       "", // Depending on how the map is sorted, this could be one of two errors
+               },
+               {
+                       "Collision between tag key and tag key label (case-insensitive)",
+                       &Vocabulary{
+                               StrictTags: false,
+                               Tags: map[string]VocabularyTag{
+                                       "IDTAGANIMALS": {
+                                               Strict: false,
+                                               Labels: []VocabularyLabel{{Label: "Animal"}, {Label: "Creature"}},
+                                       },
+                                       "IDTAGCOMMENT": {
+                                               Strict: false,
+                                               Labels: []VocabularyLabel{{Label: "Comment"}, {Label: "IdTagAnimals"}},
+                                       },
+                               },
+                       },
+                       "", // Depending on how the map is sorted, this could be one of two errors
+               },
+               {
+                       "Collision between tag key labels",
                        &Vocabulary{
                                StrictTags: false,
                                Tags: map[string]VocabularyTag{
@@ -210,7 +349,49 @@ func (s *VocabularySuite) TestValidationErrors(c *check.C) {
                        "tag label.*for key.*already seen.*",
                },
                {
-                       "Duplicated tag values",
+                       "Collision between tag value and tag value label",
+                       &Vocabulary{
+                               StrictTags: false,
+                               Tags: map[string]VocabularyTag{
+                                       "IDTAGANIMALS": {
+                                               Strict: false,
+                                               Labels: []VocabularyLabel{{Label: "Animal"}, {Label: "Creature"}},
+                                               Values: map[string]VocabularyTagValue{
+                                                       "IDVALANIMAL1": {
+                                                               Labels: []VocabularyLabel{{Label: "Human"}, {Label: "Mammal"}},
+                                                       },
+                                                       "IDVALANIMAL2": {
+                                                               Labels: []VocabularyLabel{{Label: "Elephant"}, {Label: "IDVALANIMAL1"}},
+                                                       },
+                                               },
+                                       },
+                               },
+                       },
+                       "", // Depending on how the map is sorted, this could be one of two errors
+               },
+               {
+                       "Collision between tag value and tag value label (case-insensitive)",
+                       &Vocabulary{
+                               StrictTags: false,
+                               Tags: map[string]VocabularyTag{
+                                       "IDTAGANIMALS": {
+                                               Strict: false,
+                                               Labels: []VocabularyLabel{{Label: "Animal"}, {Label: "Creature"}},
+                                               Values: map[string]VocabularyTagValue{
+                                                       "IDVALANIMAL1": {
+                                                               Labels: []VocabularyLabel{{Label: "Human"}, {Label: "Mammal"}},
+                                                       },
+                                                       "IDVALANIMAL2": {
+                                                               Labels: []VocabularyLabel{{Label: "Elephant"}, {Label: "IDValAnimal1"}},
+                                                       },
+                                               },
+                                       },
+                               },
+                       },
+                       "", // Depending on how the map is sorted, this could be one of two errors
+               },
+               {
+                       "Collision between tag value labels",
                        &Vocabulary{
                                StrictTags: false,
                                Tags: map[string]VocabularyTag{
@@ -228,10 +409,31 @@ func (s *VocabularySuite) TestValidationErrors(c *check.C) {
                                        },
                                },
                        },
-                       "tag value label.*for pair.*already seen.*",
+                       "tag value label.*for pair.*already seen.*on value.*",
                },
                {
-                       "Strict key, no values",
+                       "Collision between tag value labels (case-insensitive)",
+                       &Vocabulary{
+                               StrictTags: false,
+                               Tags: map[string]VocabularyTag{
+                                       "IDTAGANIMALS": {
+                                               Strict: false,
+                                               Labels: []VocabularyLabel{{Label: "Animal"}, {Label: "Creature"}},
+                                               Values: map[string]VocabularyTagValue{
+                                                       "IDVALANIMAL1": {
+                                                               Labels: []VocabularyLabel{{Label: "Human"}, {Label: "Mammal"}},
+                                                       },
+                                                       "IDVALANIMAL2": {
+                                                               Labels: []VocabularyLabel{{Label: "Elephant"}, {Label: "mAMMAL"}},
+                                                       },
+                                               },
+                                       },
+                               },
+                       },
+                       "tag value label.*for pair.*already seen.*on value.*",
+               },
+               {
+                       "Strict tag key, with no values",
                        &Vocabulary{
                                StrictTags: false,
                                Tags: map[string]VocabularyTag{
@@ -246,8 +448,10 @@ func (s *VocabularySuite) TestValidationErrors(c *check.C) {
        }
        for _, tt := range tests {
                c.Log(c.TestName()+" ", tt.name)
-               err := tt.voc.Validate()
+               err := tt.voc.validate()
                c.Assert(err, check.NotNil)
-               c.Assert(err, check.ErrorMatches, tt.errMatches)
+               if tt.errMatches != "" {
+                       c.Assert(err, check.ErrorMatches, tt.errMatches)
+               }
        }
 }