Skip to content
This repository has been archived by the owner on Feb 13, 2020. It is now read-only.

Commit

Permalink
Merge pull request #185 from gamechanger/ae-specs_refactor
Browse files Browse the repository at this point in the history
Ae specs refactor
  • Loading branch information
Philip Alexander Etling committed Jun 9, 2015
2 parents f9f4e6e + 116f189 commit e159354
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 35 deletions.
7 changes: 0 additions & 7 deletions dusty/commands/validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,9 @@ def _check_bare_minimum(specs):
if not specs.get(constants.CONFIG_BUNDLES_KEY):
raise ValidationException("No Bundles found - exiting")

def _ensure_app_build_or_image(app):
if 'image' in app and 'build' in app:
raise ValidationException("Keys `image` and `build` are mutually exclusive")
elif 'image' not in app and 'build' not in app:
raise ValidationException("Each app must contain either an `image` or a `build` field")

def _validate_fields_with_schemer(specs):
for app in specs.get('apps', []).values():
app_schema.validate(app)
_ensure_app_build_or_image(app)
for bundle in specs.get(constants.CONFIG_BUNDLES_KEY, []).values():
bundle_schema.validate(bundle)
for lib in specs.get('libs', []).values():
Expand Down
42 changes: 25 additions & 17 deletions dusty/schemas/app_schema.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
from schemer import Schema, Array

def image_build_isolation_validator():
def validator(document):
if 'image' in document and 'build' in document:
return 'Only one of image and build is allowed in app schema'
elif 'image' not in document and 'build' not in document:
return 'Need to have at least one of `image` or `build` in app schema'
return validator


app_depends_schema = Schema({
'services': {'type': Array(basestring)},
'apps': {'type': Array(basestring)},
'libs': {'type': Array(basestring)}
'services': {'type': Array(basestring), 'default': []},
'apps': {'type': Array(basestring), 'default': []},
'libs': {'type': Array(basestring), 'default': []}
})

conditional_links_schema = Schema({
'services': {'type': Array(basestring)},
'apps': {'type': Array(basestring)},
'services': {'type': Array(basestring), 'default': []},
'apps': {'type': Array(basestring), 'default': []},
})

host_forwarding_schema = Schema({
Expand All @@ -19,8 +27,8 @@
})

commands_schema = Schema({
'always': {'type': basestring, 'required': True},
'once': {'type': basestring}
'always': {'type': basestring, 'required': True, 'default': ''},
'once': {'type': basestring, 'default': ''}
})

script_schema = Schema({
Expand All @@ -32,13 +40,13 @@

app_schema = Schema({
'repo': {'type': basestring, 'required': True},
'depends': {'type': app_depends_schema},
'conditional_links': {'type': conditional_links_schema},
'host_forwarding': {'type': Array(host_forwarding_schema)},
'image': {'type': basestring},
'build': {'type': basestring},
'mount': {'type': basestring},
'commands': {'type': commands_schema},
'scripts': {'type': Array(script_schema)},
'compose': {'type': dict},
})
'depends': {'type': app_depends_schema, 'default': {}},
'conditional_links': {'type': conditional_links_schema, 'default': {}},
'host_forwarding': {'type': Array(host_forwarding_schema), 'default': []},
'image': {'type': basestring, 'default': ''},
'build': {'type': basestring, 'default': ''},
'mount': {'type': basestring, 'default': ''},
'commands': {'type': commands_schema, 'default': {}},
'scripts': {'type': Array(script_schema), 'default': []},
'compose': {'type': dict, 'default': {}}
}, validates=[image_build_isolation_validator()])
11 changes: 11 additions & 0 deletions dusty/schemas/base_schema_class.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from copy import deepcopy

# This is build on top of Schemer's functionality
class DustySchema(object):
def __init__(self, schema, document):
schema.validate(document)
self._document = deepcopy(document)
schema.apply_defaults(self._document)

def __getitem__(self, name):
return self._document[name]
2 changes: 1 addition & 1 deletion dusty/schemas/bundle_schema.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from schemer import Schema, Array

bundle_schema = Schema({
'description': {'type': basestring},
'description': {'type': basestring, 'default': ''},
'apps': {'type': Array(basestring), 'required': True}
})
8 changes: 4 additions & 4 deletions dusty/schemas/lib_schema.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
from schemer import Schema, Array

depends_schema = Schema({
'libs': {'type': Array(basestring)}
'libs': {'type': Array(basestring), 'default': []}
})

lib_schema = Schema({
'repo': {'type': basestring, 'required': True},
'mount': {'type': basestring},
'install': {'type': basestring},
'depends': {'type': depends_schema}
'mount': {'type': basestring, 'default': ''},
'install': {'type': basestring, 'default': ''},
'depends': {'type': depends_schema, 'default': {}}
})
2 changes: 1 addition & 1 deletion requirements.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
'PrettyTable>=0.7.0',
'GitPython>=1.0.1',
'docopt==0.6.2',
'schemer==0.2.7',
'Schemer==0.2.8',
]

test_requires = [
Expand Down
6 changes: 1 addition & 5 deletions tests/unit/commands/validate_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from schemer import ValidationException

from dusty.commands.validate import (_ensure_app_build_or_image, _validate_app_references, _validate_cycle_free,
from dusty.commands.validate import (_validate_app_references, _validate_cycle_free,
_validate_fields_with_schemer)
from dusty import constants

Expand Down Expand Up @@ -45,10 +45,6 @@ def test_schemer_called(self):
with self.assertRaises(ValidationException):
_validate_fields_with_schemer(specs)

def test_only_build_or_image(self):
with self.assertRaises(ValidationException):
_ensure_app_build_or_image({'image': 'gcimage', 'build': 'build.sh'})

def test_validate_app_with_bad_service(self):
specs = {'apps': {
'app1': {
Expand Down
Empty file added tests/unit/schemas/__init__.py
Empty file.
45 changes: 45 additions & 0 deletions tests/unit/schemas/test_base_schema_class.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from unittest import TestCase
from schemer import Schema, Array, ValidationException
from dusty.schemas.base_schema_class import DustySchema


class TestDustySchemaClass(TestCase):
def setUp(self):
self.base_schema = Schema({'street': {'type': basestring},
'house_number': {'type': int, 'default': 1}})
self.bigger_schema = Schema({'address': {'type': self.base_schema, 'default': {}},
'first_name': {'type': basestring, 'required': True},
'last_name': {'type': basestring, 'default': 'johnson'}})

def test_init_invalid_doc(self):
doc = {'street': 'dogstoon',
'house_number': '1'}
with self.assertRaises(ValidationException):
DustySchema(self.base_schema, doc)

def test_valid_doc(self):
doc = {'street': 'dogstoon',
'house_number': 1}
dusty_schema = DustySchema(self.base_schema, doc)
self.assertEquals(dusty_schema['street'], 'dogstoon')
self.assertEquals(dusty_schema['house_number'], 1)

def test_setting_defaults(self):
doc = {'street': 'dogstoon'}
dusty_schema = DustySchema(self.base_schema, doc)
self.assertEquals(dusty_schema['street'], 'dogstoon')
self.assertEquals(dusty_schema['house_number'], 1)

def test_setting_defaults_more_complicated_1(self):
doc = {'first_name': 'dusty'}
dusty_schema = DustySchema(self.bigger_schema, doc)
self.assertEquals(dusty_schema['first_name'], 'dusty')
self.assertEquals(dusty_schema['last_name'], 'johnson')
self.assertEquals(dusty_schema['address'], {'house_number': 1})

def test_setting_defaults_more_complicated_2(self):
doc = {'first_name': 'dusty',
'address': {'street': 'dogstoon'}}
dusty_schema = DustySchema(self.bigger_schema, doc)
self.assertEquals(dusty_schema['address']['street'], 'dogstoon')
self.assertEquals(dusty_schema['address']['house_number'], 1)

0 comments on commit e159354

Please sign in to comment.