From a32a8f1ce1795a930094b6045d7a34309fc8a08a Mon Sep 17 00:00:00 2001 From: Ian Wienand Date: Wed, 31 Jan 2018 13:16:57 +1100 Subject: [PATCH] Fail if two elements provide the same thing The current check only validates that an element that specifies "element-provides" doesn't conflict with a "real" element. We also want to check this against the provides of other elements. A real example is with a "block-device" element. There is no actual "block-device" element; we can have multiple elements provide it (block-device-[gpt,mbr,efi], say) but we only want one of them at a time. Update the unit test for this. Change-Id: I59d4aa5f6f09e2892b213e154befa10d85e95ca3 --- diskimage_builder/element_dependencies.py | 9 +++++++-- diskimage_builder/tests/test_elementdeps.py | 12 ++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/diskimage_builder/element_dependencies.py b/diskimage_builder/element_dependencies.py index 6ee851635..c11e8649e 100644 --- a/diskimage_builder/element_dependencies.py +++ b/diskimage_builder/element_dependencies.py @@ -151,9 +151,14 @@ def _expand_element_dependencies(user_elements, all_elements): element_deps = element_obj.depends element_provides = element_obj.provides - # save which elements provide another element for potential - # error message + # Check that we are not providing an element which has already + # been provided by someone else, and additionally save which + # elements provide another element for provide in element_provides: + if provide in provided: + raise AlreadyProvidedException( + "%s: already provided by %s" % + (provide, provided_by[provide])) provided_by[provide].append(element) provided.update(element_provides) check_queue.extend(element_deps - (final_elements | provided)) diff --git a/diskimage_builder/tests/test_elementdeps.py b/diskimage_builder/tests/test_elementdeps.py index 299ddfe82..b4c8fc37c 100644 --- a/diskimage_builder/tests/test_elementdeps.py +++ b/diskimage_builder/tests/test_elementdeps.py @@ -67,6 +67,10 @@ class TestElementDeps(testtools.TestCase): 'provides_virtual', [], ['virtual']) + _populate_element(self.element_dir, + 'also_provides_virtual', + [], + ['virtual']) _populate_element(self.element_dir, 'requires_virtual', ['virtual'], @@ -168,6 +172,14 @@ class TestElementDeps(testtools.TestCase): [self._e('requires_new_virtual'), self._e('provides_new_virtual')], result) + def test_elements_provide_same(self): + msg = "virtual: already provided by \['provides_virtual'\]" + self.assertRaisesRegexp(element_dependencies.AlreadyProvidedException, + msg, + element_dependencies.get_elements, + ['provides_virtual', 'also_provides_virtual'], + self.element_dirs) + def test_no_os_element(self): self.assertRaises(element_dependencies.MissingOSException, element_dependencies.get_elements,