summaryrefslogtreecommitdiff
path: root/yocto-poky/meta/lib/oeqa/selftest/devtool.py
diff options
context:
space:
mode:
Diffstat (limited to 'yocto-poky/meta/lib/oeqa/selftest/devtool.py')
-rw-r--r--yocto-poky/meta/lib/oeqa/selftest/devtool.py216
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):