123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290 |
- #
- # Copyright (C) 2013-2017 Intel Corporation
- #
- # SPDX-License-Identifier: MIT
- #
- import sys
- import os
- import shutil
- import glob
- import errno
- from unittest.util import safe_repr
- import oeqa.utils.ftools as ftools
- from oeqa.utils.commands import runCmd, bitbake, get_bb_var
- from oeqa.core.case import OETestCase
- import bb.utils
- class OESelftestTestCase(OETestCase):
- def __init__(self, methodName="runTest"):
- self._extra_tear_down_commands = []
- super(OESelftestTestCase, self).__init__(methodName)
- @classmethod
- def setUpClass(cls):
- super(OESelftestTestCase, cls).setUpClass()
- cls.testlayer_path = cls.tc.config_paths['testlayer_path']
- cls.builddir = cls.tc.config_paths['builddir']
- cls.localconf_path = cls.tc.config_paths['localconf']
- cls.localconf_backup = cls.tc.config_paths['localconf_class_backup']
- cls.local_bblayers_path = cls.tc.config_paths['bblayers']
- cls.local_bblayers_backup = cls.tc.config_paths['bblayers_class_backup']
- cls.testinc_path = os.path.join(cls.tc.config_paths['builddir'],
- "conf/selftest.inc")
- cls.testinc_bblayers_path = os.path.join(cls.tc.config_paths['builddir'],
- "conf/bblayers.inc")
- cls.machineinc_path = os.path.join(cls.tc.config_paths['builddir'],
- "conf/machine.inc")
- cls._track_for_cleanup = [
- cls.testinc_path, cls.testinc_bblayers_path,
- cls.machineinc_path, cls.localconf_backup,
- cls.local_bblayers_backup]
- cls.add_include()
- @classmethod
- def tearDownClass(cls):
- cls.remove_include()
- cls.remove_inc_files()
- super(OESelftestTestCase, cls).tearDownClass()
- @classmethod
- def add_include(cls):
- if "#include added by oe-selftest" \
- not in ftools.read_file(os.path.join(cls.builddir, "conf/local.conf")):
- cls.logger.info("Adding: \"include selftest.inc\" in %s" % os.path.join(cls.builddir, "conf/local.conf"))
- ftools.append_file(os.path.join(cls.builddir, "conf/local.conf"), \
- "\n#include added by oe-selftest\ninclude machine.inc\ninclude selftest.inc")
- if "#include added by oe-selftest" \
- not in ftools.read_file(os.path.join(cls.builddir, "conf/bblayers.conf")):
- cls.logger.info("Adding: \"include bblayers.inc\" in bblayers.conf")
- ftools.append_file(os.path.join(cls.builddir, "conf/bblayers.conf"), \
- "\n#include added by oe-selftest\ninclude bblayers.inc")
- @classmethod
- def remove_include(cls):
- if "#include added by oe-selftest.py" \
- in ftools.read_file(os.path.join(cls.builddir, "conf/local.conf")):
- cls.logger.info("Removing the include from local.conf")
- ftools.remove_from_file(os.path.join(cls.builddir, "conf/local.conf"), \
- "\n#include added by oe-selftest.py\ninclude machine.inc\ninclude selftest.inc")
- if "#include added by oe-selftest.py" \
- in ftools.read_file(os.path.join(cls.builddir, "conf/bblayers.conf")):
- cls.logger.info("Removing the include from bblayers.conf")
- ftools.remove_from_file(os.path.join(cls.builddir, "conf/bblayers.conf"), \
- "\n#include added by oe-selftest.py\ninclude bblayers.inc")
- @classmethod
- def remove_inc_files(cls):
- try:
- os.remove(os.path.join(cls.builddir, "conf/selftest.inc"))
- for root, _, files in os.walk(cls.testlayer_path):
- for f in files:
- if f == 'test_recipe.inc':
- os.remove(os.path.join(root, f))
- except OSError as e:
- pass
- for incl_file in ['conf/bblayers.inc', 'conf/machine.inc']:
- try:
- os.remove(os.path.join(cls.builddir, incl_file))
- except:
- pass
- def setUp(self):
- super(OESelftestTestCase, self).setUp()
- os.chdir(self.builddir)
- # Check if local.conf or bblayers.conf files backup exists
- # from a previous failed test and restore them
- if os.path.isfile(self.localconf_backup) or os.path.isfile(
- self.local_bblayers_backup):
- self.logger.debug("\
- Found a local.conf and/or bblayers.conf backup from a previously aborted test.\
- Restoring these files now, but tests should be re-executed from a clean environment\
- to ensure accurate results.")
- try:
- shutil.copyfile(self.localconf_backup, self.localconf_path)
- except OSError as e:
- if e.errno != errno.ENOENT:
- raise
- try:
- shutil.copyfile(self.local_bblayers_backup,
- self.local_bblayers_path)
- except OSError as e:
- if e.errno != errno.ENOENT:
- raise
- else:
- # backup local.conf and bblayers.conf
- shutil.copyfile(self.localconf_path, self.localconf_backup)
- shutil.copyfile(self.local_bblayers_path, self.local_bblayers_backup)
- self.logger.debug("Creating local.conf and bblayers.conf backups.")
- # we don't know what the previous test left around in config or inc files
- # if it failed so we need a fresh start
- try:
- os.remove(self.testinc_path)
- except OSError as e:
- if e.errno != errno.ENOENT:
- raise
- for root, _, files in os.walk(self.testlayer_path):
- for f in files:
- if f == 'test_recipe.inc':
- os.remove(os.path.join(root, f))
- for incl_file in [self.testinc_bblayers_path, self.machineinc_path]:
- try:
- os.remove(incl_file)
- except OSError as e:
- if e.errno != errno.ENOENT:
- raise
- if self.tc.custommachine:
- machine_conf = 'MACHINE ??= "%s"\n' % self.tc.custommachine
- self.set_machine_config(machine_conf)
- # tests might need their own setup
- # but if they overwrite this one they have to call
- # super each time, so let's give them an alternative
- self.setUpLocal()
- def setUpLocal(self):
- pass
- def tearDown(self):
- if self._extra_tear_down_commands:
- failed_extra_commands = []
- for command in self._extra_tear_down_commands:
- result = runCmd(command, ignore_status=True)
- if not result.status == 0:
- failed_extra_commands.append(command)
- if failed_extra_commands:
- self.logger.warning("tearDown commands have failed: %s" % ', '.join(map(str, failed_extra_commands)))
- self.logger.debug("Trying to move on.")
- self._extra_tear_down_commands = []
- if self._track_for_cleanup:
- for path in self._track_for_cleanup:
- if os.path.isdir(path):
- bb.utils.remove(path, recurse=True)
- if os.path.isfile(path):
- os.remove(path)
- self._track_for_cleanup = []
- self.tearDownLocal()
- super(OESelftestTestCase, self).tearDown()
- def tearDownLocal(self):
- pass
- def add_command_to_tearDown(self, command):
- """Add test specific commands to the tearDown method"""
- self.logger.debug("Adding command '%s' to tearDown for this test." % command)
- self._extra_tear_down_commands.append(command)
- def track_for_cleanup(self, path):
- """Add test specific files or directories to be removed in the tearDown method"""
- self.logger.debug("Adding path '%s' to be cleaned up when test is over" % path)
- self._track_for_cleanup.append(path)
- def write_config(self, data, multiconfig=None):
- """Write to config file"""
- if multiconfig:
- multiconfigdir = "%s/conf/multiconfig" % self.builddir
- os.makedirs(multiconfigdir, exist_ok=True)
- dest_path = '%s/%s.conf' % (multiconfigdir, multiconfig)
- self.track_for_cleanup(dest_path)
- else:
- dest_path = self.testinc_path
- self.logger.debug("Writing to: %s\n%s\n" % (dest_path, data))
- ftools.write_file(dest_path, data)
- if not multiconfig and self.tc.custommachine and 'MACHINE' in data:
- machine = get_bb_var('MACHINE')
- self.logger.warning('MACHINE overridden: %s' % machine)
- def append_config(self, data):
- """Append to <builddir>/conf/selftest.inc"""
- self.logger.debug("Appending to: %s\n%s\n" % (self.testinc_path, data))
- ftools.append_file(self.testinc_path, data)
- if self.tc.custommachine and 'MACHINE' in data:
- machine = get_bb_var('MACHINE')
- self.logger.warning('MACHINE overridden: %s' % machine)
- def remove_config(self, data):
- """Remove data from <builddir>/conf/selftest.inc"""
- self.logger.debug("Removing from: %s\n%s\n" % (self.testinc_path, data))
- ftools.remove_from_file(self.testinc_path, data)
- def recipeinc(self, recipe):
- """Return absolute path of meta-selftest/recipes-test/<recipe>/test_recipe.inc"""
- return os.path.join(self.testlayer_path, 'recipes-test', recipe, 'test_recipe.inc')
- def write_recipeinc(self, recipe, data):
- """Write to meta-selftest/recipes-test/<recipe>/test_recipe.inc"""
- inc_file = self.recipeinc(recipe)
- self.logger.debug("Writing to: %s\n%s\n" % (inc_file, data))
- ftools.write_file(inc_file, data)
- return inc_file
- def append_recipeinc(self, recipe, data):
- """Append data to meta-selftest/recipes-test/<recipe>/test_recipe.inc"""
- inc_file = self.recipeinc(recipe)
- self.logger.debug("Appending to: %s\n%s\n" % (inc_file, data))
- ftools.append_file(inc_file, data)
- return inc_file
- def remove_recipeinc(self, recipe, data):
- """Remove data from meta-selftest/recipes-test/<recipe>/test_recipe.inc"""
- inc_file = self.recipeinc(recipe)
- self.logger.debug("Removing from: %s\n%s\n" % (inc_file, data))
- ftools.remove_from_file(inc_file, data)
- def delete_recipeinc(self, recipe):
- """Delete meta-selftest/recipes-test/<recipe>/test_recipe.inc file"""
- inc_file = self.recipeinc(recipe)
- self.logger.debug("Deleting file: %s" % inc_file)
- try:
- os.remove(inc_file)
- except OSError as e:
- if e.errno != errno.ENOENT:
- raise
- def write_bblayers_config(self, data):
- """Write to <builddir>/conf/bblayers.inc"""
- self.logger.debug("Writing to: %s\n%s\n" % (self.testinc_bblayers_path, data))
- ftools.write_file(self.testinc_bblayers_path, data)
- def append_bblayers_config(self, data):
- """Append to <builddir>/conf/bblayers.inc"""
- self.logger.debug("Appending to: %s\n%s\n" % (self.testinc_bblayers_path, data))
- ftools.append_file(self.testinc_bblayers_path, data)
- def remove_bblayers_config(self, data):
- """Remove data from <builddir>/conf/bblayers.inc"""
- self.logger.debug("Removing from: %s\n%s\n" % (self.testinc_bblayers_path, data))
- ftools.remove_from_file(self.testinc_bblayers_path, data)
- def set_machine_config(self, data):
- """Write to <builddir>/conf/machine.inc"""
- self.logger.debug("Writing to: %s\n%s\n" % (self.machineinc_path, data))
- ftools.write_file(self.machineinc_path, data)
- # check does path exist
- def assertExists(self, expr, msg=None):
- if not os.path.exists(expr):
- msg = self._formatMessage(msg, "%s does not exist" % safe_repr(expr))
- raise self.failureException(msg)
- # check does path not exist
- def assertNotExists(self, expr, msg=None):
- if os.path.exists(expr):
- msg = self._formatMessage(msg, "%s exists when it should not" % safe_repr(expr))
- raise self.failureException(msg)
|