summaryrefslogtreecommitdiffstats
path: root/poky/meta/lib/oeqa/targetcontrol.py
diff options
context:
space:
mode:
Diffstat (limited to 'poky/meta/lib/oeqa/targetcontrol.py')
-rw-r--r--poky/meta/lib/oeqa/targetcontrol.py232
1 files changed, 232 insertions, 0 deletions
diff --git a/poky/meta/lib/oeqa/targetcontrol.py b/poky/meta/lib/oeqa/targetcontrol.py
new file mode 100644
index 000000000..59a9c35a0
--- /dev/null
+++ b/poky/meta/lib/oeqa/targetcontrol.py
@@ -0,0 +1,232 @@
+# Copyright (C) 2013 Intel Corporation
+#
+# Released under the MIT license (see COPYING.MIT)
+
+# This module is used by testimage.bbclass for setting up and controlling a target machine.
+
+import os
+import shutil
+import subprocess
+import bb
+import traceback
+import sys
+import logging
+from oeqa.utils.sshcontrol import SSHControl
+from oeqa.utils.qemurunner import QemuRunner
+from oeqa.utils.qemutinyrunner import QemuTinyRunner
+from oeqa.utils.dump import TargetDumper
+from oeqa.controllers.testtargetloader import TestTargetLoader
+from abc import ABCMeta, abstractmethod
+
+class BaseTarget(object, metaclass=ABCMeta):
+
+ supported_image_fstypes = []
+
+ def __init__(self, d, logger):
+ self.connection = None
+ self.ip = None
+ self.server_ip = None
+ self.datetime = d.getVar('DATETIME')
+ self.testdir = d.getVar("TEST_LOG_DIR")
+ self.pn = d.getVar("PN")
+ self.logger = logger
+
+ @abstractmethod
+ def deploy(self):
+
+ self.sshlog = os.path.join(self.testdir, "ssh_target_log.%s" % self.datetime)
+ sshloglink = os.path.join(self.testdir, "ssh_target_log")
+ if os.path.islink(sshloglink):
+ os.unlink(sshloglink)
+ os.symlink(self.sshlog, sshloglink)
+ self.logger.info("SSH log file: %s" % self.sshlog)
+
+ @abstractmethod
+ def start(self, params=None, ssh=True, extra_bootparams=None):
+ pass
+
+ @abstractmethod
+ def stop(self):
+ pass
+
+ @classmethod
+ def get_extra_files(self):
+ return None
+
+ @classmethod
+ def match_image_fstype(self, d, image_fstypes=None):
+ if not image_fstypes:
+ image_fstypes = d.getVar('IMAGE_FSTYPES').split(' ')
+ possible_image_fstypes = [fstype for fstype in self.supported_image_fstypes if fstype in image_fstypes]
+ if possible_image_fstypes:
+ return possible_image_fstypes[0]
+ else:
+ return None
+
+ def get_image_fstype(self, d):
+ image_fstype = self.match_image_fstype(d)
+ if image_fstype:
+ return image_fstype
+ else:
+ bb.fatal("IMAGE_FSTYPES should contain a Target Controller supported image fstype: %s " % ', '.join(map(str, self.supported_image_fstypes)))
+
+ def restart(self, params=None):
+ self.stop()
+ self.start(params)
+
+ def run(self, cmd, timeout=None):
+ return self.connection.run(cmd, timeout)
+
+ def copy_to(self, localpath, remotepath):
+ return self.connection.copy_to(localpath, remotepath)
+
+ def copy_from(self, remotepath, localpath):
+ return self.connection.copy_from(remotepath, localpath)
+
+
+
+class QemuTarget(BaseTarget):
+
+ supported_image_fstypes = ['ext3', 'ext4', 'cpio.gz', 'wic']
+
+ def __init__(self, d, logger, image_fstype=None):
+
+ import oe.types
+
+ super(QemuTarget, self).__init__(d, logger)
+
+ self.rootfs = ''
+ self.kernel = ''
+ self.image_fstype = ''
+
+ if d.getVar('FIND_ROOTFS') == '1':
+ self.image_fstype = image_fstype or self.get_image_fstype(d)
+ self.rootfs = os.path.join(d.getVar("DEPLOY_DIR_IMAGE"), d.getVar("IMAGE_LINK_NAME") + '.' + self.image_fstype)
+ self.kernel = os.path.join(d.getVar("DEPLOY_DIR_IMAGE"), d.getVar("KERNEL_IMAGETYPE", False) + '-' + d.getVar('MACHINE', False) + '.bin')
+ self.qemulog = os.path.join(self.testdir, "qemu_boot_log.%s" % self.datetime)
+ dump_target_cmds = d.getVar("testimage_dump_target")
+ dump_host_cmds = d.getVar("testimage_dump_host")
+ dump_dir = d.getVar("TESTIMAGE_DUMP_DIR")
+ qemu_use_kvm = d.getVar("QEMU_USE_KVM")
+ if qemu_use_kvm and \
+ (oe.types.boolean(qemu_use_kvm) and "x86" in d.getVar("MACHINE") or \
+ d.getVar("MACHINE") in qemu_use_kvm.split()):
+ use_kvm = True
+ else:
+ use_kvm = False
+
+ # Log QemuRunner log output to a file
+ import oe.path
+ bb.utils.mkdirhier(self.testdir)
+ self.qemurunnerlog = os.path.join(self.testdir, 'qemurunner_log.%s' % self.datetime)
+ loggerhandler = logging.FileHandler(self.qemurunnerlog)
+ loggerhandler.setFormatter(logging.Formatter("%(levelname)s: %(message)s"))
+ self.logger.addHandler(loggerhandler)
+ oe.path.symlink(os.path.basename(self.qemurunnerlog), os.path.join(self.testdir, 'qemurunner_log'), force=True)
+
+ if d.getVar("DISTRO") == "poky-tiny":
+ self.runner = QemuTinyRunner(machine=d.getVar("MACHINE"),
+ rootfs=self.rootfs,
+ tmpdir = d.getVar("TMPDIR"),
+ deploy_dir_image = d.getVar("DEPLOY_DIR_IMAGE"),
+ display = d.getVar("BB_ORIGENV", False).getVar("DISPLAY"),
+ logfile = self.qemulog,
+ kernel = self.kernel,
+ boottime = int(d.getVar("TEST_QEMUBOOT_TIMEOUT")),
+ logger = logger)
+ else:
+ self.runner = QemuRunner(machine=d.getVar("MACHINE"),
+ rootfs=self.rootfs,
+ tmpdir = d.getVar("TMPDIR"),
+ deploy_dir_image = d.getVar("DEPLOY_DIR_IMAGE"),
+ display = d.getVar("BB_ORIGENV", False).getVar("DISPLAY"),
+ logfile = self.qemulog,
+ boottime = int(d.getVar("TEST_QEMUBOOT_TIMEOUT")),
+ use_kvm = use_kvm,
+ dump_dir = dump_dir,
+ dump_host_cmds = d.getVar("testimage_dump_host"),
+ logger = logger)
+
+ self.target_dumper = TargetDumper(dump_target_cmds, dump_dir, self.runner)
+
+ def deploy(self):
+ bb.utils.mkdirhier(self.testdir)
+
+ qemuloglink = os.path.join(self.testdir, "qemu_boot_log")
+ if os.path.islink(qemuloglink):
+ os.unlink(qemuloglink)
+ os.symlink(self.qemulog, qemuloglink)
+
+ self.logger.info("rootfs file: %s" % self.rootfs)
+ self.logger.info("Qemu log file: %s" % self.qemulog)
+ super(QemuTarget, self).deploy()
+
+ def start(self, params=None, ssh=True, extra_bootparams='', runqemuparams='', launch_cmd='', discard_writes=True):
+ if launch_cmd:
+ start = self.runner.launch(get_ip=ssh, launch_cmd=launch_cmd)
+ else:
+ start = self.runner.start(params, get_ip=ssh, extra_bootparams=extra_bootparams, runqemuparams=runqemuparams, discard_writes=discard_writes)
+
+ if start:
+ if ssh:
+ self.ip = self.runner.ip
+ self.server_ip = self.runner.server_ip
+ self.connection = SSHControl(ip=self.ip, logfile=self.sshlog)
+ else:
+ self.stop()
+ if os.path.exists(self.qemulog):
+ with open(self.qemulog, 'r') as f:
+ bb.error("Qemu log output from %s:\n%s" % (self.qemulog, f.read()))
+ raise bb.build.FuncFailed("%s - FAILED to start qemu - check the task log and the boot log" % self.pn)
+
+ def check(self):
+ return self.runner.is_alive()
+
+ def stop(self):
+ self.runner.stop()
+ self.connection = None
+ self.ip = None
+ self.server_ip = None
+
+ def restart(self, params=None):
+ if self.runner.restart(params):
+ self.ip = self.runner.ip
+ self.server_ip = self.runner.server_ip
+ self.connection = SSHControl(ip=self.ip, logfile=self.sshlog)
+ else:
+ raise bb.build.FuncFailed("%s - FAILED to re-start qemu - check the task log and the boot log" % self.pn)
+
+ def run_serial(self, command, timeout=5):
+ return self.runner.run_serial(command, timeout=timeout)
+
+
+class SimpleRemoteTarget(BaseTarget):
+
+ def __init__(self, d):
+ super(SimpleRemoteTarget, self).__init__(d)
+ addr = d.getVar("TEST_TARGET_IP") or bb.fatal('Please set TEST_TARGET_IP with the IP address of the machine you want to run the tests on.')
+ self.ip = addr.split(":")[0]
+ try:
+ self.port = addr.split(":")[1]
+ except IndexError:
+ self.port = None
+ self.logger.info("Target IP: %s" % self.ip)
+ self.server_ip = d.getVar("TEST_SERVER_IP")
+ if not self.server_ip:
+ try:
+ self.server_ip = subprocess.check_output(['ip', 'route', 'get', self.ip ]).split("\n")[0].split()[-1]
+ except Exception as e:
+ bb.fatal("Failed to determine the host IP address (alternatively you can set TEST_SERVER_IP with the IP address of this machine): %s" % e)
+ self.logger.info("Server IP: %s" % self.server_ip)
+
+ def deploy(self):
+ super(SimpleRemoteTarget, self).deploy()
+
+ def start(self, params=None, ssh=True, extra_bootparams=None):
+ if ssh:
+ self.connection = SSHControl(self.ip, logfile=self.sshlog, port=self.port)
+
+ def stop(self):
+ self.connection = None
+ self.ip = None
+ self.server_ip = None
OpenPOWER on IntegriCloud