Explorar o código

Catch non-unique errors

When a schema type is set as unique, we should display the validation
error to indicate that non-unique values have been provided for a key.

Signed-off-by: Mazz Mosley <[email protected]>
Mazz Mosley %!s(int64=10) %!d(string=hai) anos
pai
achega
df14a4384d
Modificáronse 2 ficheiros con 22 adicións e 1 borrados
  1. 9 1
      compose/config/validation.py
  2. 13 0
      tests/unit/config_test.py

+ 9 - 1
compose/config/validation.py

@@ -59,6 +59,7 @@ def process_errors(errors):
     invalid_keys = []
     required = []
     type_errors = []
+    other_errors = []
 
     for error in errors:
         # handle root level errors
@@ -115,8 +116,15 @@ def process_errors(errors):
                 required_keys = ",".join(error.validator_value[dependency_key])
                 required.append("Invalid '{}' configuration for '{}' service: when defining '{}' you must set '{}' as well".format(
                     dependency_key, service_name, dependency_key, required_keys))
+            else:
+                # pop the service name off our path
+                error.path.popleft()
+
+                config_key = " ".join(["'%s'" % k for k in error.path])
+                err_msg = "Service '{}' configuration key {} value {}".format(service_name, config_key, error.message)
+                other_errors.append(err_msg)
 
-    return "\n".join(root_msgs + invalid_keys + required + type_errors)
+    return "\n".join(root_msgs + invalid_keys + required + type_errors + other_errors)
 
 
 def validate_against_schema(config):

+ 13 - 0
tests/unit/config_test.py

@@ -147,6 +147,19 @@ class ConfigTest(unittest.TestCase):
                 )
             )
 
+    def test_invalid_config_not_unique_items(self):
+        expected_error_msg = "has non-unique elements"
+        with self.assertRaisesRegexp(ConfigurationError, expected_error_msg):
+            config.load(
+                config.ConfigDetails(
+                    {
+                        'web': {'build': '.', 'devices': ['/dev/foo:/dev/foo', '/dev/foo:/dev/foo']}
+                    },
+                    'tests/fixtures/extends',
+                    'filename.yml'
+                )
+            )
+
 
 class InterpolationTest(unittest.TestCase):
     @mock.patch.dict(os.environ)