diff options
author | Tristan Van Berkom <tristan.vanberkom@codethink.co.uk> | 2016-11-28 17:32:57 +0000 |
---|---|---|
committer | Tristan Van Berkom <tristan.vanberkom@codethink.co.uk> | 2016-11-28 17:37:31 +0000 |
commit | 2fbcb9681f6720b3b141c1003d865a9080daa558 (patch) | |
tree | 8283026234ade0f47bc47b1eb3b057205487b2b0 /tests/loader | |
parent | 0cf884dbabcc039c0771456c55bcf086110ddb54 (diff) | |
download | buildstream-2fbcb9681f6720b3b141c1003d865a9080daa558.tar.gz |
Added a ton of tests to test the Loader
o Tests for basic file loading
o Tests for include directive functionality
o Tests for resolution of arch conditionals
o Tests for dependency resolution and detecting circular dependencies
o Tests for variants, ensures that we have the correct variant conflict errors
and that the correct variants are chosen in the correct cases
o Tests for stacks, test that stacks with embedded elements unwrap properly
into the concrete dependency tree, test for internal stack circular dependencies,
test that arch conditionals and variant conditionals work inside stacks including
with embedded elements
Lots of tests
Diffstat (limited to 'tests/loader')
54 files changed, 1431 insertions, 0 deletions
diff --git a/tests/loader/__init__.py b/tests/loader/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tests/loader/__init__.py diff --git a/tests/loader/arches.py b/tests/loader/arches.py new file mode 100644 index 000000000..55415131e --- /dev/null +++ b/tests/loader/arches.py @@ -0,0 +1,169 @@ +import os +import pytest + +from buildstream import LoadError, LoadErrorReason +from buildstream._loader import Loader +from buildstream._metaelement import MetaElement + +DATA_DIR = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + 'arches', +) + +############################################################## +# Test Simple Arch Conditionals # +############################################################## +@pytest.mark.datafiles(DATA_DIR) +def test_simple_conditional_nomatch(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/simple-conditional.bst', None, 'arm') + + element = loader.load() + assert(isinstance(element, MetaElement)) + number = element.config.get('number') + + # Did not provide any arch specific data for 'arm', number remains 5 + assert(number == 5) + +@pytest.mark.datafiles(DATA_DIR) +def test_simple_conditional_x86_64(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/simple-conditional.bst', None, 'x86_64') + + element = loader.load() + assert(isinstance(element, MetaElement)) + number = element.config.get('number') + + # x86_64 arch overrides the number to 6 + assert(number == 6) + +@pytest.mark.datafiles(DATA_DIR) +def test_simple_conditional_x86_32(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/simple-conditional.bst', None, 'x86_32') + + element = loader.load() + assert(isinstance(element, MetaElement)) + number = element.config.get('number') + + # x86_32 arch overrides the number to 7 + assert(number == 7) + +############################################################## +# Test Arch Conditionals inside Variants # +############################################################## +@pytest.mark.datafiles(DATA_DIR) +def test_variant_arch_default(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/variant-arch-conditional.bst', None, 'arm') + + element = loader.load() + assert(isinstance(element, MetaElement)) + number = element.config.get('number') + + # The default "pink" variant sets number to 6 + assert(number == 6) + +@pytest.mark.datafiles(DATA_DIR) +def test_variant_arch_default_x86_64(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/variant-arch-conditional.bst', None, 'x86_64') + + element = loader.load() + assert(isinstance(element, MetaElement)) + number = element.config.get('number') + + assert(number == 7) + +@pytest.mark.datafiles(DATA_DIR) +def test_variant_arch_default_x86_32(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/variant-arch-conditional.bst', None, 'x86_32') + + element = loader.load() + assert(isinstance(element, MetaElement)) + number = element.config.get('number') + + assert(number == 8) + +@pytest.mark.datafiles(DATA_DIR) +def test_variant_arch_pink_pony(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/variant-arch-conditional.bst', 'pink', 'arm') + + element = loader.load() + assert(isinstance(element, MetaElement)) + number = element.config.get('number') + + # The default "pink" variant sets number to 6 + assert(number == 6) + +@pytest.mark.datafiles(DATA_DIR) +def test_variant_arch_pink_pony_x86_64(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/variant-arch-conditional.bst', 'pink', 'x86_64') + + element = loader.load() + assert(isinstance(element, MetaElement)) + number = element.config.get('number') + + assert(number == 7) + +@pytest.mark.datafiles(DATA_DIR) +def test_variant_arch_pink_pony_x86_32(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/variant-arch-conditional.bst', 'pink', 'x86_32') + + element = loader.load() + assert(isinstance(element, MetaElement)) + number = element.config.get('number') + + assert(number == 8) + + + +@pytest.mark.datafiles(DATA_DIR) +def test_variant_arch_blue_pony(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/variant-arch-conditional.bst', 'blue', 'arm') + + element = loader.load() + assert(isinstance(element, MetaElement)) + number = element.config.get('number') + + # The "blue" variant sets number to 4 + assert(number == 4) + +@pytest.mark.datafiles(DATA_DIR) +def test_variant_arch_blue_pony_x86_64(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/variant-arch-conditional.bst', 'blue', 'x86_64') + + element = loader.load() + assert(isinstance(element, MetaElement)) + number = element.config.get('number') + + assert(number == 3) + +@pytest.mark.datafiles(DATA_DIR) +def test_variant_arch_blue_pony_x86_32(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/variant-arch-conditional.bst', 'blue', 'x86_32') + + element = loader.load() + assert(isinstance(element, MetaElement)) + number = element.config.get('number') + + assert(number == 2) diff --git a/tests/loader/arches/elements/simple-conditional.bst b/tests/loader/arches/elements/simple-conditional.bst new file mode 100644 index 000000000..7d1c1e5d9 --- /dev/null +++ b/tests/loader/arches/elements/simple-conditional.bst @@ -0,0 +1,11 @@ +kind: pony +description: An element with an arch conditional +config: + number: 5 +arches: + x86_64: + config: + number: 6 + x86_32: + config: + number: 7 diff --git a/tests/loader/arches/elements/variant-arch-conditional.bst b/tests/loader/arches/elements/variant-arch-conditional.bst new file mode 100644 index 000000000..1171911d7 --- /dev/null +++ b/tests/loader/arches/elements/variant-arch-conditional.bst @@ -0,0 +1,25 @@ +kind: pony +description: Test out arch conditionals nested inside variant declarations +config: + number: 5 +variants: +- variant: pink + config: + number: 6 + arches: + x86_64: + config: + number: 7 + x86_32: + config: + number: 8 +- variant: blue + config: + number: 4 + arches: + x86_64: + config: + number: 3 + x86_32: + config: + number: 2 diff --git a/tests/loader/basics.py b/tests/loader/basics.py new file mode 100644 index 000000000..13824047b --- /dev/null +++ b/tests/loader/basics.py @@ -0,0 +1,69 @@ +import os +import pytest + +from buildstream import LoadError, LoadErrorReason +from buildstream._loader import Loader +from buildstream._metaelement import MetaElement + +DATA_DIR = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + 'basics', +) + +############################################################## +# Basics: Test behavior loading the simplest of projects # +############################################################## +@pytest.mark.datafiles(os.path.join(DATA_DIR, 'onefile')) +def test_one_file(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/onefile.bst', None, None) + + element = loader.load() + + assert(isinstance(element, MetaElement)) + assert(element.kind == 'pony') + +@pytest.mark.datafiles(os.path.join(DATA_DIR, 'onefile')) +def test_missing_file(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/missing.bst', None, None) + + with pytest.raises(LoadError) as exc: + element = loader.load() + + assert (exc.value.reason == LoadErrorReason.MISSING_FILE) + +@pytest.mark.datafiles(os.path.join(DATA_DIR, 'onefile')) +def test_invalid_reference(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/badreference.bst', None, None) + + with pytest.raises(LoadError) as exc: + element = loader.load() + + assert (exc.value.reason == LoadErrorReason.INVALID_YAML) + +@pytest.mark.datafiles(os.path.join(DATA_DIR, 'onefile')) +def test_invalid_yaml(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/badfile.bst', None, None) + + with pytest.raises(LoadError) as exc: + element = loader.load() + + assert (exc.value.reason == LoadErrorReason.INVALID_YAML) + +@pytest.mark.datafiles(os.path.join(DATA_DIR, 'onefile')) +def test_fail_fullpath_target(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + fullpath = os.path.join(basedir, 'elements', 'onefile.bst') + + with pytest.raises(LoadError) as exc: + loader = Loader(basedir, fullpath, None, None) + + assert (exc.value.reason == LoadErrorReason.INVALID_DATA) diff --git a/tests/loader/basics/onefile/elements/badfile.bst b/tests/loader/basics/onefile/elements/badfile.bst new file mode 100644 index 000000000..df68dbf2a --- /dev/null +++ b/tests/loader/basics/onefile/elements/badfile.bst @@ -0,0 +1,5 @@ +# This is just invalid YAML +- | + this is malformed yaml. + +) diff --git a/tests/loader/basics/onefile/elements/badreference.bst b/tests/loader/basics/onefile/elements/badreference.bst new file mode 100644 index 000000000..9d320b2bf --- /dev/null +++ b/tests/loader/basics/onefile/elements/badreference.bst @@ -0,0 +1,3 @@ +# This bad YAML file makes a reference to an undefined entity +name: pony +pony: *pony diff --git a/tests/loader/basics/onefile/elements/onefile.bst b/tests/loader/basics/onefile/elements/onefile.bst new file mode 100644 index 000000000..ae4950585 --- /dev/null +++ b/tests/loader/basics/onefile/elements/onefile.bst @@ -0,0 +1,2 @@ +kind: pony +description: This is the pony diff --git a/tests/loader/dependencies.py b/tests/loader/dependencies.py new file mode 100644 index 000000000..77748249f --- /dev/null +++ b/tests/loader/dependencies.py @@ -0,0 +1,92 @@ +import os +import pytest + +from buildstream import LoadError, LoadErrorReason +from buildstream._loader import Loader +from buildstream._metaelement import MetaElement + +DATA_DIR = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + 'dependencies', +) + +############################################################## +# Basics: Test behavior loading projects with dependencies # +############################################################## +@pytest.mark.datafiles(DATA_DIR) +def test_two_files(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/target.bst', None, None) + element = loader.load() + + assert(isinstance(element, MetaElement)) + assert(element.kind == 'pony') + + assert(len(element.dependencies) == 1) + firstdep = element.dependencies[0] + assert(isinstance(firstdep, MetaElement)) + assert(firstdep.kind == 'thefirstdep') + + +@pytest.mark.datafiles(DATA_DIR) +def test_shared_dependency(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/shareddeptarget.bst', None, None) + element = loader.load() + + # Toplevel is 'pony' with 2 dependencies + # + assert(isinstance(element, MetaElement)) + assert(element.kind == 'pony') + assert(len(element.dependencies) == 2) + + # The first specified dependency is 'thefirstdep' + # + firstdep = element.dependencies[0] + assert(isinstance(firstdep, MetaElement)) + assert(firstdep.kind == 'thefirstdep') + assert(len(firstdep.dependencies) == 0) + + # The second specified dependency is 'shareddep' + # + shareddep = element.dependencies[1] + assert(isinstance(shareddep, MetaElement)) + assert(shareddep.kind == 'shareddep') + assert(len(shareddep.dependencies) == 1) + + # The element which shareddep depends on is + # the same element in memory as firstdep + # + shareddepdep = shareddep.dependencies[0] + assert(isinstance(shareddepdep, MetaElement)) + + # Assert they are in fact the same LoadElement + # + # Note we must use 'is' to test that both variables + # refer to the same object in memory, not a regular + # equality test with '==' which is one of those operator + # overridable thingies. + # + assert(shareddepdep is firstdep) + +@pytest.mark.datafiles(DATA_DIR) +def test_invalid_dependency_declaration(datafiles): + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/invaliddep.bst', None, None) + + with pytest.raises(LoadError) as exc: + element = loader.load() + + assert (exc.value.reason == LoadErrorReason.INVALID_DATA) + +@pytest.mark.datafiles(DATA_DIR) +def test_circular_dependency(datafiles): + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/circulartarget.bst', None, None) + + with pytest.raises(LoadError) as exc: + element = loader.load() + + assert (exc.value.reason == LoadErrorReason.CIRCULAR_DEPENDENCY) diff --git a/tests/loader/dependencies/elements/circular-firstdep.bst b/tests/loader/dependencies/elements/circular-firstdep.bst new file mode 100644 index 000000000..92f6993a2 --- /dev/null +++ b/tests/loader/dependencies/elements/circular-firstdep.bst @@ -0,0 +1,4 @@ +kind: pony +description: Depend on another dep which depends on the target +depends: +- elements/circular-seconddep.bst diff --git a/tests/loader/dependencies/elements/circular-seconddep.bst b/tests/loader/dependencies/elements/circular-seconddep.bst new file mode 100644 index 000000000..12a67ba75 --- /dev/null +++ b/tests/loader/dependencies/elements/circular-seconddep.bst @@ -0,0 +1,4 @@ +kind: pony +description: Depend on the target, creating a circular dependency +depends: +- elements/circulartarget.bst diff --git a/tests/loader/dependencies/elements/circulartarget.bst b/tests/loader/dependencies/elements/circulartarget.bst new file mode 100644 index 000000000..14db24682 --- /dev/null +++ b/tests/loader/dependencies/elements/circulartarget.bst @@ -0,0 +1,4 @@ +kind: pony +description: This is a main target which introduces a circular dependency +depends: +- elements/circular-firstdep.bst diff --git a/tests/loader/dependencies/elements/firstdep.bst b/tests/loader/dependencies/elements/firstdep.bst new file mode 100644 index 000000000..9b6a57824 --- /dev/null +++ b/tests/loader/dependencies/elements/firstdep.bst @@ -0,0 +1,2 @@ +kind: thefirstdep +description: This is the first dependency diff --git a/tests/loader/dependencies/elements/invaliddep.bst b/tests/loader/dependencies/elements/invaliddep.bst new file mode 100644 index 000000000..65c43c60a --- /dev/null +++ b/tests/loader/dependencies/elements/invaliddep.bst @@ -0,0 +1,4 @@ +kind: pony +description: This is an invalid dependency +depends: + more: it should be a list, not a dict diff --git a/tests/loader/dependencies/elements/shareddep.bst b/tests/loader/dependencies/elements/shareddep.bst new file mode 100644 index 000000000..cb98171f6 --- /dev/null +++ b/tests/loader/dependencies/elements/shareddep.bst @@ -0,0 +1,4 @@ +kind: shareddep +description: This is the first dependency +depends: +- elements/firstdep.bst diff --git a/tests/loader/dependencies/elements/shareddeptarget.bst b/tests/loader/dependencies/elements/shareddeptarget.bst new file mode 100644 index 000000000..03982d69f --- /dev/null +++ b/tests/loader/dependencies/elements/shareddeptarget.bst @@ -0,0 +1,5 @@ +kind: pony +description: This is the main target +depends: +- elements/firstdep.bst +- elements/shareddep.bst diff --git a/tests/loader/dependencies/elements/target.bst b/tests/loader/dependencies/elements/target.bst new file mode 100644 index 000000000..05c767956 --- /dev/null +++ b/tests/loader/dependencies/elements/target.bst @@ -0,0 +1,4 @@ +kind: pony +description: This is the main target +depends: +- elements/firstdep.bst diff --git a/tests/loader/includes.py b/tests/loader/includes.py new file mode 100644 index 000000000..60b20d557 --- /dev/null +++ b/tests/loader/includes.py @@ -0,0 +1,65 @@ +import os +import pytest + +from buildstream import LoadError, LoadErrorReason +from buildstream._loader import Loader +from buildstream._metaelement import MetaElement + +DATA_DIR = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + 'includes', +) + +############################################################## +# Test Basic Include Functionality # +############################################################## +@pytest.mark.datafiles(DATA_DIR) +def test_basic_include(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/target.bst', None, None) + element = loader.load() + + assert(isinstance(element, MetaElement)) + assert(element.kind == 'pony') + + # Assert that the stuff from the include got into the element data + assert(element.config.get('pony') == 'Someone rides their pony') + + thelist = element.config.get('list', None) + assert(isinstance(thelist, list)) + assert(thelist[0] == 'Element 1') + assert(thelist[1] == 'Element 2') + +@pytest.mark.datafiles(DATA_DIR) +def test_invalid_type_include(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/invalidinclude.bst', None, None) + + with pytest.raises(LoadError) as exc: + element = loader.load() + + assert (exc.value.reason == LoadErrorReason.ILLEGAL_COMPOSITE) + +@pytest.mark.datafiles(DATA_DIR) +def test_overwrite_kind_include(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/overwriting.bst', None, None) + + with pytest.raises(LoadError) as exc: + element = loader.load() + + assert (exc.value.reason == LoadErrorReason.ILLEGAL_COMPOSITE) + +@pytest.mark.datafiles(DATA_DIR) +def test_missing_include(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/missing.bst', None, None) + + with pytest.raises(LoadError) as exc: + element = loader.load() + + assert (exc.value.reason == LoadErrorReason.MISSING_FILE) diff --git a/tests/loader/includes/elements/invalidinclude.bst b/tests/loader/includes/elements/invalidinclude.bst new file mode 100644 index 000000000..ea1cad06f --- /dev/null +++ b/tests/loader/includes/elements/invalidinclude.bst @@ -0,0 +1,4 @@ +kind: pony +description: This includes a file which tries to override a regular attribute with a dict +include: include/invalidtype.bst +somekey: pony diff --git a/tests/loader/includes/elements/missing.bst b/tests/loader/includes/elements/missing.bst new file mode 100644 index 000000000..aaaaf1712 --- /dev/null +++ b/tests/loader/includes/elements/missing.bst @@ -0,0 +1,3 @@ +kind: pony +description: This is a missing include file that does not exist +include: include/missinginclude.bst diff --git a/tests/loader/includes/elements/overwriting.bst b/tests/loader/includes/elements/overwriting.bst new file mode 100644 index 000000000..0f33473d4 --- /dev/null +++ b/tests/loader/includes/elements/overwriting.bst @@ -0,0 +1,3 @@ +kind: pony +description: This includes a file which tries to override the 'kind', overwriting from an include is not allowed +include: include/overwritekind.bst diff --git a/tests/loader/includes/elements/target.bst b/tests/loader/includes/elements/target.bst new file mode 100644 index 000000000..740af38c0 --- /dev/null +++ b/tests/loader/includes/elements/target.bst @@ -0,0 +1,3 @@ +kind: pony +description: This is the main target, which includes another file +include: include/basicinclude.bst diff --git a/tests/loader/includes/include/basicinclude.bst b/tests/loader/includes/include/basicinclude.bst new file mode 100644 index 000000000..a7e85e8eb --- /dev/null +++ b/tests/loader/includes/include/basicinclude.bst @@ -0,0 +1,5 @@ +config: + pony: "Someone rides their pony" + list: + - "Element 1" + - "Element 2" diff --git a/tests/loader/includes/include/invalidtype.bst b/tests/loader/includes/include/invalidtype.bst new file mode 100644 index 000000000..f561c4705 --- /dev/null +++ b/tests/loader/includes/include/invalidtype.bst @@ -0,0 +1,4 @@ +pony: "Someone rides their pony" +somekey: + this: "pony" + that: "foo" diff --git a/tests/loader/includes/include/overwritekind.bst b/tests/loader/includes/include/overwritekind.bst new file mode 100644 index 000000000..ee8df0ca1 --- /dev/null +++ b/tests/loader/includes/include/overwritekind.bst @@ -0,0 +1,2 @@ +# You cannot overwrite members specified in the including element +kind: horse diff --git a/tests/loader/stacks.py b/tests/loader/stacks.py new file mode 100644 index 000000000..f71b78800 --- /dev/null +++ b/tests/loader/stacks.py @@ -0,0 +1,421 @@ +import os +import pytest + +from buildstream import LoadError, LoadErrorReason +from buildstream._loader import Loader +from buildstream._metaelement import MetaElement + +DATA_DIR = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + 'stacks', +) + + +@pytest.mark.datafiles(DATA_DIR) +def test_stack_basic(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + filename = os.path.join('elements', 'stack.bst') + loader = Loader(basedir, filename, None, 'x86_64') + + element = loader.load() + + assert(isinstance(element, MetaElement)) + assert(element.kind == 'stack') + + # Assert that the stuff from the include got into the element data, + # first check that we depend on both elements + assert(len(element.dependencies) == 2) + + pony = element.dependencies[0] + assert(isinstance(pony, MetaElement)) + assert(pony.kind == 'pony') + + horse = element.dependencies[1] + assert(isinstance(horse, MetaElement)) + assert(horse.kind == 'horsy') + + +@pytest.mark.datafiles(DATA_DIR) +def test_stack_dependencies(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + filename = os.path.join('elements', 'stackdepends.bst') + loader = Loader(basedir, filename, None, 'x86_64') + + element = loader.load() + + assert(isinstance(element, MetaElement)) + assert(element.kind == 'stack') + + # Assert that the stuff from the include got into the element data, + # first check that we depend on both elements + assert(len(element.dependencies) == 3) + + leaf = element.dependencies[0] + assert(isinstance(leaf, MetaElement)) + assert(leaf.kind == 'element') + + pony = element.dependencies[1] + assert(isinstance(pony, MetaElement)) + assert(pony.kind == 'pony') + assert(len(pony.dependencies) == 1) + + # By virtue of being embedded in a stack which + # depends on the leaf 'element', this element + # also depends on the leaf 'element' + ponyleaf = pony.dependencies[0] + assert(isinstance(ponyleaf, MetaElement)) + assert(ponyleaf.kind == 'element') + + horse = element.dependencies[2] + assert(isinstance(horse, MetaElement)) + assert(horse.kind == 'horsy') + assert(len(horse.dependencies) == 1) + + # By virtue of being embedded in a stack which + # depends on the leaf 'element', this element + # also depends on the leaf 'element' + horseleaf = horse.dependencies[0] + assert(isinstance(horseleaf, MetaElement)) + assert(horseleaf.kind == 'element') + + +@pytest.mark.datafiles(DATA_DIR) +def test_stack_includes(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/includingstack.bst', None, None) + + element = loader.load() + + assert(isinstance(element, MetaElement)) + assert(element.kind == 'stack') + + # Assert that the stuff from the include got into the element data, + # first check that we depend on both elements + assert(len(element.dependencies) == 2) + + pony = element.dependencies[0] + assert(isinstance(pony, MetaElement)) + assert(pony.kind == 'pony') + + horse = element.dependencies[1] + assert(isinstance(horse, MetaElement)) + assert(horse.kind == 'horsy') + + # Now check that the config data from the includes made it in + assert(pony.config.get('pony') == 'Someone rides their pony') + assert(horse.config.get('horse') == 'Riding a horse') + + +@pytest.mark.datafiles(DATA_DIR) +def test_stack_arch_default(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/archstack.bst', None, None) + + element = loader.load() + + assert(isinstance(element, MetaElement)) + assert(element.kind == 'stack') + assert(element.name == 'archstack') + + # Only one dependency, no known arch was selected + assert(len(element.dependencies) == 1) + rider = element.dependencies[0] + assert(isinstance(rider, MetaElement)) + assert(rider.kind == 'rider') + +@pytest.mark.datafiles(DATA_DIR) +def test_stack_arch_x86_64(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/archstack.bst', None, 'x86_64') + + element = loader.load() + + assert(isinstance(element, MetaElement)) + assert(element.kind == 'stack') + assert(element.name == 'archstack') + + # Two dependencies for x86_64 + assert(len(element.dependencies) == 2) + rider = element.dependencies[0] + assert(isinstance(rider, MetaElement)) + assert(rider.kind == 'rider') + + pony = element.dependencies[1] + assert(isinstance(pony, MetaElement)) + assert(pony.kind == 'pony') + + +@pytest.mark.datafiles(DATA_DIR) +def test_stack_arch_x86_32(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/archstack.bst', None, 'x86_32') + + element = loader.load() + + assert(isinstance(element, MetaElement)) + assert(element.kind == 'stack') + assert(element.name == 'archstack') + + # Two dependencies for x86_64 + assert(len(element.dependencies) == 2) + rider = element.dependencies[0] + assert(isinstance(rider, MetaElement)) + assert(rider.kind == 'rider') + + horse = element.dependencies[1] + assert(isinstance(horse, MetaElement)) + assert(horse.kind == 'horsy') + + +@pytest.mark.datafiles(DATA_DIR) +def test_stack_nested_arch_default(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/nestedarchstack.bst', None, None) + + element = loader.load() + + assert(isinstance(element, MetaElement)) + assert(element.kind == 'stack') + assert(element.name == 'nestedarchstack') + + # No specified arch, the color remains brown by default + assert(len(element.dependencies) == 1) + rider = element.dependencies[0] + assert(isinstance(rider, MetaElement)) + assert(rider.kind == 'rider') + assert(rider.config.get('color') == 'brown') + + +@pytest.mark.datafiles(DATA_DIR) +def test_stack_nested_arch_x86_64(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/nestedarchstack.bst', None, 'x86_64') + + element = loader.load() + + assert(isinstance(element, MetaElement)) + assert(element.kind == 'stack') + assert(element.name == 'nestedarchstack') + + # x86_64, the color is now pink + assert(len(element.dependencies) == 1) + rider = element.dependencies[0] + assert(isinstance(rider, MetaElement)) + assert(rider.kind == 'rider') + assert(rider.config.get('color') == 'pink') + + +@pytest.mark.datafiles(DATA_DIR) +def test_stack_nested_arch_x86_32(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/nestedarchstack.bst', None, 'x86_32') + + element = loader.load() + + assert(isinstance(element, MetaElement)) + assert(element.kind == 'stack') + assert(element.name == 'nestedarchstack') + + # x86_32, the color is now pink + assert(len(element.dependencies) == 1) + rider = element.dependencies[0] + assert(isinstance(rider, MetaElement)) + assert(rider.kind == 'rider') + assert(rider.config.get('color') == 'blue') + + +@pytest.mark.datafiles(DATA_DIR) +def test_stack_variant_default(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/variantstack.bst', None, None) + + element = loader.load() + + assert(isinstance(element, MetaElement)) + assert(element.kind == 'stack') + assert(element.name == 'variantstack') + + # No specified variant, we get a pony by default + assert(len(element.dependencies) == 2) + + rider = element.dependencies[0] + assert(isinstance(rider, MetaElement)) + assert(rider.kind == 'rider') + + pony = element.dependencies[1] + assert(isinstance(pony, MetaElement)) + assert(pony.kind == 'pony') + + +@pytest.mark.datafiles(DATA_DIR) +def test_stack_variant_pony(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/variantstack.bst', 'pony', None) + + element = loader.load() + + assert(isinstance(element, MetaElement)) + assert(element.kind == 'stack') + assert(element.name == 'variantstack') + + # We asked for the pony variant, we get a pony + assert(len(element.dependencies) == 2) + + rider = element.dependencies[0] + assert(isinstance(rider, MetaElement)) + assert(rider.kind == 'rider') + + pony = element.dependencies[1] + assert(isinstance(pony, MetaElement)) + assert(pony.kind == 'pony') + + +@pytest.mark.datafiles(DATA_DIR) +def test_stack_variant_horse(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/variantstack.bst', 'horse', None) + + element = loader.load() + + assert(isinstance(element, MetaElement)) + assert(element.kind == 'stack') + assert(element.name == 'variantstack') + + # We asked for the horse variant, we get a horse + assert(len(element.dependencies) == 2) + + rider = element.dependencies[0] + assert(isinstance(rider, MetaElement)) + assert(rider.kind == 'rider') + + horse = element.dependencies[1] + assert(isinstance(horse, MetaElement)) + assert(horse.kind == 'horsy') + + +@pytest.mark.datafiles(DATA_DIR) +def test_stack_nested_variant_default(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/nestedvariantstack.bst', None, None) + + element = loader.load() + + assert(isinstance(element, MetaElement)) + assert(element.kind == 'stack') + assert(element.name == 'nestedvariantstack') + + # No specified variant, we get a pony by default + assert(len(element.dependencies) == 3) + + rider = element.dependencies[0] + assert(isinstance(rider, MetaElement)) + assert(rider.kind == 'rider') + assert(rider.config.get('number') == 6) + + pony = element.dependencies[1] + assert(isinstance(pony, MetaElement)) + assert(pony.kind == 'pony') + assert(pony.config.get('number') == 6) + + horse = element.dependencies[2] + assert(isinstance(horse, MetaElement)) + assert(horse.kind == 'horsy') + assert(horse.config.get('number') == 5) + + +@pytest.mark.datafiles(DATA_DIR) +def test_stack_nested_variant_pony(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/nestedvariantstack.bst', 'pony', None) + + element = loader.load() + + assert(isinstance(element, MetaElement)) + assert(element.kind == 'stack') + assert(element.name == 'nestedvariantstack') + + # We asked for a pony, we get a pony + assert(len(element.dependencies) == 3) + + rider = element.dependencies[0] + assert(isinstance(rider, MetaElement)) + assert(rider.kind == 'rider') + assert(rider.config.get('number') == 6) + + pony = element.dependencies[1] + assert(isinstance(pony, MetaElement)) + assert(pony.kind == 'pony') + assert(pony.config.get('number') == 6) + + horse = element.dependencies[2] + assert(isinstance(horse, MetaElement)) + assert(horse.kind == 'horsy') + assert(horse.config.get('number') == 5) + + +@pytest.mark.datafiles(DATA_DIR) +def test_stack_nested_variant_horse(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/nestedvariantstack.bst', 'horse', None) + + element = loader.load() + + assert(isinstance(element, MetaElement)) + assert(element.kind == 'stack') + assert(element.name == 'nestedvariantstack') + + # We asked for a horse, we get a horse + assert(len(element.dependencies) == 3) + + rider = element.dependencies[0] + assert(isinstance(rider, MetaElement)) + assert(rider.kind == 'rider') + assert(rider.config.get('number') == 7) + + pony = element.dependencies[1] + assert(isinstance(pony, MetaElement)) + assert(pony.kind == 'pony') + assert(pony.config.get('number') == 5) + + horse = element.dependencies[2] + assert(isinstance(horse, MetaElement)) + assert(horse.kind == 'horsy') + assert(horse.config.get('number') == 7) + + +@pytest.mark.datafiles(DATA_DIR) +def test_stack_internal_circular_dependency(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/circulardepstack.bst', None, None) + + with pytest.raises(LoadError) as exc: + element = loader.load() + + assert (exc.value.reason == LoadErrorReason.CIRCULAR_DEPENDENCY) + +@pytest.mark.datafiles(DATA_DIR) +def test_stack_embedded_in_stack(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/stackinstack.bst', None, None) + + with pytest.raises(LoadError) as exc: + element = loader.load() + + assert (exc.value.reason == LoadErrorReason.INVALID_DATA) diff --git a/tests/loader/stacks/elements/archstack.bst b/tests/loader/stacks/elements/archstack.bst new file mode 100644 index 000000000..08239c345 --- /dev/null +++ b/tests/loader/stacks/elements/archstack.bst @@ -0,0 +1,15 @@ +kind: stack +description: This is a stack, and it's elements include stuff +embeds: +- name: rider + kind: rider +arches: + x86_64: + embeds: + - name: pony + kind: pony + x86_32: + embeds: + - name: horse + kind: horsy +
\ No newline at end of file diff --git a/tests/loader/stacks/elements/circulardepstack.bst b/tests/loader/stacks/elements/circulardepstack.bst new file mode 100644 index 000000000..9a65ff485 --- /dev/null +++ b/tests/loader/stacks/elements/circulardepstack.bst @@ -0,0 +1,15 @@ +kind: stack +description: This is a stack with an internal circular dependency +embeds: +- name: horse + kind: horsy + depends: + - rider +- name: pony + kind: pony + depends: + - horse +- name: rider + kind: rider + depends: + - pony diff --git a/tests/loader/stacks/elements/element.bst b/tests/loader/stacks/elements/element.bst new file mode 100644 index 000000000..366429eb1 --- /dev/null +++ b/tests/loader/stacks/elements/element.bst @@ -0,0 +1,4 @@ +kind: element +description: This is just a leaf element +config: + type: leaf diff --git a/tests/loader/stacks/elements/includingstack.bst b/tests/loader/stacks/elements/includingstack.bst new file mode 100644 index 000000000..79187e3ec --- /dev/null +++ b/tests/loader/stacks/elements/includingstack.bst @@ -0,0 +1,10 @@ +kind: stack +description: This is a stack, and it's elements include stuff +embeds: +- name: pony + kind: pony + include: include/pony.bst +- name: horse + kind: horsy + include: include/horse.bst + diff --git a/tests/loader/stacks/elements/nestedarchstack.bst b/tests/loader/stacks/elements/nestedarchstack.bst new file mode 100644 index 000000000..ddef648e4 --- /dev/null +++ b/tests/loader/stacks/elements/nestedarchstack.bst @@ -0,0 +1,14 @@ +kind: stack +description: This is a stack whos embedded elements have arch conditionals +embeds: +- name: rider + kind: rider + config: + color: brown + arches: + x86_64: + config: + color: pink + x86_32: + config: + color: blue diff --git a/tests/loader/stacks/elements/nestedvariantstack.bst b/tests/loader/stacks/elements/nestedvariantstack.bst new file mode 100644 index 000000000..3f6879fde --- /dev/null +++ b/tests/loader/stacks/elements/nestedvariantstack.bst @@ -0,0 +1,33 @@ +kind: stack +description: This is a stack, and variants define how the embedded elements are configured +embeds: +- name: rider + kind: rider + config: + number: 5 + variants: + - variant: pony + config: + number: 6 + - variant: horse + config: + number: 7 +- name: pony + kind: pony + config: + number: 5 + variants: + - variant: pony + config: + number: 6 +- name: horse + kind: horsy + config: + number: 5 + variants: + - variant: horse + config: + number: 7 +variants: +- variant: pony +- variant: horse diff --git a/tests/loader/stacks/elements/stack.bst b/tests/loader/stacks/elements/stack.bst new file mode 100644 index 000000000..1900e389b --- /dev/null +++ b/tests/loader/stacks/elements/stack.bst @@ -0,0 +1,7 @@ +kind: stack +description: This is a stack, and it's elements include stuff +embeds: +- name: pony + kind: pony +- name: horse + kind: horsy diff --git a/tests/loader/stacks/elements/stackdepends.bst b/tests/loader/stacks/elements/stackdepends.bst new file mode 100644 index 000000000..0d35f8464 --- /dev/null +++ b/tests/loader/stacks/elements/stackdepends.bst @@ -0,0 +1,9 @@ +kind: stack +description: This is a stack, and it's elements include stuff +depends: +- elements/element.bst +embeds: +- name: pony + kind: pony +- name: horse + kind: horsy diff --git a/tests/loader/stacks/elements/stackinstack.bst b/tests/loader/stacks/elements/stackinstack.bst new file mode 100644 index 000000000..5b91128d2 --- /dev/null +++ b/tests/loader/stacks/elements/stackinstack.bst @@ -0,0 +1,9 @@ +kind: stack +description: This is a stack embedded in a stack +embeds: +- name: horse + kind: stack + embeds: + - name: impossible + kind: mission + description: You cannot embed stacks inside stacks diff --git a/tests/loader/stacks/elements/variantstack.bst b/tests/loader/stacks/elements/variantstack.bst new file mode 100644 index 000000000..6b8b2c8a6 --- /dev/null +++ b/tests/loader/stacks/elements/variantstack.bst @@ -0,0 +1,14 @@ +kind: stack +description: This is a stack, and variants define what other elements to embed +embeds: +- name: rider + kind: rider +variants: +- variant: pony + embeds: + - name: pony + kind: pony +- variant: horse + embeds: + - name: horse + kind: horsy diff --git a/tests/loader/stacks/include/horse.bst b/tests/loader/stacks/include/horse.bst new file mode 100644 index 000000000..1003c9073 --- /dev/null +++ b/tests/loader/stacks/include/horse.bst @@ -0,0 +1,2 @@ +config: + horse: "Riding a horse" diff --git a/tests/loader/stacks/include/pony.bst b/tests/loader/stacks/include/pony.bst new file mode 100644 index 000000000..3e33614b5 --- /dev/null +++ b/tests/loader/stacks/include/pony.bst @@ -0,0 +1,2 @@ +config: + pony: "Someone rides their pony" diff --git a/tests/loader/variants.py b/tests/loader/variants.py new file mode 100644 index 000000000..bdea0642f --- /dev/null +++ b/tests/loader/variants.py @@ -0,0 +1,242 @@ +import os +import pytest + +from buildstream import LoadError, LoadErrorReason +from buildstream._loader import Loader +from buildstream._metaelement import MetaElement + +DATA_DIR = os.path.join( + os.path.dirname(os.path.realpath(__file__)), + 'variants', +) + +############################################################## +# Test Basic Failure Modes # +############################################################## +@pytest.mark.datafiles(DATA_DIR) +def test_variant_not_list(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/variants-not-list.bst', None, None) + + with pytest.raises(LoadError) as exc: + element = loader.load() + + assert (exc.value.reason == LoadErrorReason.INVALID_DATA) + +@pytest.mark.datafiles(DATA_DIR) +def test_variant_unnamed(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/unnamed-variant.bst', None, None) + + with pytest.raises(LoadError) as exc: + element = loader.load() + + assert (exc.value.reason == LoadErrorReason.INVALID_DATA) + +@pytest.mark.datafiles(DATA_DIR) +def test_variant_bad_name(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/variant-bad-name.bst', None, None) + + with pytest.raises(LoadError) as exc: + element = loader.load() + + assert (exc.value.reason == LoadErrorReason.INVALID_DATA) + +@pytest.mark.datafiles(DATA_DIR) +def test_variant_only_one(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/only-one-variant.bst', None, None) + + with pytest.raises(LoadError) as exc: + element = loader.load() + + assert (exc.value.reason == LoadErrorReason.INVALID_DATA) + +############################################################## +# Test Simple Variant Compositing # +############################################################## +@pytest.mark.datafiles(DATA_DIR) +def test_variant_simple_composite_default(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/simple-variant-compositing.bst', None, None) + + element = loader.load() + + assert(isinstance(element, MetaElement)) + assert(element.kind == 'pony') + + # Without specifying a variant, the default (first) should have been chosen + assert(element.config.get('somedata') == 5) + assert(element.config.get('pony-color') == 'pink') + +@pytest.mark.datafiles(DATA_DIR) +def test_variant_simple_composite_pink_pony(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/simple-variant-compositing.bst', 'pink', None) + + element = loader.load() + + assert(isinstance(element, MetaElement)) + assert(element.kind == 'pony') + + # We explicitly asked for the pink variation of this pony + assert(element.config.get('somedata') == 5) + assert(element.config.get('pony-color') == 'pink') + +@pytest.mark.datafiles(DATA_DIR) +def test_variant_simple_composite_blue_pony(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/simple-variant-compositing.bst', 'blue', None) + + element = loader.load() + + assert(isinstance(element, MetaElement)) + assert(element.kind == 'pony') + + # We explicitly asked for the blue variation of this pony, + # which has the side effect of overriding the value of 'somedata' + assert(element.config.get('somedata') == 6) + assert(element.config.get('pony-color') == 'blue') + +############################################################## +# Test Variant Dependency Plotting # +############################################################## + +# Convenience for asserting dependencies +# +def assert_dependency(element, index, name, key, value): + + # Test that the dependency we got is the pink color by default + assert(len(element.dependencies) >= index + 1) + dep = element.dependencies[index] + + assert(isinstance(dep, MetaElement)) + assert(dep.name == name) + assert(isinstance(dep.config, dict)) + assert(dep.config.get(key) == value) + + return dep + + +@pytest.mark.datafiles(DATA_DIR) +def test_variant_simple_dependency_default(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/simple-dependency-variants.bst', None, None) + element = loader.load() + + assert(isinstance(element, MetaElement)) + assert(element.kind == 'pony') + + # Test that the default is a pink pony + assert_dependency(element, 0, 'simply-pink', 'color', 'pink') + +@pytest.mark.datafiles(DATA_DIR) +def test_variant_simple_dependency_pink_pony(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/simple-dependency-variants.bst', 'pink', None) + element = loader.load() + + assert(isinstance(element, MetaElement)) + assert(element.kind == 'pony') + + # Test that the explicit pink dependency is correct + assert_dependency(element, 0, 'simply-pink', 'color', 'pink') + +@pytest.mark.datafiles(DATA_DIR) +def test_variant_simple_dependency_blue_pony(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/simple-dependency-variants.bst', 'blue', None) + element = loader.load() + + assert(isinstance(element, MetaElement)) + assert(element.kind == 'pony') + + # Test that the explicit blue dependency is correct + assert_dependency(element, 0, 'simply-blue', 'color', 'blue') + +@pytest.mark.datafiles(DATA_DIR) +def test_variant_indirect_dependency_default(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/indirect-dependency-variants.bst', None, None) + element = loader.load() + + assert(isinstance(element, MetaElement)) + assert(element.kind == 'pony') + + # Test that the default is a blue pony-color by default + simple = assert_dependency(element, 0, 'simple-dependency-variants', 'pony-color', 'blue') + + # Test that the element we depend on now depends on the blue color + assert_dependency(simple, 0, 'simply-blue', 'color', 'blue') + +@pytest.mark.datafiles(DATA_DIR) +def test_variant_indirect_dependency_blue_pony(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/indirect-dependency-variants.bst', 'blue', None) + element = loader.load() + + assert(isinstance(element, MetaElement)) + assert(element.kind == 'pony') + + # Test for a blue pony-color + simple = assert_dependency(element, 0, 'simple-dependency-variants', 'pony-color', 'blue') + + # Test that the element we depend on now depends on the blue color + assert_dependency(simple, 0, 'simply-blue', 'color', 'blue') + + +@pytest.mark.datafiles(DATA_DIR) +def test_variant_indirect_dependency_pink_pony(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/indirect-dependency-variants.bst', 'pink', None) + element = loader.load() + + assert(isinstance(element, MetaElement)) + assert(element.kind == 'pony') + + # Test for a blue pony-color + simple = assert_dependency(element, 0, 'simple-dependency-variants', 'pony-color', 'pink') + + # Test that the element we depend on now depends on the blue color + assert_dependency(simple, 0, 'simply-pink', 'color', 'pink') + + +@pytest.mark.datafiles(DATA_DIR) +def test_engine_resolve_agreement(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/tricky.bst', None, None) + element = loader.load() + + assert(isinstance(element, MetaElement)) + assert(element.kind == 'tricky') + + # Test the first dependency + first = assert_dependency(element, 0, 'tricky-first', 'choice', 'second') + second = assert_dependency(element, 1, 'tricky-second', 'choice', 'second') + + +@pytest.mark.datafiles(DATA_DIR) +def test_engine_disagreement(datafiles): + + basedir = os.path.join(datafiles.dirname, datafiles.basename) + loader = Loader(basedir, 'elements/disagreement.bst', None, None) + + with pytest.raises(LoadError) as exc: + element = loader.load() + + assert (exc.value.reason == LoadErrorReason.VARIANT_DISAGREEMENT) diff --git a/tests/loader/variants/elements/disagreement-one.bst b/tests/loader/variants/elements/disagreement-one.bst new file mode 100644 index 000000000..37ab8e833 --- /dev/null +++ b/tests/loader/variants/elements/disagreement-one.bst @@ -0,0 +1,6 @@ +kind: color +description: Something or other +choice: pony +depends: +- filename: elements/disagreement-two.bst + variant: first diff --git a/tests/loader/variants/elements/disagreement-two.bst b/tests/loader/variants/elements/disagreement-two.bst new file mode 100644 index 000000000..e5cec1546 --- /dev/null +++ b/tests/loader/variants/elements/disagreement-two.bst @@ -0,0 +1,8 @@ +kind: color +description: Something or other +choice: None +variants: +- variant: first + choice: first +- variant: second + choice: second diff --git a/tests/loader/variants/elements/disagreement.bst b/tests/loader/variants/elements/disagreement.bst new file mode 100644 index 000000000..b26c51c14 --- /dev/null +++ b/tests/loader/variants/elements/disagreement.bst @@ -0,0 +1,9 @@ +kind: disagreement +description: | + This pipeline cannot be built because elements are in disagreement about + what variants to choose + +depends: +- elements/disagreement-one.bst +- filename: elements/disagreement-two.bst + variant: second diff --git a/tests/loader/variants/elements/indirect-dependency-variants.bst b/tests/loader/variants/elements/indirect-dependency-variants.bst new file mode 100644 index 000000000..81f227691 --- /dev/null +++ b/tests/loader/variants/elements/indirect-dependency-variants.bst @@ -0,0 +1,17 @@ +kind: pony +description: | + Indirect dependency variants, depend on a different variant of the simple test, + depending on the selected variant +variants: +- variant: blue + config: + pony-color: blue + depends: + - filename: elements/simple-dependency-variants.bst + variant: blue +- variant: pink + config: + pony-color: pink + depends: + - filename: elements/simple-dependency-variants.bst + variant: pink diff --git a/tests/loader/variants/elements/only-one-variant.bst b/tests/loader/variants/elements/only-one-variant.bst new file mode 100644 index 000000000..623bf2655 --- /dev/null +++ b/tests/loader/variants/elements/only-one-variant.bst @@ -0,0 +1,8 @@ +kind: pony +description: | + Elements which declare variants must declare a minimum of two variants, even + if the declared variant does not augment the element in anyway. This is because + every variant of every element must be addressable by name. +variants: +- variant: pink + pony-color: pink diff --git a/tests/loader/variants/elements/simple-dependency-variants.bst b/tests/loader/variants/elements/simple-dependency-variants.bst new file mode 100644 index 000000000..721be88f3 --- /dev/null +++ b/tests/loader/variants/elements/simple-dependency-variants.bst @@ -0,0 +1,13 @@ +kind: pony +description: Simple dependency variants, different variants depend on different elements +variants: +- variant: pink + config: + pony-color: pink + depends: + - elements/simply-pink.bst +- variant: blue + config: + pony-color: blue + depends: + - elements/simply-blue.bst diff --git a/tests/loader/variants/elements/simple-variant-compositing.bst b/tests/loader/variants/elements/simple-variant-compositing.bst new file mode 100644 index 000000000..33c6571f2 --- /dev/null +++ b/tests/loader/variants/elements/simple-variant-compositing.bst @@ -0,0 +1,12 @@ +kind: pony +description: Simple test of variant compositing, without fancy dependencies +config: + somedata: 5 +variants: +- variant: pink + config: + pony-color: pink +- variant: blue + config: + pony-color: blue + somedata: 6 diff --git a/tests/loader/variants/elements/simply-blue.bst b/tests/loader/variants/elements/simply-blue.bst new file mode 100644 index 000000000..2565d762c --- /dev/null +++ b/tests/loader/variants/elements/simply-blue.bst @@ -0,0 +1,4 @@ +kind: color +description: A color dependency for variant tests +config: + color: blue diff --git a/tests/loader/variants/elements/simply-pink.bst b/tests/loader/variants/elements/simply-pink.bst new file mode 100644 index 000000000..b51a07f7b --- /dev/null +++ b/tests/loader/variants/elements/simply-pink.bst @@ -0,0 +1,4 @@ +kind: color +description: A color dependency for variant tests +config: + color: pink diff --git a/tests/loader/variants/elements/tricky-first.bst b/tests/loader/variants/elements/tricky-first.bst new file mode 100644 index 000000000..fdc14f75f --- /dev/null +++ b/tests/loader/variants/elements/tricky-first.bst @@ -0,0 +1,14 @@ +kind: color +description: Something or other +config: + choice: None +variants: +- variant: first + config: + choice: first + depends: + - filename: elements/tricky-second.bst + variant: first +- variant: second + config: + choice: second diff --git a/tests/loader/variants/elements/tricky-second.bst b/tests/loader/variants/elements/tricky-second.bst new file mode 100644 index 000000000..f386eaff4 --- /dev/null +++ b/tests/loader/variants/elements/tricky-second.bst @@ -0,0 +1,11 @@ +kind: color +description: Something or other +config: + choice: None +variants: +- variant: first + config: + choice: first +- variant: second + config: + choice: second diff --git a/tests/loader/variants/elements/tricky.bst b/tests/loader/variants/elements/tricky.bst new file mode 100644 index 000000000..06596cb1d --- /dev/null +++ b/tests/loader/variants/elements/tricky.bst @@ -0,0 +1,15 @@ +kind: tricky +description: | + This element depends ambivalently on tricky-first, then specifically + on the second variant of tricky-second. The default variant of tricky-first + depends explicitly on the first variant of tricky-second. + + This forces the engine to make a choice and resolve the tree, we're expecting + the tree to end up with: + o tricky + o tricky-first(second) + o tricky-second(second) +depends: +- elements/tricky-first.bst +- filename: elements/tricky-second.bst + variant: second diff --git a/tests/loader/variants/elements/unnamed-variant.bst b/tests/loader/variants/elements/unnamed-variant.bst new file mode 100644 index 000000000..18767e95c --- /dev/null +++ b/tests/loader/variants/elements/unnamed-variant.bst @@ -0,0 +1,5 @@ +kind: pony +description: This has variants but they dont specify the 'variant' name +variants: +- pony: 4 +- horse: Hello diff --git a/tests/loader/variants/elements/variant-bad-name.bst b/tests/loader/variants/elements/variant-bad-name.bst new file mode 100644 index 000000000..aefcfcf4b --- /dev/null +++ b/tests/loader/variants/elements/variant-bad-name.bst @@ -0,0 +1,9 @@ +kind: pony +description: These variants dont have string types for their name +variants: +- variant: + - pony + - horse + horse: Hello +- variant: 5 + pony: 4 diff --git a/tests/loader/variants/elements/variants-not-list.bst b/tests/loader/variants/elements/variants-not-list.bst new file mode 100644 index 000000000..9d5399939 --- /dev/null +++ b/tests/loader/variants/elements/variants-not-list.bst @@ -0,0 +1,3 @@ +kind: pony +description: This has variants but not a list of them +variants: This is not a list |