summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--morphlib/morphloader.py46
-rw-r--r--morphlib/morphloader_tests.py128
-rw-r--r--yarns/implementations.yarn25
-rw-r--r--yarns/regression.yarn4
4 files changed, 155 insertions, 48 deletions
diff --git a/morphlib/morphloader.py b/morphlib/morphloader.py
index 9ac248da..fdc3b62f 100644
--- a/morphlib/morphloader.py
+++ b/morphlib/morphloader.py
@@ -16,6 +16,7 @@
# =*= License: GPL-2 =*=
+import collections
import logging
import yaml
@@ -102,6 +103,16 @@ class DuplicateChunkError(morphlib.Error):
'in stratum %(stratum_name)s' % locals())
+class SystemStrataNotListError(morphlib.Error):
+
+ def __init__(self, system_name, strata_type):
+ self.system_name = system_name
+ self.strata_type = strata_type
+ typename = strata_type.__name__
+ morphlib.Error.__init__(
+ self, 'System %(system_name)s has the wrong type for its strata: '\
+ '%(typename)s, expected list' % locals())
+
class DuplicateStratumError(morphlib.Error):
def __init__(self, system_name, stratum_name):
@@ -112,6 +123,23 @@ class DuplicateStratumError(morphlib.Error):
'in system %(system_name)s' % locals())
+class SystemStratumSpecsNotMappingError(morphlib.Error):
+
+ def __init__(self, system_name, strata):
+ self.system_name = system_name
+ self.strata = strata
+ morphlib.Error.__init__(
+ self, 'System %(system_name)s has stratum specs '\
+ 'that are not mappings.' % locals())
+
+
+class EmptySystemError(morphlib.Error):
+
+ def __init__(self, system_name):
+ morphlib.Error.__init__(
+ self, 'System %(system_name)s has no strata.' % locals())
+
+
class MorphologyLoader(object):
'''Load morphologies from disk, or save them back to disk.'''
@@ -126,6 +154,7 @@ class MorphologyLoader(object):
'system': [
'name',
'arch',
+ 'strata',
],
'cluster': [
'name',
@@ -166,7 +195,6 @@ class MorphologyLoader(object):
'build-depends': [],
},
'system': {
- 'strata': [],
'description': '',
'arch': None,
'configuration-extensions': [],
@@ -270,9 +298,23 @@ class MorphologyLoader(object):
assert kind == 'cluster'
def _validate_system(self, morph):
+ # A system must contain at least one stratum
+ strata = morph['strata']
+ if (not isinstance(strata, collections.Iterable)
+ or isinstance(strata, collections.Mapping)):
+
+ raise SystemStrataNotListError(morph['name'],
+ type(strata))
+
+ if not strata:
+ raise EmptySystemError(morph['name'])
+
+ if not all(isinstance(o, collections.Mapping) for o in strata):
+ raise SystemStratumSpecsNotMappingError(morph['name'], strata)
+
# All stratum names should be unique within a system.
names = set()
- for spec in morph['strata']:
+ for spec in strata:
name = spec.get('alias', spec['morph'])
if name in names:
raise DuplicateStratumError(morph['name'], name)
diff --git a/morphlib/morphloader_tests.py b/morphlib/morphloader_tests.py
index b6ebff6a..8b87467a 100644
--- a/morphlib/morphloader_tests.py
+++ b/morphlib/morphloader_tests.py
@@ -99,6 +99,9 @@ build-system: dummy
'kind': 'system',
'name': 'foo',
'arch': 'x86_64',
+ 'strata': [
+ {'morph': 'bar'},
+ ],
'system-kind': 'foo',
})
self.assertRaises(
@@ -109,6 +112,9 @@ build-system: dummy
'kind': 'system',
'name': 'foo',
'arch': 'x86_64',
+ 'strata': [
+ {'morph': 'bar'},
+ ],
'disk-size': 'over 9000',
})
self.assertRaises(
@@ -122,12 +128,14 @@ build-system: dummy
morphlib.morphloader.MissingFieldError, self.loader.validate, m)
def test_fails_to_validate_system_with_invalid_field(self):
- m = morphlib.morph3.Morphology({
- 'kind': 'system',
- 'name': 'name',
- 'arch': 'x86_64',
- 'invalid': 'field',
- })
+ m = morphlib.morph3.Morphology(
+ kind="system",
+ name="foo",
+ arch="blah",
+ strata=[
+ {'morph': 'bar'},
+ ],
+ invalid='field')
self.assertRaises(
morphlib.morphloader.InvalidFieldError, self.loader.validate, m)
@@ -183,24 +191,24 @@ build-system: dummy
def test_validate_requires_a_valid_architecture(self):
m = morphlib.morph3.Morphology(
- {
- "kind": "system",
- "name": "foo",
- "arch": "blah",
- "strata": [],
- })
+ kind="system",
+ name="foo",
+ arch="blah",
+ strata=[
+ {'morph': 'bar'},
+ ])
self.assertRaises(
morphlib.morphloader.UnknownArchitectureError,
self.loader.validate, m)
def test_validate_normalises_architecture_armv7_to_armv7l(self):
m = morphlib.morph3.Morphology(
- {
- "kind": "system",
- "name": "foo",
- "arch": "armv7",
- "strata": [],
- })
+ kind="system",
+ name="foo",
+ arch="armv7",
+ strata=[
+ {'morph': 'bar'},
+ ])
self.loader.validate(m)
self.assertEqual(m['arch'], 'armv7l')
@@ -276,6 +284,50 @@ build-system: dummy
morphlib.morphloader.EmptyStratumError,
self.loader.validate, m)
+ def test_validate_requires_strata_in_system(self):
+ m = morphlib.morph3.Morphology(
+ name='system',
+ kind='system',
+ arch='testarch')
+ self.assertRaises(
+ morphlib.morphloader.MissingFieldError,
+ self.loader.validate, m)
+
+ def test_validate_requires_list_of_strata_in_system(self):
+ for v in (None, {}):
+ m = morphlib.morph3.Morphology(
+ name='system',
+ kind='system',
+ arch='testarch',
+ strata=v)
+ with self.assertRaises(
+ morphlib.morphloader.SystemStrataNotListError) as cm:
+
+ self.loader.validate(m)
+ self.assertEqual(cm.exception.strata_type, type(v))
+
+ def test_validate_requires_non_empty_strata_in_system(self):
+ m = morphlib.morph3.Morphology(
+ name='system',
+ kind='system',
+ arch='testarch',
+ strata=[])
+ self.assertRaises(
+ morphlib.morphloader.EmptySystemError,
+ self.loader.validate, m)
+
+ def test_validate_requires_stratum_specs_in_system(self):
+ m = morphlib.morph3.Morphology(
+ name='system',
+ kind='system',
+ arch='testarch',
+ strata=["foo"])
+ with self.assertRaises(
+ morphlib.morphloader.SystemStratumSpecsNotMappingError) as cm:
+
+ self.loader.validate(m)
+ self.assertEqual(cm.exception.strata, ["foo"])
+
def test_loads_yaml_from_string(self):
string = '''\
name: foo
@@ -463,11 +515,13 @@ name: foo
test_dict)
def test_sets_defaults_for_system(self):
- m = morphlib.morph3.Morphology({
- 'kind': 'system',
- 'name': 'foo',
- 'arch': 'x86_64',
- })
+ m = morphlib.morph3.Morphology(
+ kind='system',
+ name='foo',
+ arch='testarch',
+ strata=[
+ {'morph': 'bar'},
+ ])
self.loader.set_defaults(m)
self.loader.validate(m)
self.assertEqual(
@@ -476,25 +530,35 @@ name: foo
'kind': 'system',
'name': 'foo',
'description': '',
- 'arch': 'x86_64',
- 'strata': [],
+ 'arch': 'testarch',
+ 'strata': [
+ {'morph': 'bar'},
+ ],
'configuration-extensions': [],
})
def test_unsets_defaults_for_system(self):
- m = morphlib.morph3.Morphology({
- 'kind': 'system',
- 'name': 'foo',
- 'arch': 'x86_64',
- 'strata': [],
- })
+ m = morphlib.morph3.Morphology(
+ {
+ 'description': '',
+ 'kind': 'system',
+ 'name': 'foo',
+ 'arch': 'testarch',
+ 'strata': [
+ {'morph': 'bar'},
+ ],
+ 'configuration-extensions': [],
+ })
self.loader.unset_defaults(m)
self.assertEqual(
dict(m),
{
'kind': 'system',
'name': 'foo',
- 'arch': 'x86_64',
+ 'arch': 'testarch',
+ 'strata': [
+ {'morph': 'bar'},
+ ],
})
def test_sets_defaults_for_cluster(self):
diff --git a/yarns/implementations.yarn b/yarns/implementations.yarn
index 6491b38e..98955f48 100644
--- a/yarns/implementations.yarn
+++ b/yarns/implementations.yarn
@@ -75,13 +75,6 @@ another to hold a chunk.
morph: test-stratum
EOF
- cat << EOF > "$DATADIR/gits/morphs/simple-system.morph"
- name: simple-system
- kind: system
- arch: $arch
- strata: []
- EOF
-
cat << EOF > "$DATADIR/gits/morphs/test-stratum.morph"
name: test-stratum
kind: stratum
@@ -134,7 +127,11 @@ another to hold a chunk.
description: A system called $MATCH_1 for architectures $MATCH_2
kind: system
name: $MATCH_1
- strata: []
+ strata:
+ - name: test-stratum
+ repo: test:morphs
+ ref: master
+ morph: test-stratum
EOF
run_in "$DATADIR/gits/morphs" git add "$MATCH_1.morph"
run_in "$DATADIR/gits/morphs" git commit -m "Added $MATCH_1 morphology."
@@ -275,7 +272,11 @@ Editing morphologies with `morph edit`.
description: A system called $MATCH_1 for architectures $MATCH_2
kind: system
name: $MATCH_1
- strata: []
+ strata:
+ - name: test-stratum
+ repo: test:morphs
+ ref: master
+ morph: test-stratum
EOF
Reporting status of checked out repositories:
@@ -425,7 +426,7 @@ Generating a manifest.
> "$DATADIR/baserock/hello_world.meta"
{
"artifact-name": "hello_world",
- "cache-key":
+ "cache-key":
"ab8d00a80298a842446ce23507cea6b4d0e34c7ddfa05c67f460318b04d21308",
"kind": "chunk",
"morphology": "hello_world.morph",
@@ -440,7 +441,7 @@ Generating a manifest.
IMPLEMENTS WHEN morph generates a manifest
run_morph generate-manifest "$DATADIR/artifact.tar" > "$DATADIR/manifest"
-
+
IMPLEMENTS THEN the manifest is generated
# Generated manifest should contain the name of the repository
@@ -554,4 +555,4 @@ Implementations for building systems
IMPLEMENTS THEN morph build the system (\S+) of the (branch|tag) (\S+) of the repo (\S+)
cd "$DATADIR/workspace/$MATCH_3/$MATCH_4"
- run_morph build "$MATCH_1"
+ run_morph build "$MATCH_1"
diff --git a/yarns/regression.yarn b/yarns/regression.yarn
index a17d2f87..582ebb08 100644
--- a/yarns/regression.yarn
+++ b/yarns/regression.yarn
@@ -10,13 +10,13 @@ Testing if we can build after checking out from a tag.
GIVEN a workspace
AND a git server
WHEN the user checks out the system tag called test-tag
- THEN morph build the system simple-system of the tag test-tag of the repo test:morphs
+ THEN morph build the system test-system of the tag test-tag of the repo test:morphs
Running `morph branch` when the branch directory exists doesn't
remove the existing directory.
- SCENARIO re-running 'morph branch' fails, original branch untouched
+ SCENARIO re-running 'morph branch' fails, original branch untouched
GIVEN a workspace
AND a git server
WHEN the user creates a system branch called foo