From f8efb54c80ed661538f06ecea7c1329925442b3a Mon Sep 17 00:00:00 2001 From: Mazz Mosley Date: Tue, 11 Aug 2015 13:06:32 +0100 Subject: [PATCH] Handle $ref defined types errors We use $ref in the schema to allow us to specify multiple type, eg command, it can be a string or a list of strings. It required some extra parsing to retrieve a helpful type to display in our error message rather than 'string or string'. Which while correct, is not helpful. We value helpful. Signed-off-by: Mazz Mosley --- compose/config/validation.py | 16 ++++++++++++++-- tests/unit/config_test.py | 13 +++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/compose/config/validation.py b/compose/config/validation.py index 946acf149b..36fd03b5f2 100644 --- a/compose/config/validation.py +++ b/compose/config/validation.py @@ -55,6 +55,16 @@ def process_errors(errors): def _clean_error_message(message): return message.replace("u'", "'") + def _parse_valid_types_from_schema(schema): + """ + Our defined types using $ref in the schema require some extra parsing + retrieve a helpful type for error message display. + """ + if '$ref' in schema: + return schema['$ref'].replace("#/definitions/", "").replace("_", " ") + else: + return str(schema['type']) + root_msgs = [] invalid_keys = [] required = [] @@ -93,9 +103,11 @@ def process_errors(errors): required.append(_clean_error_message(error.message)) elif error.validator == 'oneOf': config_key = error.path[0] - valid_types = [context.validator_value for context in error.context] + + valid_types = [_parse_valid_types_from_schema(schema) for schema in error.schema['oneOf']] valid_type_msg = " or ".join(valid_types) - type_errors.append("Service '{}' configuration key '{}' contains an invalid type, it should be either {}".format( + + type_errors.append("Service '{}' configuration key '{}' contains an invalid type, valid types are {}".format( service_name, config_key, valid_type_msg) ) elif error.validator == 'type': diff --git a/tests/unit/config_test.py b/tests/unit/config_test.py index f35010c695..1948e21826 100644 --- a/tests/unit/config_test.py +++ b/tests/unit/config_test.py @@ -160,6 +160,19 @@ class ConfigTest(unittest.TestCase): ) ) + def test_invalid_list_of_strings_format(self): + expected_error_msg = "'command' contains an invalid type, valid types are string or list of strings" + with self.assertRaisesRegexp(ConfigurationError, expected_error_msg): + config.load( + config.ConfigDetails( + { + 'web': {'build': '.', 'command': [1]} + }, + 'tests/fixtures/extends', + 'filename.yml' + ) + ) + class InterpolationTest(unittest.TestCase): @mock.patch.dict(os.environ)