diff options
Diffstat (limited to 'yocto-poky/meta/lib/oeqa/selftest/devtool.py')
-rw-r--r-- | yocto-poky/meta/lib/oeqa/selftest/devtool.py | 216 |
1 files changed, 185 insertions, 31 deletions
diff --git a/yocto-poky/meta/lib/oeqa/selftest/devtool.py b/yocto-poky/meta/lib/oeqa/selftest/devtool.py index dcdef5a14..132a73d0e 100644 --- a/yocto-poky/meta/lib/oeqa/selftest/devtool.py +++ b/yocto-poky/meta/lib/oeqa/selftest/devtool.py @@ -15,18 +15,45 @@ class DevtoolBase(oeSelfTest): def _test_recipe_contents(self, recipefile, checkvars, checkinherits): with open(recipefile, 'r') as f: + invar = None + invalue = None for line in f: - if '=' in line: + var = None + if invar: + value = line.strip().strip('"') + if value.endswith('\\'): + invalue += ' ' + value[:-1].strip() + continue + else: + invalue += ' ' + value.strip() + var = invar + value = invalue + invar = None + elif '=' in line: splitline = line.split('=', 1) var = splitline[0].rstrip() value = splitline[1].strip().strip('"') - if var in checkvars: - needvalue = checkvars.pop(var) - self.assertEqual(value, needvalue, 'values for %s do not match' % var) - if line.startswith('inherit '): + if value.endswith('\\'): + invalue = value[:-1].strip() + invar = var + continue + elif line.startswith('inherit '): inherits = line.split()[1:] - self.assertEqual(checkvars, {}, 'Some variables not found: %s' % checkvars) + if var and var in checkvars: + needvalue = checkvars.pop(var) + if needvalue is None: + self.fail('Variable %s should not appear in recipe') + if isinstance(needvalue, set): + value = set(value.split()) + self.assertEqual(value, needvalue, 'values for %s do not match' % var) + + + missingvars = {} + for var, value in checkvars.iteritems(): + if value is not None: + missingvars[var] = value + self.assertEqual(missingvars, {}, 'Some expected variables not found in recipe: %s' % checkvars) for inherit in checkinherits: self.assertIn(inherit, inherits, 'Missing inherit of %s' % inherit) @@ -68,6 +95,8 @@ class DevtoolBase(oeSelfTest): filelist = [] for line in output.splitlines(): splitline = line.split() + if len(splitline) < 8: + self.fail('_process_ls_output: invalid output line: %s' % line) # Remove trailing . on perms splitline[0] = splitline[0].rstrip('.') # Remove leading . on paths @@ -172,6 +201,44 @@ class DevtoolTests(DevtoolBase): bindir = bindir[1:] self.assertTrue(os.path.isfile(os.path.join(installdir, bindir, 'pv')), 'pv binary not found in D') + @testcase(1423) + def test_devtool_add_git_local(self): + # Fetch source from a remote URL, but do it outside of devtool + tempdir = tempfile.mkdtemp(prefix='devtoolqa') + self.track_for_cleanup(tempdir) + pn = 'dbus-wait' + # We choose an https:// git URL here to check rewriting the URL works + url = 'https://git.yoctoproject.org/git/dbus-wait' + # Force fetching to "noname" subdir so we verify we're picking up the name from autoconf + # instead of the directory name + result = runCmd('git clone %s noname' % url, cwd=tempdir) + srcdir = os.path.join(tempdir, 'noname') + self.assertTrue(os.path.isfile(os.path.join(srcdir, 'configure.ac')), 'Unable to find configure script in source directory') + # Test devtool add + self.track_for_cleanup(self.workspacedir) + self.add_command_to_tearDown('bitbake-layers remove-layer */workspace') + # Don't specify a name since we should be able to auto-detect it + result = runCmd('devtool add %s' % srcdir) + self.assertTrue(os.path.exists(os.path.join(self.workspacedir, 'conf', 'layer.conf')), 'Workspace directory not created') + # Check the recipe name is correct + recipefile = get_bb_var('FILE', pn) + self.assertIn('%s_git.bb' % pn, recipefile, 'Recipe file incorrectly named') + self.assertIn(recipefile, result.output) + # Test devtool status + result = runCmd('devtool status') + self.assertIn(pn, result.output) + self.assertIn(srcdir, result.output) + self.assertIn(recipefile, result.output) + checkvars = {} + checkvars['LICENSE'] = 'GPLv2' + checkvars['LIC_FILES_CHKSUM'] = 'file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263' + checkvars['S'] = '${WORKDIR}/git' + checkvars['PV'] = '0.1+git${SRCPV}' + checkvars['SRC_URI'] = 'git://git.yoctoproject.org/git/dbus-wait;protocol=https' + checkvars['SRCREV'] = '${AUTOREV}' + checkvars['DEPENDS'] = set(['dbus']) + self._test_recipe_contents(recipefile, checkvars, []) + @testcase(1162) def test_devtool_add_library(self): # We don't have the ability to pick up this dependency automatically yet... @@ -179,15 +246,16 @@ class DevtoolTests(DevtoolBase): # Fetch source tempdir = tempfile.mkdtemp(prefix='devtoolqa') self.track_for_cleanup(tempdir) - url = 'http://www.intra2net.com/en/developer/libftdi/download/libftdi1-1.1.tar.bz2' + version = '1.1' + url = 'https://www.intra2net.com/en/developer/libftdi/download/libftdi1-%s.tar.bz2' % version result = runCmd('wget %s' % url, cwd=tempdir) - result = runCmd('tar xfv libftdi1-1.1.tar.bz2', cwd=tempdir) - srcdir = os.path.join(tempdir, 'libftdi1-1.1') + result = runCmd('tar xfv libftdi1-%s.tar.bz2' % version, cwd=tempdir) + srcdir = os.path.join(tempdir, 'libftdi1-%s' % version) self.assertTrue(os.path.isfile(os.path.join(srcdir, 'CMakeLists.txt')), 'Unable to find CMakeLists.txt in source directory') # Test devtool add (and use -V so we test that too) self.track_for_cleanup(self.workspacedir) self.add_command_to_tearDown('bitbake-layers remove-layer */workspace') - result = runCmd('devtool add libftdi %s -V 1.1' % srcdir) + result = runCmd('devtool add libftdi %s -V %s' % (srcdir, version)) self.assertTrue(os.path.exists(os.path.join(self.workspacedir, 'conf', 'layer.conf')), 'Workspace directory not created') # Test devtool status result = runCmd('devtool status') @@ -195,6 +263,14 @@ class DevtoolTests(DevtoolBase): self.assertIn(srcdir, result.output) # Clean up anything in the workdir/sysroot/sstate cache (have to do this *after* devtool add since the recipe only exists then) bitbake('libftdi -c cleansstate') + # libftdi's python/CMakeLists.txt is a bit broken, so let's just disable it + # There's also the matter of it installing cmake files to a path we don't + # normally cover, which triggers the installed-vs-shipped QA test we have + # within do_package + recipefile = '%s/recipes/libftdi/libftdi_%s.bb' % (self.workspacedir, version) + result = runCmd('recipetool setvar %s EXTRA_OECMAKE -- \'-DPYTHON_BINDINGS=OFF -DLIBFTDI_CMAKE_CONFIG_DIR=${datadir}/cmake/Modules\'' % recipefile) + with open(recipefile, 'a') as f: + f.write('\nFILES_${PN}-dev += "${datadir}/cmake/Modules"\n') # Test devtool build result = runCmd('devtool build libftdi') staging_libdir = get_bb_var('STAGING_LIBDIR', 'libftdi') @@ -226,21 +302,23 @@ class DevtoolTests(DevtoolBase): result = runCmd('devtool add %s %s -f %s' % (testrecipe, srcdir, url)) self.assertTrue(os.path.exists(os.path.join(self.workspacedir, 'conf', 'layer.conf')), 'Workspace directory not created. %s' % result.output) self.assertTrue(os.path.isfile(os.path.join(srcdir, 'setup.py')), 'Unable to find setup.py in source directory') + self.assertTrue(os.path.isdir(os.path.join(srcdir, '.git')), 'git repository for external source tree was not created') # Test devtool status result = runCmd('devtool status') self.assertIn(testrecipe, result.output) self.assertIn(srcdir, result.output) # Check recipe recipefile = get_bb_var('FILE', testrecipe) - self.assertIn('%s.bb' % testrecipe, recipefile, 'Recipe file incorrectly named') + self.assertIn('%s_%s.bb' % (testrecipe, testver), recipefile, 'Recipe file incorrectly named') checkvars = {} - checkvars['S'] = '${WORKDIR}/MarkupSafe-%s' % testver - checkvars['SRC_URI'] = url + checkvars['S'] = '${WORKDIR}/MarkupSafe-${PV}' + checkvars['SRC_URI'] = url.replace(testver, '${PV}') self._test_recipe_contents(recipefile, checkvars, []) # Try with version specified result = runCmd('devtool reset -n %s' % testrecipe) shutil.rmtree(srcdir) - result = runCmd('devtool add %s %s -f %s -V %s' % (testrecipe, srcdir, url, testver)) + fakever = '1.9' + result = runCmd('devtool add %s %s -f %s -V %s' % (testrecipe, srcdir, url, fakever)) self.assertTrue(os.path.isfile(os.path.join(srcdir, 'setup.py')), 'Unable to find setup.py in source directory') # Test devtool status result = runCmd('devtool status') @@ -248,10 +326,10 @@ class DevtoolTests(DevtoolBase): self.assertIn(srcdir, result.output) # Check recipe recipefile = get_bb_var('FILE', testrecipe) - self.assertIn('%s_%s.bb' % (testrecipe, testver), recipefile, 'Recipe file incorrectly named') + self.assertIn('%s_%s.bb' % (testrecipe, fakever), recipefile, 'Recipe file incorrectly named') checkvars = {} - checkvars['S'] = '${WORKDIR}/MarkupSafe-${PV}' - checkvars['SRC_URI'] = url.replace(testver, '${PV}') + checkvars['S'] = '${WORKDIR}/MarkupSafe-%s' % testver + checkvars['SRC_URI'] = url self._test_recipe_contents(recipefile, checkvars, []) @testcase(1161) @@ -279,7 +357,7 @@ class DevtoolTests(DevtoolBase): self.assertIn('_git.bb', recipefile, 'Recipe file incorrectly named') checkvars = {} checkvars['S'] = '${WORKDIR}/git' - checkvars['PV'] = '1.0+git${SRCPV}' + checkvars['PV'] = '1.11+git${SRCPV}' checkvars['SRC_URI'] = url checkvars['SRCREV'] = '${AUTOREV}' self._test_recipe_contents(recipefile, checkvars, []) @@ -303,6 +381,34 @@ class DevtoolTests(DevtoolBase): checkvars['SRCREV'] = checkrev self._test_recipe_contents(recipefile, checkvars, []) + @testcase(1391) + def test_devtool_add_fetch_simple(self): + # Fetch source from a remote URL, auto-detecting name + tempdir = tempfile.mkdtemp(prefix='devtoolqa') + self.track_for_cleanup(tempdir) + testver = '1.6.0' + url = 'http://www.ivarch.com/programs/sources/pv-%s.tar.bz2' % testver + testrecipe = 'pv' + srcdir = os.path.join(self.workspacedir, 'sources', testrecipe) + # Test devtool add + self.track_for_cleanup(self.workspacedir) + self.add_command_to_tearDown('bitbake-layers remove-layer */workspace') + result = runCmd('devtool add %s' % url) + self.assertTrue(os.path.exists(os.path.join(self.workspacedir, 'conf', 'layer.conf')), 'Workspace directory not created. %s' % result.output) + self.assertTrue(os.path.isfile(os.path.join(srcdir, 'configure')), 'Unable to find configure script in source directory') + self.assertTrue(os.path.isdir(os.path.join(srcdir, '.git')), 'git repository for external source tree was not created') + # Test devtool status + result = runCmd('devtool status') + self.assertIn(testrecipe, result.output) + self.assertIn(srcdir, result.output) + # Check recipe + recipefile = get_bb_var('FILE', testrecipe) + self.assertIn('%s_%s.bb' % (testrecipe, testver), recipefile, 'Recipe file incorrectly named') + checkvars = {} + checkvars['S'] = None + checkvars['SRC_URI'] = url.replace(testver, '${PV}') + self._test_recipe_contents(recipefile, checkvars, []) + @testcase(1164) def test_devtool_modify(self): # Clean up anything in the workdir/sysroot/sstate cache @@ -504,7 +610,8 @@ class DevtoolTests(DevtoolBase): self.track_for_cleanup(self.workspacedir) self.add_command_to_tearDown('bitbake-layers remove-layer */workspace') # (don't bother with cleaning the recipe on teardown, we won't be building it) - result = runCmd('devtool modify %s -x %s' % (testrecipe, tempdir)) + # We don't use -x here so that we test the behaviour of devtool modify without it + result = runCmd('devtool modify %s %s' % (testrecipe, tempdir)) # Check git repo self._check_src_repo(tempdir) # Add a couple of commits @@ -823,10 +930,11 @@ class DevtoolTests(DevtoolBase): tempdir = tempfile.mkdtemp(prefix='devtoolqa') # Try devtool extract self.track_for_cleanup(tempdir) - self.track_for_cleanup(self.workspacedir) - self.add_command_to_tearDown('bitbake-layers remove-layer */workspace') + self.append_config('PREFERRED_PROVIDER_virtual/make = "remake"') result = runCmd('devtool extract remake %s' % tempdir) self.assertTrue(os.path.exists(os.path.join(tempdir, 'Makefile.am')), 'Extracted source could not be found') + # devtool extract shouldn't create the workspace + self.assertFalse(os.path.exists(self.workspacedir)) self._check_src_repo(tempdir) @testcase(1379) @@ -834,10 +942,10 @@ class DevtoolTests(DevtoolBase): tempdir = tempfile.mkdtemp(prefix='devtoolqa') # Try devtool extract self.track_for_cleanup(tempdir) - self.track_for_cleanup(self.workspacedir) - self.add_command_to_tearDown('bitbake-layers remove-layer */workspace') result = runCmd('devtool extract virtual/libx11 %s' % tempdir) self.assertTrue(os.path.exists(os.path.join(tempdir, 'Makefile.am')), 'Extracted source could not be found') + # devtool extract shouldn't create the workspace + self.assertFalse(os.path.exists(self.workspacedir)) self._check_src_repo(tempdir) @testcase(1168) @@ -920,7 +1028,7 @@ class DevtoolTests(DevtoolBase): result = runCmd('devtool deploy-target -n %s root@localhost' % testrecipe) self.assertIn(' %s' % testfile, result.output) # Boot the image - with runqemu(testimage, self) as qemu: + with runqemu(testimage) as qemu: # Now really test deploy-target result = runCmd('devtool deploy-target -c %s root@%s' % (testrecipe, qemu.ip)) # Run a test command to see if it was installed properly @@ -990,14 +1098,18 @@ class DevtoolTests(DevtoolBase): def test_devtool_upgrade(self): # Check preconditions self.assertTrue(not os.path.exists(self.workspacedir), 'This test cannot be run with a workspace directory under the build directory') + self.track_for_cleanup(self.workspacedir) + self.add_command_to_tearDown('bitbake-layers remove-layer */workspace') # Check parameters result = runCmd('devtool upgrade -h') for param in 'recipename srctree --version -V --branch -b --keep-temp --no-patch'.split(): self.assertIn(param, result.output) # For the moment, we are using a real recipe. - recipe='devtool-upgrade' - version='0.2' + recipe = 'devtool-upgrade-test1' + version = '1.6.0' + oldrecipefile = get_bb_var('FILE', recipe) tempdir = tempfile.mkdtemp(prefix='devtoolqa') + self.track_for_cleanup(tempdir) # Check that recipe is not already under devtool control result = runCmd('devtool status') self.assertNotIn(recipe, result.output) @@ -1005,22 +1117,64 @@ class DevtoolTests(DevtoolBase): # we are downgrading instead of upgrading. result = runCmd('devtool upgrade %s %s -V %s' % (recipe, tempdir, version)) # Check if srctree at least is populated - self.assertTrue(len(os.listdir(tempdir)) > 0, 'scrtree (%s) should be populated with new (%s) source code' % (tempdir, version)) - # Check new recipe folder is present - self.assertTrue(os.path.exists(os.path.join(self.workspacedir,'recipes',recipe)), 'Recipe folder should exist') + self.assertTrue(len(os.listdir(tempdir)) > 0, 'srctree (%s) should be populated with new (%s) source code' % (tempdir, version)) + # Check new recipe subdirectory is present + self.assertTrue(os.path.exists(os.path.join(self.workspacedir, 'recipes', recipe, '%s-%s' % (recipe, version))), 'Recipe folder should exist') # Check new recipe file is present - self.assertTrue(os.path.exists(os.path.join(self.workspacedir,'recipes',recipe,"%s_%s.bb" % (recipe,version))), 'Recipe folder should exist') + newrecipefile = os.path.join(self.workspacedir, 'recipes', recipe, '%s_%s.bb' % (recipe, version)) + self.assertTrue(os.path.exists(newrecipefile), 'Recipe file should exist after upgrade') # Check devtool status and make sure recipe is present result = runCmd('devtool status') self.assertIn(recipe, result.output) self.assertIn(tempdir, result.output) + # Check recipe got changed as expected + with open(oldrecipefile + '.upgraded', 'r') as f: + desiredlines = f.readlines() + with open(newrecipefile, 'r') as f: + newlines = f.readlines() + self.assertEqual(desiredlines, newlines) # Check devtool reset recipe result = runCmd('devtool reset %s -n' % recipe) result = runCmd('devtool status') self.assertNotIn(recipe, result.output) - self.track_for_cleanup(tempdir) + self.assertFalse(os.path.exists(os.path.join(self.workspacedir, 'recipes', recipe)), 'Recipe directory should not exist after resetting') + + @testcase(1433) + def test_devtool_upgrade_git(self): + # Check preconditions + self.assertTrue(not os.path.exists(self.workspacedir), 'This test cannot be run with a workspace directory under the build directory') self.track_for_cleanup(self.workspacedir) self.add_command_to_tearDown('bitbake-layers remove-layer */workspace') + recipe = 'devtool-upgrade-test2' + commit = '6cc6077a36fe2648a5f993fe7c16c9632f946517' + oldrecipefile = get_bb_var('FILE', recipe) + tempdir = tempfile.mkdtemp(prefix='devtoolqa') + self.track_for_cleanup(tempdir) + # Check that recipe is not already under devtool control + result = runCmd('devtool status') + self.assertNotIn(recipe, result.output) + # Check upgrade + result = runCmd('devtool upgrade %s %s -S %s' % (recipe, tempdir, commit)) + # Check if srctree at least is populated + self.assertTrue(len(os.listdir(tempdir)) > 0, 'srctree (%s) should be populated with new (%s) source code' % (tempdir, commit)) + # Check new recipe file is present + newrecipefile = os.path.join(self.workspacedir, 'recipes', recipe, os.path.basename(oldrecipefile)) + self.assertTrue(os.path.exists(newrecipefile), 'Recipe file should exist after upgrade') + # Check devtool status and make sure recipe is present + result = runCmd('devtool status') + self.assertIn(recipe, result.output) + self.assertIn(tempdir, result.output) + # Check recipe got changed as expected + with open(oldrecipefile + '.upgraded', 'r') as f: + desiredlines = f.readlines() + with open(newrecipefile, 'r') as f: + newlines = f.readlines() + self.assertEqual(desiredlines, newlines) + # Check devtool reset recipe + result = runCmd('devtool reset %s -n' % recipe) + result = runCmd('devtool status') + self.assertNotIn(recipe, result.output) + self.assertFalse(os.path.exists(os.path.join(self.workspacedir, 'recipes', recipe)), 'Recipe directory should not exist after resetting') @testcase(1352) def test_devtool_layer_plugins(self): |