summaryrefslogtreecommitdiff
path: root/meta/lib/oeqa/selftest
diff options
context:
space:
mode:
Diffstat (limited to 'meta/lib/oeqa/selftest')
-rw-r--r--meta/lib/oeqa/selftest/devtool.py31
-rw-r--r--meta/lib/oeqa/selftest/recipetool.py313
2 files changed, 341 insertions, 3 deletions
diff --git a/meta/lib/oeqa/selftest/devtool.py b/meta/lib/oeqa/selftest/devtool.py
index f4571c4ef1..ad10af5826 100644
--- a/meta/lib/oeqa/selftest/devtool.py
+++ b/meta/lib/oeqa/selftest/devtool.py
@@ -8,7 +8,7 @@ import glob
import oeqa.utils.ftools as ftools
from oeqa.selftest.base import oeSelfTest
-from oeqa.utils.commands import runCmd, bitbake, get_bb_var
+from oeqa.utils.commands import runCmd, bitbake, get_bb_var, create_temp_layer
from oeqa.utils.decorators import testcase
class DevtoolBase(oeSelfTest):
@@ -31,6 +31,35 @@ class DevtoolBase(oeSelfTest):
for inherit in checkinherits:
self.assertIn(inherit, inherits, 'Missing inherit of %s' % inherit)
+ def _check_bbappend(self, testrecipe, recipefile, appenddir):
+ result = runCmd('bitbake-layers show-appends', cwd=self.builddir)
+ resultlines = result.output.splitlines()
+ inrecipe = False
+ bbappends = []
+ bbappendfile = None
+ for line in resultlines:
+ if inrecipe:
+ if line.startswith(' '):
+ bbappends.append(line.strip())
+ else:
+ break
+ elif line == '%s:' % os.path.basename(recipefile):
+ inrecipe = True
+ self.assertLessEqual(len(bbappends), 2, '%s recipe is being bbappended by another layer - bbappends found:\n %s' % (testrecipe, '\n '.join(bbappends)))
+ for bbappend in bbappends:
+ if bbappend.startswith(appenddir):
+ bbappendfile = bbappend
+ break
+ else:
+ self.assertTrue(False, 'bbappend for recipe %s does not seem to be created in test layer' % testrecipe)
+ return bbappendfile
+
+ def _create_temp_layer(self, templayerdir, addlayer, templayername, priority=999, recipepathspec='recipes-*/*'):
+ create_temp_layer(templayerdir, templayername, priority, recipepathspec)
+ if addlayer:
+ self.add_command_to_tearDown('bitbake-layers remove-layer %s || true' % templayerdir)
+ result = runCmd('bitbake-layers add-layer %s' % templayerdir, cwd=self.builddir)
+
class DevtoolTests(DevtoolBase):
diff --git a/meta/lib/oeqa/selftest/recipetool.py b/meta/lib/oeqa/selftest/recipetool.py
index 832fb7b16a..f3ad493457 100644
--- a/meta/lib/oeqa/selftest/recipetool.py
+++ b/meta/lib/oeqa/selftest/recipetool.py
@@ -6,16 +6,326 @@ import tempfile
import oeqa.utils.ftools as ftools
from oeqa.selftest.base import oeSelfTest
-from oeqa.utils.commands import runCmd, bitbake, get_bb_var
+from oeqa.utils.commands import runCmd, bitbake, get_bb_var, create_temp_layer
from oeqa.utils.decorators import testcase
from oeqa.selftest.devtool import DevtoolBase
+templayerdir = ''
+
+def setUpModule():
+ global templayerdir
+ templayerdir = tempfile.mkdtemp(prefix='recipetoolqa')
+ create_temp_layer(templayerdir, 'selftestrecipetool')
+ result = runCmd('bitbake-layers add-layer %s' % templayerdir)
+ # Ensure we have the right data in shlibs/pkgdata
+ logger = logging.getLogger("selftest")
+ logger.info('Running bitbake to generate pkgdata')
+ bitbake('base-files coreutils busybox selftest-recipetool-appendfile')
+
+def tearDownModule():
+ runCmd('bitbake-layers remove-layer %s' % templayerdir, ignore_status=True)
+ runCmd('rm -rf %s' % templayerdir)
+ # Shouldn't leave any traces of this artificial recipe behind
+ bitbake('-c cleansstate selftest-recipetool-appendfile')
+
+
class RecipetoolTests(DevtoolBase):
def setUpLocal(self):
self.tempdir = tempfile.mkdtemp(prefix='recipetoolqa')
self.track_for_cleanup(self.tempdir)
+ self.testfile = os.path.join(self.tempdir, 'testfile')
+ with open(self.testfile, 'w') as f:
+ f.write('Test file\n')
+
+ def tearDownLocal(self):
+ runCmd('rm -rf %s/recipes-*' % templayerdir)
+
+ def _try_recipetool_appendfile(self, testrecipe, destfile, newfile, options, expectedlines, expectedfiles):
+ result = runCmd('recipetool appendfile %s %s %s %s' % (templayerdir, destfile, newfile, options))
+ self.assertNotIn('Traceback', result.output)
+ # Check the bbappend was created and applies properly
+ recipefile = get_bb_var('FILE', testrecipe)
+ bbappendfile = self._check_bbappend(testrecipe, recipefile, templayerdir)
+ # Check the bbappend contents
+ with open(bbappendfile, 'r') as f:
+ self.assertEqual(expectedlines, f.readlines())
+ # Check file was copied
+ filesdir = os.path.join(os.path.dirname(bbappendfile), testrecipe)
+ for expectedfile in expectedfiles:
+ self.assertTrue(os.path.isfile(os.path.join(filesdir, expectedfile)), 'Expected file %s to be copied next to bbappend, but it wasn\'t' % expectedfile)
+ # Check no other files created
+ createdfiles = []
+ for root, _, files in os.walk(filesdir):
+ for f in files:
+ createdfiles.append(os.path.relpath(os.path.join(root, f), filesdir))
+ self.assertTrue(sorted(createdfiles), sorted(expectedfiles))
+ return bbappendfile, result.output
+
+ def _try_recipetool_appendfile_fail(self, destfile, newfile, checkerror):
+ cmd = 'recipetool appendfile %s %s %s' % (templayerdir, destfile, newfile)
+ result = runCmd(cmd, ignore_status=True)
+ self.assertNotEqual(result.status, 0, 'Command "%s" should have failed but didn\'t' % cmd)
+ self.assertNotIn('Traceback', result.output)
+ for errorstr in checkerror:
+ self.assertIn(errorstr, result.output)
+
+
+ def test_recipetool_appendfile_basic(self):
+ # Basic test
+ expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ '\n']
+ _, output = self._try_recipetool_appendfile('base-files', '/etc/motd', self.testfile, '', expectedlines, ['motd'])
+ self.assertNotIn('WARNING: ', output)
+
+ def test_recipetool_appendfile_invalid(self):
+ # Test some commands that should error
+ self._try_recipetool_appendfile_fail('/etc/passwd', self.testfile, ['ERROR: /etc/passwd cannot be handled by this tool', 'useradd', 'extrausers'])
+ self._try_recipetool_appendfile_fail('/etc/timestamp', self.testfile, ['ERROR: /etc/timestamp cannot be handled by this tool'])
+ self._try_recipetool_appendfile_fail('/dev/console', self.testfile, ['ERROR: /dev/console cannot be handled by this tool'])
+
+ def test_recipetool_appendfile_alternatives(self):
+ # Now try with a file we know should be an alternative
+ # (this is very much a fake example, but one we know is reliably an alternative)
+ self._try_recipetool_appendfile_fail('/bin/ls', self.testfile, ['ERROR: File /bin/ls is an alternative possibly provided by the following recipes:', 'coreutils', 'busybox'])
+ corebase = get_bb_var('COREBASE')
+ # Need a test file - should be executable
+ testfile2 = os.path.join(corebase, 'oe-init-build-env')
+ testfile2name = os.path.basename(testfile2)
+ expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ '\n',
+ 'SRC_URI += "file://%s"\n' % testfile2name,
+ '\n',
+ 'do_install_append() {\n',
+ ' install -d ${D}${base_bindir}\n',
+ ' install -m 0755 ${WORKDIR}/%s ${D}${base_bindir}/ls\n' % testfile2name,
+ '}\n']
+ self._try_recipetool_appendfile('coreutils', '/bin/ls', testfile2, '-r coreutils', expectedlines, [testfile2name])
+ # Now try bbappending the same file again, contents should not change
+ bbappendfile, _ = self._try_recipetool_appendfile('coreutils', '/bin/ls', self.testfile, '-r coreutils', expectedlines, [testfile2name])
+ # But file should have
+ copiedfile = os.path.join(os.path.dirname(bbappendfile), 'coreutils', testfile2name)
+ result = runCmd('diff -q %s %s' % (testfile2, copiedfile), ignore_status=True)
+ self.assertNotEqual(result.status, 0, 'New file should have been copied but was not')
+
+ def test_recipetool_appendfile_binary(self):
+ # Try appending a binary file
+ result = runCmd('recipetool appendfile %s /bin/ls /bin/ls -r coreutils' % templayerdir)
+ self.assertIn('WARNING: ', result.output)
+ self.assertIn('is a binary', result.output)
+
+ def test_recipetool_appendfile_add(self):
+ corebase = get_bb_var('COREBASE')
+ # Try arbitrary file add to a recipe
+ expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ '\n',
+ 'SRC_URI += "file://testfile"\n',
+ '\n',
+ 'do_install_append() {\n',
+ ' install -d ${D}${datadir}\n',
+ ' install -m 0644 ${WORKDIR}/testfile ${D}${datadir}/something\n',
+ '}\n']
+ self._try_recipetool_appendfile('netbase', '/usr/share/something', self.testfile, '-r netbase', expectedlines, ['testfile'])
+ # Try adding another file, this time where the source file is executable
+ # (so we're testing that, plus modifying an existing bbappend)
+ testfile2 = os.path.join(corebase, 'oe-init-build-env')
+ testfile2name = os.path.basename(testfile2)
+ expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ '\n',
+ 'SRC_URI += "file://testfile \\\n',
+ ' file://%s \\\n' % testfile2name,
+ ' "\n',
+ '\n',
+ 'do_install_append() {\n',
+ ' install -d ${D}${datadir}\n',
+ ' install -m 0644 ${WORKDIR}/testfile ${D}${datadir}/something\n',
+ ' install -m 0755 ${WORKDIR}/%s ${D}${datadir}/scriptname\n' % testfile2name,
+ '}\n']
+ self._try_recipetool_appendfile('netbase', '/usr/share/scriptname', testfile2, '-r netbase', expectedlines, ['testfile', testfile2name])
+
+ def test_recipetool_appendfile_add_bindir(self):
+ # Try arbitrary file add to a recipe, this time to a location such that should be installed as executable
+ expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ '\n',
+ 'SRC_URI += "file://testfile"\n',
+ '\n',
+ 'do_install_append() {\n',
+ ' install -d ${D}${bindir}\n',
+ ' install -m 0755 ${WORKDIR}/testfile ${D}${bindir}/selftest-recipetool-testbin\n',
+ '}\n']
+ _, output = self._try_recipetool_appendfile('netbase', '/usr/bin/selftest-recipetool-testbin', self.testfile, '-r netbase', expectedlines, ['testfile'])
+ self.assertNotIn('WARNING: ', output)
+
+ def test_recipetool_appendfile_add_machine(self):
+ # Try arbitrary file add to a recipe, this time to a location such that should be installed as executable
+ expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ '\n',
+ 'PACKAGE_ARCH = "${MACHINE_ARCH}"\n',
+ '\n',
+ 'SRC_URI_append_mymachine = " file://testfile"\n',
+ '\n',
+ 'do_install_append_mymachine() {\n',
+ ' install -d ${D}${datadir}\n',
+ ' install -m 0644 ${WORKDIR}/testfile ${D}${datadir}/something\n',
+ '}\n']
+ _, output = self._try_recipetool_appendfile('netbase', '/usr/share/something', self.testfile, '-r netbase -m mymachine', expectedlines, ['mymachine/testfile'])
+ self.assertNotIn('WARNING: ', output)
+
+ def test_recipetool_appendfile_orig(self):
+ # A file that's in SRC_URI and in do_install with the same name
+ expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ '\n']
+ _, output = self._try_recipetool_appendfile('selftest-recipetool-appendfile', '/usr/share/selftest-replaceme-orig', self.testfile, '', expectedlines, ['selftest-replaceme-orig'])
+ self.assertNotIn('WARNING: ', output)
+
+ def test_recipetool_appendfile_todir(self):
+ # A file that's in SRC_URI and in do_install with destination directory rather than file
+ expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ '\n']
+ _, output = self._try_recipetool_appendfile('selftest-recipetool-appendfile', '/usr/share/selftest-replaceme-todir', self.testfile, '', expectedlines, ['selftest-replaceme-todir'])
+ self.assertNotIn('WARNING: ', output)
+
+ def test_recipetool_appendfile_renamed(self):
+ # A file that's in SRC_URI with a different name to the destination file
+ expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ '\n']
+ _, output = self._try_recipetool_appendfile('selftest-recipetool-appendfile', '/usr/share/selftest-replaceme-renamed', self.testfile, '', expectedlines, ['file1'])
+ self.assertNotIn('WARNING: ', output)
+
+ def test_recipetool_appendfile_subdir(self):
+ # A file that's in SRC_URI in a subdir
+ expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ '\n',
+ 'SRC_URI += "file://testfile"\n',
+ '\n',
+ 'do_install_append() {\n',
+ ' install -d ${D}${datadir}\n',
+ ' install -m 0644 ${WORKDIR}/testfile ${D}${datadir}/selftest-replaceme-subdir\n',
+ '}\n']
+ _, output = self._try_recipetool_appendfile('selftest-recipetool-appendfile', '/usr/share/selftest-replaceme-subdir', self.testfile, '', expectedlines, ['testfile'])
+ self.assertNotIn('WARNING: ', output)
+
+ def test_recipetool_appendfile_src_glob(self):
+ # A file that's in SRC_URI as a glob
+ expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ '\n',
+ 'SRC_URI += "file://testfile"\n',
+ '\n',
+ 'do_install_append() {\n',
+ ' install -d ${D}${datadir}\n',
+ ' install -m 0644 ${WORKDIR}/testfile ${D}${datadir}/selftest-replaceme-src-globfile\n',
+ '}\n']
+ _, output = self._try_recipetool_appendfile('selftest-recipetool-appendfile', '/usr/share/selftest-replaceme-src-globfile', self.testfile, '', expectedlines, ['testfile'])
+ self.assertNotIn('WARNING: ', output)
+
+ def test_recipetool_appendfile_inst_glob(self):
+ # A file that's in do_install as a glob
+ expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ '\n']
+ _, output = self._try_recipetool_appendfile('selftest-recipetool-appendfile', '/usr/share/selftest-replaceme-inst-globfile', self.testfile, '', expectedlines, ['selftest-replaceme-inst-globfile'])
+ self.assertNotIn('WARNING: ', output)
+
+ def test_recipetool_appendfile_inst_todir_glob(self):
+ # A file that's in do_install as a glob with destination as a directory
+ expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ '\n']
+ _, output = self._try_recipetool_appendfile('selftest-recipetool-appendfile', '/usr/share/selftest-replaceme-inst-todir-globfile', self.testfile, '', expectedlines, ['selftest-replaceme-inst-todir-globfile'])
+ self.assertNotIn('WARNING: ', output)
+
+ def test_recipetool_appendfile_patch(self):
+ # A file that's added by a patch in SRC_URI
+ expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ '\n',
+ 'SRC_URI += "file://testfile"\n',
+ '\n',
+ 'do_install_append() {\n',
+ ' install -d ${D}${sysconfdir}\n',
+ ' install -m 0644 ${WORKDIR}/testfile ${D}${sysconfdir}/selftest-replaceme-patched\n',
+ '}\n']
+ _, output = self._try_recipetool_appendfile('selftest-recipetool-appendfile', '/etc/selftest-replaceme-patched', self.testfile, '', expectedlines, ['testfile'])
+ for line in output.splitlines():
+ if line.startswith('WARNING: '):
+ self.assertIn('add-file.patch', line, 'Unexpected warning found in output:\n%s' % line)
+ break
+ else:
+ self.assertTrue(False, 'Patch warning not found in output:\n%s' % output)
+
+ def test_recipetool_appendfile_script(self):
+ # Now, a file that's in SRC_URI but installed by a script (so no mention in do_install)
+ expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ '\n',
+ 'SRC_URI += "file://testfile"\n',
+ '\n',
+ 'do_install_append() {\n',
+ ' install -d ${D}${datadir}\n',
+ ' install -m 0644 ${WORKDIR}/testfile ${D}${datadir}/selftest-replaceme-scripted\n',
+ '}\n']
+ _, output = self._try_recipetool_appendfile('selftest-recipetool-appendfile', '/usr/share/selftest-replaceme-scripted', self.testfile, '', expectedlines, ['testfile'])
+ self.assertNotIn('WARNING: ', output)
+
+ def test_recipetool_appendfile_inst_func(self):
+ # A file that's installed from a function called by do_install
+ expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ '\n']
+ _, output = self._try_recipetool_appendfile('selftest-recipetool-appendfile', '/usr/share/selftest-replaceme-inst-func', self.testfile, '', expectedlines, ['selftest-replaceme-inst-func'])
+ self.assertNotIn('WARNING: ', output)
+
+ def test_recipetool_appendfile_postinstall(self):
+ # A file that's created by a postinstall script (and explicitly mentioned in it)
+ # First try without specifying recipe
+ self._try_recipetool_appendfile_fail('/usr/share/selftest-replaceme-postinst', self.testfile, ['File /usr/share/selftest-replaceme-postinst may be written out in a pre/postinstall script of the following recipes:', 'selftest-recipetool-appendfile'])
+ # Now specify recipe
+ expectedlines = ['FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"\n',
+ '\n',
+ 'SRC_URI += "file://testfile"\n',
+ '\n',
+ 'do_install_append() {\n',
+ ' install -d ${D}${datadir}\n',
+ ' install -m 0644 ${WORKDIR}/testfile ${D}${datadir}/selftest-replaceme-postinst\n',
+ '}\n']
+ _, output = self._try_recipetool_appendfile('selftest-recipetool-appendfile', '/usr/share/selftest-replaceme-postinst', self.testfile, '-r selftest-recipetool-appendfile', expectedlines, ['testfile'])
+
+ def test_recipetool_appendfile_extlayer(self):
+ # Try creating a bbappend in a layer that's not in bblayers.conf and has a different structure
+ exttemplayerdir = os.path.join(self.tempdir, 'extlayer')
+ self._create_temp_layer(exttemplayerdir, False, 'oeselftestextlayer', recipepathspec='metadata/recipes/recipes-*/*')
+ result = runCmd('recipetool appendfile %s /usr/share/selftest-replaceme-orig %s' % (exttemplayerdir, self.testfile))
+ self.assertNotIn('Traceback', result.output)
+ createdfiles = []
+ for root, _, files in os.walk(exttemplayerdir):
+ for f in files:
+ createdfiles.append(os.path.relpath(os.path.join(root, f), exttemplayerdir))
+ createdfiles.remove('conf/layer.conf')
+ expectedfiles = ['metadata/recipes/recipes-test/selftest-recipetool-appendfile/selftest-recipetool-appendfile.bbappend',
+ 'metadata/recipes/recipes-test/selftest-recipetool-appendfile/selftest-recipetool-appendfile/selftest-replaceme-orig']
+ self.assertEqual(sorted(createdfiles), sorted(expectedfiles))
+
+ def test_recipetool_appendfile_wildcard(self):
+
+ def try_appendfile_wc(options):
+ result = runCmd('recipetool appendfile %s /etc/profile %s %s' % (templayerdir, self.testfile, options))
+ self.assertNotIn('Traceback', result.output)
+ bbappendfile = None
+ for root, _, files in os.walk(templayerdir):
+ for f in files:
+ if f.endswith('.bbappend'):
+ bbappendfile = f
+ break
+ if not bbappendfile:
+ self.assertTrue(False, 'No bbappend file created')
+ runCmd('rm -rf %s/recipes-*' % templayerdir)
+ return bbappendfile
+
+ # Check without wildcard option
+ recipefn = os.path.basename(get_bb_var('FILE', 'base-files'))
+ filename = try_appendfile_wc('')
+ self.assertEqual(filename, recipefn.replace('.bb', '.bbappend'))
+ # Now check with wildcard option
+ filename = try_appendfile_wc('-w')
+ self.assertEqual(filename, recipefn.split('_')[0] + '_%.bbappend')
+
+
def test_recipetool_create(self):
# Try adding a recipe
@@ -52,4 +362,3 @@ class RecipetoolTests(DevtoolBase):
checkvars['DEPENDS'] = 'libpng pango libx11 libxext jpeg'
inherits = ['autotools', 'pkgconfig']
self._test_recipe_contents(recipefile, checkvars, inherits)
-