@@ -1327,6 +1327,139 @@ class DevtoolModifyTests(DevtoolBase):
self.assertExists(os.path.join(source_repo_gitsm_gitmodules, 'bitbake'), 'Submodule not found')
self.assertExists(os.path.join(source_repo_gitsm_gitmodules, 'bitbake-gitsm-test1'), 'Submodule not found')
+class DevtoolMulticonfigTests(DevtoolBase):
+
+ def setUp(self):
+ super(DevtoolMulticonfigTests, self).setUp()
+ self.recipe = 'devtool-multiconfig-test'
+ self.target = 'mc:devtooltest:%s' % self.recipe
+ self.tempdir = tempfile.mkdtemp(prefix='devtoolqa')
+ self.track_for_cleanup(self.tempdir)
+ self.track_for_cleanup(self.workspacedir)
+ self.srctree = os.path.join(self.tempdir, 'source')
+ self.layerdir = os.path.join(self.tempdir, 'meta-devtool-multiconfig')
+
+ self.append_config('BBMULTICONFIG = "devtooltest"\n')
+ # Only this configuration satisfies the test recipe's compatibility
+ # restriction, regardless of the machine used by the selftest runner.
+ self.write_config('MACHINEOVERRIDES .= ":devtool-mc"\n'
+ 'TMPDIR = "${TOPDIR}/tmp-devtool-mc"\n', 'devtooltest')
+ self.add_command_to_tearDown('bitbake -c clean %s' % self.target)
+ self.add_command_to_tearDown('bitbake-layers remove-layer */workspace')
+ self._create_temp_layer(self.layerdir, True, 'devtoolmulticonfig')
+
+ self.recipedir = os.path.join(self.layerdir, 'recipes-test', self.recipe)
+ filesdir = os.path.join(self.recipedir, self.recipe)
+ os.makedirs(filesdir)
+ archive = 'devtool-test-subdir.tar.gz'
+ shutil.copyfile(os.path.join(get_test_layer(), 'recipes-test', 'devtool',
+ 'devtool-test-subdir', archive),
+ os.path.join(filesdir, archive))
+ with open(os.path.join(self.recipedir, self.recipe + '_1.0.bb'), 'w') as f:
+ f.write('LICENSE = "MIT"\n'
+ 'LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302"\n'
+ 'inherit allarch\n'
+ 'INHIBIT_DEFAULT_DEPS = "1"\n'
+ 'COMPATIBLE_MACHINE = "devtool-mc"\n'
+ 'SRC_URI = "file://devtool-test-subdir.tar.gz"\n'
+ 'S = "${UNPACKDIR}/devtool-test-subdir"\n'
+ 'B = "${WORKDIR}/build"\n'
+ 'do_compile() {\n'
+ ' cp ${S}/testfile ${B}/testfile\n'
+ '}\n'
+ 'do_install() {\n'
+ ' install -Dm0644 ${B}/testfile ${D}${datadir}/${BPN}/testfile\n'
+ '}\n'
+ 'FILES:${PN} = "${datadir}/${BPN}"\n')
+
+ def _modify(self, wildcard=False):
+ runCmd('devtool modify %s %s %s' %
+ ('--wildcard' if wildcard else '', self.target, self.srctree))
+ self._check_src_repo(self.srctree)
+ append = os.path.join(self.workspacedir, 'appends', 'multiconfig',
+ 'devtooltest', self.recipe + ('_%.bbappend' if wildcard else '_1.0.bbappend'))
+ self.assertExists(append)
+ self.assertEqual(get_bb_var('EXTERNALSRC', self.target), self.srctree)
+ self.assertIn(self.recipe, runCmd('devtool status').output)
+ return append
+
+ def test_devtool_multiconfig_modify_build_reset(self):
+ """Extract, build and clean a recipe unavailable in the default config."""
+ result = bitbake('%s -n' % self.recipe, ignore_status=True)
+ self.assertNotEqual(result.status, 0)
+ self.assertIn('incompatible with machine', result.output)
+
+ append = self._modify()
+ with open(os.path.join(self.srctree, 'testfile'), 'a') as f:
+ f.write('\nmulticonfig workspace change\n')
+ runCmd('devtool build %s' % self.target)
+ builddir = get_bb_var('B', self.target)
+ with open(os.path.join(builddir, 'testfile')) as f:
+ self.assertIn('multiconfig workspace change', f.read())
+
+ # Do not use --no-clean: cleaning must retain the multiconfig prefix.
+ runCmd('devtool reset %s' % self.target)
+ self.assertNotExists(append)
+ self.assertNotIn(self.recipe, runCmd('devtool status').output)
+ self.assertFalse(get_bb_var('EXTERNALSRC', self.target))
+
+ def test_devtool_multiconfig_update_finish(self):
+ """Update and finish using qualified targets and bare workspace keys."""
+ append = self._modify()
+ for command, marker in [('update-recipe', 'update'), ('finish', 'finish')]:
+ with open(os.path.join(self.srctree, 'testfile'), 'a') as f:
+ f.write('\nmulticonfig %s change\n' % marker)
+ runCmd('git commit -am "Multiconfig %s change" '
+ '-m "Upstream-Status: Inappropriate [selftest]"' % marker,
+ cwd=self.srctree)
+ destination = self.layerdir if command == 'finish' else ''
+ runCmd('devtool %s %s %s' % (command, self.target, destination))
+ patches = glob.glob(os.path.join(self.recipedir, self.recipe, '*.patch'))
+ self.assertTrue(patches, 'No patches written by %s' % command)
+ contents = ''
+ for patch in patches:
+ with open(patch) as f:
+ contents += f.read()
+ self.assertIn('multiconfig %s change' % marker, contents)
+ if command == 'update-recipe':
+ self.assertExists(append)
+ self.assertIn(self.recipe, runCmd('devtool status').output)
+
+ self.assertNotExists(append)
+ self.assertNotIn(self.recipe, runCmd('devtool status').output)
+ self.assertFalse(get_bb_var('EXTERNALSRC', self.target))
+ bitbake('%s -c patch' % self.target)
+ with open(os.path.join(get_bb_var('S', self.target), 'testfile')) as f:
+ contents = f.read()
+ self.assertIn('multiconfig update change', contents)
+ self.assertIn('multiconfig finish change', contents)
+
+ def test_devtool_multiconfig_workspace_isolation(self):
+ """A wildcard workspace append must affect only its configuration."""
+ self.append_config('COMPATIBLE_MACHINE:pn-%s = ".*"\n'
+ 'BBMULTICONFIG += "devtoolother"\n' % self.recipe)
+ self.write_config('TMPDIR = "${TOPDIR}/tmp-devtool-other"\n', 'devtoolother')
+ other_target = 'mc:devtoolother:%s' % self.recipe
+ append = self._modify(wildcard=True)
+ self.assertFalse(get_bb_var('EXTERNALSRC', self.recipe))
+ self.assertFalse(get_bb_var('EXTERNALSRC', other_target))
+
+ result = runCmd('devtool modify -n %s %s' % (self.recipe, self.srctree),
+ ignore_status=True)
+ self.assertNotEqual(result.status, 0)
+ self.assertIn('already in your workspace', result.output)
+ self.assertExists(append)
+ runCmd('devtool reset %s' % self.target)
+ self.assertNotExists(append)
+
+ # The default configuration's append must likewise stay out of MCs.
+ runCmd('devtool modify -n %s %s' % (self.recipe, self.srctree))
+ self.assertEqual(get_bb_var('EXTERNALSRC', self.recipe), self.srctree)
+ self.assertFalse(get_bb_var('EXTERNALSRC', self.target))
+ self.assertFalse(get_bb_var('EXTERNALSRC', other_target))
+ runCmd('devtool reset %s' % self.recipe)
+
+
class DevtoolUpdateTests(DevtoolBase):
def test_devtool_update_recipe(self):
Cover modify, build, reset, update-recipe and finish with a recipe available only in the selected multiconfig. Check workspace isolation between configurations. [YOCTO #13933] Signed-off-by: Anusmita Dutta Mazumder <anusmita.duttamazumder@arm.com> --- meta/lib/oeqa/selftest/cases/devtool.py | 133 ++++++++++++++++++++++++ 1 file changed, 133 insertions(+)