Add ids to config schemas

Also enforce a max complexity for functions and add some new tests for config.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
This commit is contained in:
Daniel Nephin 2015-11-12 12:40:36 -05:00
parent d52c969f94
commit 285e52cc7c
5 changed files with 30 additions and 18 deletions

View File

@ -2,15 +2,18 @@
"$schema": "http://json-schema.org/draft-04/schema#", "$schema": "http://json-schema.org/draft-04/schema#",
"type": "object", "type": "object",
"id": "fields_schema.json",
"patternProperties": { "patternProperties": {
"^[a-zA-Z0-9._-]+$": { "^[a-zA-Z0-9._-]+$": {
"$ref": "#/definitions/service" "$ref": "#/definitions/service"
} }
}, },
"additionalProperties": false,
"definitions": { "definitions": {
"service": { "service": {
"id": "#/definitions/service",
"type": "object", "type": "object",
"properties": { "properties": {
@ -167,6 +170,5 @@
] ]
} }
}, }
"additionalProperties": false
} }

View File

@ -1,15 +1,17 @@
{ {
"$schema": "http://json-schema.org/draft-04/schema#", "$schema": "http://json-schema.org/draft-04/schema#",
"id": "service_schema.json",
"type": "object", "type": "object",
"allOf": [ "allOf": [
{"$ref": "fields_schema.json#/definitions/service"}, {"$ref": "fields_schema.json#/definitions/service"},
{"$ref": "#/definitions/service_constraints"} {"$ref": "#/definitions/constraints"}
], ],
"definitions": { "definitions": {
"service_constraints": { "constraints": {
"id": "#/definitions/constraints",
"anyOf": [ "anyOf": [
{ {
"required": ["build"], "required": ["build"],
@ -21,13 +23,8 @@
{"required": ["build"]}, {"required": ["build"]},
{"required": ["dockerfile"]} {"required": ["dockerfile"]}
]} ]}
},
{
"required": ["extends"],
"not": {"required": ["build", "image"]}
} }
] ]
} }
} }
} }

View File

@ -307,7 +307,10 @@ def _validate_against_schema(config, schema_filename, format_checker=[], service
schema = json.load(schema_fh) schema = json.load(schema_fh)
resolver = RefResolver(resolver_full_path, schema) resolver = RefResolver(resolver_full_path, schema)
validation_output = Draft4Validator(schema, resolver=resolver, format_checker=FormatChecker(format_checker)) validation_output = Draft4Validator(
schema,
resolver=resolver,
format_checker=FormatChecker(format_checker))
errors = [error for error in sorted(validation_output.iter_errors(config), key=str)] errors = [error for error in sorted(validation_output.iter_errors(config), key=str)]
if errors: if errors:

View File

@ -78,14 +78,12 @@ class ConfigTest(unittest.TestCase):
def test_config_invalid_service_names(self): def test_config_invalid_service_names(self):
for invalid_name in ['?not?allowed', ' ', '', '!', '/', '\xe2']: for invalid_name in ['?not?allowed', ' ', '', '!', '/', '\xe2']:
with pytest.raises(ConfigurationError): with pytest.raises(ConfigurationError) as exc:
config.load( config.load(build_config_details(
build_config_details( {invalid_name: {'image': 'busybox'}},
{invalid_name: {'image': 'busybox'}}, 'working_dir',
'working_dir', 'filename.yml'))
'filename.yml' assert 'Invalid service name \'%s\'' % invalid_name in exc.exconly()
)
)
def test_load_with_invalid_field_name(self): def test_load_with_invalid_field_name(self):
config_details = build_config_details( config_details = build_config_details(
@ -97,6 +95,16 @@ class ConfigTest(unittest.TestCase):
error_msg = "Unsupported config option for 'web' service: 'name'" error_msg = "Unsupported config option for 'web' service: 'name'"
assert error_msg in exc.exconly() assert error_msg in exc.exconly()
def test_load_invalid_service_definition(self):
config_details = build_config_details(
{'web': 'wrong'},
'working_dir',
'filename.yml')
with pytest.raises(ConfigurationError) as exc:
config.load(config_details)
error_msg = "Service \"web\" doesn\'t have any configuration options"
assert error_msg in exc.exconly()
def test_config_integer_service_name_raise_validation_error(self): def test_config_integer_service_name_raise_validation_error(self):
expected_error_msg = "Service name: 1 needs to be a string, eg '1'" expected_error_msg = "Service name: 1 needs to be a string, eg '1'"
with self.assertRaisesRegexp(ConfigurationError, expected_error_msg): with self.assertRaisesRegexp(ConfigurationError, expected_error_msg):

View File

@ -43,4 +43,6 @@ directory = coverage-html
[flake8] [flake8]
# Allow really long lines for now # Allow really long lines for now
max-line-length = 140 max-line-length = 140
# Set this high for now
max-complexity = 20
exclude = compose/packages exclude = compose/packages