diff options
Diffstat (limited to 'poky/meta/lib/oeqa/core')
-rw-r--r-- | poky/meta/lib/oeqa/core/context.py | 48 | ||||
-rw-r--r-- | poky/meta/lib/oeqa/core/runner.py | 13 | ||||
-rw-r--r-- | poky/meta/lib/oeqa/core/target/qemu.py | 11 | ||||
-rw-r--r-- | poky/meta/lib/oeqa/core/target/ssh.py | 5 | ||||
-rw-r--r-- | poky/meta/lib/oeqa/core/utils/concurrencytest.py | 58 |
5 files changed, 86 insertions, 49 deletions
diff --git a/poky/meta/lib/oeqa/core/context.py b/poky/meta/lib/oeqa/core/context.py index 14fc6a54f4..4705d608ac 100644 --- a/poky/meta/lib/oeqa/core/context.py +++ b/poky/meta/lib/oeqa/core/context.py @@ -72,6 +72,9 @@ class OETestContext(object): modules_required, **kwargs) self.suites = self.loader.discover() + def prepareSuite(self, suites, processes): + return suites + def runTests(self, processes=None, skips=[]): self.runner = self.runnerClass(self, descriptions=False, verbosity=2) @@ -79,14 +82,9 @@ class OETestContext(object): self.skipTests(skips) self._run_start_time = time.time() - if processes: - from oeqa.core.utils.concurrencytest import ConcurrentTestSuite - - concurrent_suite = ConcurrentTestSuite(self.suites, processes) - result = self.runner.run(concurrent_suite) - else: + if not processes: self.runner.buffer = True - result = self.runner.run(self.suites) + result = self.runner.run(self.prepareSuite(self.suites, processes)) self._run_end_time = time.time() return result @@ -102,22 +100,27 @@ class OETestContextExecutor(object): name = 'core' help = 'core test component example' description = 'executes core test suite example' + datetime = time.strftime("%Y%m%d%H%M%S") default_cases = [os.path.join(os.path.abspath(os.path.dirname(__file__)), 'cases/example')] default_test_data = os.path.join(default_cases[0], 'data.json') default_tests = None + default_json_result_dir = None def register_commands(self, logger, subparsers): self.parser = subparsers.add_parser(self.name, help=self.help, description=self.description, group='components') - self.default_output_log = '%s-results-%s.log' % (self.name, - time.strftime("%Y%m%d%H%M%S")) + self.default_output_log = '%s-results-%s.log' % (self.name, self.datetime) self.parser.add_argument('--output-log', action='store', default=self.default_output_log, help="results output log, default: %s" % self.default_output_log) + self.parser.add_argument('--json-result-dir', action='store', + default=self.default_json_result_dir, + help="json result output dir, default: %s" % self.default_json_result_dir) + group = self.parser.add_mutually_exclusive_group() group.add_argument('--run-tests', action='store', nargs='+', default=self.default_tests, @@ -180,6 +183,22 @@ class OETestContextExecutor(object): self.module_paths = args.CASES_PATHS + def _get_json_result_dir(self, args): + return args.json_result_dir + + def _get_configuration(self): + td = self.tc_kwargs['init']['td'] + configuration = {'TEST_TYPE': self.name, + 'MACHINE': td.get("MACHINE"), + 'DISTRO': td.get("DISTRO"), + 'IMAGE_BASENAME': td.get("IMAGE_BASENAME"), + 'DATETIME': td.get("DATETIME")} + return configuration + + def _get_result_id(self, configuration): + return '%s_%s_%s_%s' % (configuration['TEST_TYPE'], configuration['IMAGE_BASENAME'], + configuration['MACHINE'], self.datetime) + def _pre_run(self): pass @@ -198,7 +217,16 @@ class OETestContextExecutor(object): else: self._pre_run() rc = self.tc.runTests(**self.tc_kwargs['run']) - rc.logDetails() + + json_result_dir = self._get_json_result_dir(args) + if json_result_dir: + configuration = self._get_configuration() + rc.logDetails(json_result_dir, + configuration, + self._get_result_id(configuration)) + else: + rc.logDetails() + rc.logSummary(self.name) output_link = os.path.join(os.path.dirname(args.output_log), diff --git a/poky/meta/lib/oeqa/core/runner.py b/poky/meta/lib/oeqa/core/runner.py index f656e1a9c5..1284295c34 100644 --- a/poky/meta/lib/oeqa/core/runner.py +++ b/poky/meta/lib/oeqa/core/runner.py @@ -319,10 +319,17 @@ class OETestResultJSONHelper(object): the_file.write(file_content) def dump_testresult_file(self, write_dir, configuration, result_id, test_result): - bb.utils.mkdirhier(write_dir) - lf = bb.utils.lockfile(os.path.join(write_dir, 'jsontestresult.lock')) + try: + import bb + has_bb = True + bb.utils.mkdirhier(write_dir) + lf = bb.utils.lockfile(os.path.join(write_dir, 'jsontestresult.lock')) + except ImportError: + has_bb = False + os.makedirs(write_dir, exist_ok=True) test_results = self._get_existing_testresults_if_available(write_dir) test_results[result_id] = {'configuration': configuration, 'result': test_result} json_testresults = json.dumps(test_results, sort_keys=True, indent=4) self._write_file(write_dir, self.testresult_filename, json_testresults) - bb.utils.unlockfile(lf) + if has_bb: + bb.utils.unlockfile(lf) diff --git a/poky/meta/lib/oeqa/core/target/qemu.py b/poky/meta/lib/oeqa/core/target/qemu.py index 081c627b01..295e8765e9 100644 --- a/poky/meta/lib/oeqa/core/target/qemu.py +++ b/poky/meta/lib/oeqa/core/target/qemu.py @@ -8,6 +8,7 @@ import os import sys import signal import time +from collections import defaultdict from .ssh import OESSHTarget from oeqa.utils.qemurunner import QemuRunner @@ -18,23 +19,29 @@ class OEQemuTarget(OESSHTarget): def __init__(self, logger, server_ip, timeout=300, user='root', port=None, machine='', rootfs='', kernel='', kvm=False, slirp=False, dump_dir='', dump_host_cmds='', display='', bootlog='', - tmpdir='', dir_image='', boottime=60, **kwargs): + tmpdir='', dir_image='', boottime=60, serial_ports=2, + boot_patterns = defaultdict(str), ovmf=False, **kwargs): super(OEQemuTarget, self).__init__(logger, None, server_ip, timeout, user, port) self.server_ip = server_ip + self.server_port = 0 self.machine = machine self.rootfs = rootfs self.kernel = kernel self.kvm = kvm + self.ovmf = ovmf self.use_slirp = slirp + self.boot_patterns = boot_patterns self.runner = QemuRunner(machine=machine, rootfs=rootfs, tmpdir=tmpdir, deploy_dir_image=dir_image, display=display, logfile=bootlog, boottime=boottime, use_kvm=kvm, use_slirp=slirp, dump_dir=dump_dir, - dump_host_cmds=dump_host_cmds, logger=logger) + dump_host_cmds=dump_host_cmds, logger=logger, + serial_ports=serial_ports, boot_patterns = boot_patterns, + use_ovmf=ovmf) def start(self, params=None, extra_bootparams=None, runqemuparams=''): if self.use_slirp and not self.server_ip: diff --git a/poky/meta/lib/oeqa/core/target/ssh.py b/poky/meta/lib/oeqa/core/target/ssh.py index 51032ef1a9..090b40a814 100644 --- a/poky/meta/lib/oeqa/core/target/ssh.py +++ b/poky/meta/lib/oeqa/core/target/ssh.py @@ -15,7 +15,7 @@ from . import OETarget class OESSHTarget(OETarget): def __init__(self, logger, ip, server_ip, timeout=300, user='root', - port=None, **kwargs): + port=None, server_port=0, **kwargs): if not logger: logger = logging.getLogger('target') logger.setLevel(logging.INFO) @@ -30,6 +30,7 @@ class OESSHTarget(OETarget): super(OESSHTarget, self).__init__(logger) self.ip = ip self.server_ip = server_ip + self.server_port = server_port self.timeout = timeout self.user = user ssh_options = [ @@ -246,7 +247,7 @@ def SSHCall(command, logger, timeout=None, **opts): "stdin": None, "shell": False, "bufsize": -1, - "preexec_fn": os.setsid, + "start_new_session": True, } options.update(opts) output = '' diff --git a/poky/meta/lib/oeqa/core/utils/concurrencytest.py b/poky/meta/lib/oeqa/core/utils/concurrencytest.py index 0f7b3dcc11..fac59f765a 100644 --- a/poky/meta/lib/oeqa/core/utils/concurrencytest.py +++ b/poky/meta/lib/oeqa/core/utils/concurrencytest.py @@ -146,6 +146,20 @@ def outSideTestaddError(self, offset, line): subunit._OutSideTest.addError = outSideTestaddError +# Like outSideTestaddError above, we need an equivalent for skips +# happening at the setUpClass() level, otherwise we will see "UNKNOWN" +# as a result for concurrent tests +# +def outSideTestaddSkip(self, offset, line): + """A 'skip:' directive has been read.""" + test_name = line[offset:-1].decode('utf8') + self.parser._current_test = subunit.RemotedTestCase(test_name) + self.parser.current_test_description = test_name + self.parser._state = self.parser._reading_skip_details + self.parser._reading_skip_details.set_simple() + self.parser.subunitLineReceived(line) + +subunit._OutSideTest.addSkip = outSideTestaddSkip # # A dummy structure to add to io.StringIO so that the .buffer object @@ -163,9 +177,10 @@ class dummybuf(object): # class ConcurrentTestSuite(unittest.TestSuite): - def __init__(self, suite, processes): + def __init__(self, suite, processes, setupfunc): super(ConcurrentTestSuite, self).__init__([suite]) self.processes = processes + self.setupfunc = setupfunc def run(self, result): tests, totaltests = fork_for_tests(self.processes, self) @@ -221,6 +236,15 @@ def removebuilddir(d): while delay and os.path.exists(d + "/bitbake.lock"): time.sleep(1) delay = delay - 1 + # Deleting these directories takes a lot of time, use autobuilder + # clobberdir if its available + clobberdir = os.path.expanduser("~/yocto-autobuilder-helper/janitor/clobberdir") + if os.path.exists(clobberdir): + try: + subprocess.check_call([clobberdir, d]) + return + except subprocess.CalledProcessError: + pass bb.utils.prunedir(d, ionice=True) def fork_for_tests(concurrency_num, suite): @@ -249,37 +273,7 @@ def fork_for_tests(concurrency_num, suite): stream = os.fdopen(c2pwrite, 'wb', 1) os.close(c2pread) - # Create a new separate BUILDDIR for each group of tests - if 'BUILDDIR' in os.environ: - builddir = os.environ['BUILDDIR'] - newbuilddir = builddir + "-st-" + str(ourpid) - newselftestdir = newbuilddir + "/meta-selftest" - - bb.utils.mkdirhier(newbuilddir) - oe.path.copytree(builddir + "/conf", newbuilddir + "/conf") - oe.path.copytree(builddir + "/cache", newbuilddir + "/cache") - oe.path.copytree(selftestdir, newselftestdir) - - for e in os.environ: - if builddir in os.environ[e]: - os.environ[e] = os.environ[e].replace(builddir, newbuilddir) - - subprocess.check_output("git init; git add *; git commit -a -m 'initial'", cwd=newselftestdir, shell=True) - - # Tried to used bitbake-layers add/remove but it requires recipe parsing and hence is too slow - subprocess.check_output("sed %s/conf/bblayers.conf -i -e 's#%s#%s#g'" % (newbuilddir, selftestdir, newselftestdir), cwd=newbuilddir, shell=True) - - os.chdir(newbuilddir) - - for t in process_suite: - if not hasattr(t, "tc"): - continue - cp = t.tc.config_paths - for p in cp: - if selftestdir in cp[p] and newselftestdir not in cp[p]: - cp[p] = cp[p].replace(selftestdir, newselftestdir) - if builddir in cp[p] and newbuilddir not in cp[p]: - cp[p] = cp[p].replace(builddir, newbuilddir) + (builddir, newbuilddir) = suite.setupfunc("-st-" + str(ourpid), selftestdir, process_suite) # Leave stderr and stdout open so we can see test noise # Close stdin so that the child goes away if it decides to |