=== modified file 'lava_dispatcher/client/base.py'
@@ -42,17 +42,17 @@
involve executing multiple commands.
"""
- def __init__(self, connection, prompt_str, wait_for_rc=True):
+ def __init__(self, connection, prompt_str, prompt_str_includes_rc):
"""
:param connection: A pexpect.spawn-like object.
:param prompt_str: The shell prompt to wait for.
- :param wait_for_rc: Whether to wait for a rc=$? indication of the
- command's return value after prompt_str.
+ :param prompt_str_includes_rc: Whether prompt_str includes a pattern
+ matching the return code of the command.
"""
self._connection = connection
self._prompt_str = prompt_str
- self._wait_for_rc = wait_for_rc
+ self._prompt_str_includes_rc = prompt_str_includes_rc
self.match_id = None
self.match = None
@@ -90,28 +90,23 @@
self.match_id = None
self.match = None
self._connection.expect(self._prompt_str, timeout=timeout)
- if self._wait_for_rc:
- match_id = self._connection.expect(
- ['rc=(\d+\d?\d?)', pexpect.EOF, pexpect.TIMEOUT], timeout=2, lava_no_logging=1)
- if match_id == 0:
- rc = int(self._connection.match.groups()[0])
- if rc != 0 and not failok:
- raise OperationFailed(
- "executing %r failed with code %s" % (cmd, rc))
- else:
- rc = None
+ if self._prompt_str_includes_rc:
+ rc = int(self._connection.match.group(1))
+ if rc != 0 and not failok:
+ raise OperationFailed(
+ "executing %r failed with code %s" % (cmd, rc))
else:
rc = None
return rc
-
class NetworkCommandRunner(CommandRunner):
"""A CommandRunner with some networking utility methods."""
- def __init__(self, client, prompt_str, wait_for_rc=True):
+ def __init__(self, client, prompt_str, prompt_str_includes_rc):
CommandRunner.__init__(
- self, client.proc, prompt_str, wait_for_rc=wait_for_rc)
+ self, client.proc, prompt_str,
+ prompt_str_includes_rc=prompt_str_includes_rc)
self._client = client
def _check_network_up(self):
@@ -141,9 +136,13 @@
See `LavaClient.tester_session`.
"""
- def __init__(self, client, wait_for_rc=True):
+ def __init__(self, client):
CommandRunner.__init__(
- self, client.proc, client.config.tester_str, wait_for_rc)
+ self,
+ client.proc,
+ client.target_device.deployment_data['TESTER_PS1_PATTERN'],
+ prompt_str_includes_rc=client.target_device.deployment_data[
+ 'TESTER_PS1_INCLUDES_RC'])
def export_display(self):
self.run("su - linaro -c 'DISPLAY=:0 xhost local:'", failok=True)
@@ -158,7 +157,8 @@
def __init__(self, client):
super(AndroidTesterCommandRunner, self).__init__(
- client, client.config.tester_str, wait_for_rc=False)
+ client, client.target_device.deployment_data['TESTER_PS1_PATTERN'],
+ prompt_str_includes_rc=client.target_device.deployment_data['TESTER_PS1_INCLUDES_RC'])
self.dev_name = None
# adb cound be connected through network
@@ -274,7 +274,7 @@
"""A session that can be used to run commands booted into the test
image."""
try:
- self.in_test_shell()
+ self._in_test_shell()
except OperationFailed:
self.boot_linaro_image()
yield TesterCommandRunner(self)
@@ -288,9 +288,10 @@
manager.
"""
try:
- self.in_test_shell()
+ self._in_test_shell()
except OperationFailed:
self.boot_linaro_android_image()
+
session = AndroidTesterCommandRunner(self)
logging.info("adb connect over default network interface")
dev_ip = session.get_default_nic_ip()
@@ -327,15 +328,15 @@
"""
raise NotImplementedError(self.reliable_session)
- def in_test_shell(self, timeout=10):
+ def _in_test_shell(self):
"""
Check that we are in a shell on the test image
"""
if self.proc is None:
raise OperationFailed
self.proc.sendline("")
- match_id = self.proc.expect([self.config.tester_str, pexpect.TIMEOUT],
- timeout=timeout)
+ prompt = self.target_device.deployment_data['TESTER_PS1_PATTERN']
+ match_id = self.proc.expect([prompt, pexpect.TIMEOUT], timeout=10)
if match_id == 1:
raise OperationFailed
@@ -363,15 +364,9 @@
self._boot_linaro_image()
timeout = self.config.boot_linaro_timeout
- self.in_test_shell(timeout)
- # set PS1 to include return value of last command
- # Details: system PS1 is set in /etc/bash.bashrc and user PS1 is set in
- # /root/.bashrc, it is
- # "${debian_chroot:+($debian_chroot)}\u@\h:\w\$ "
- self.proc.sendline('export PS1="$PS1 [rc=$(echo \$?)]: "')
- self.proc.expect(self.config.tester_str, timeout=120)
-
- self.setup_proxy(self.config.tester_str)
+ TESTER_PS1_PATTERN = self.target_device.deployment_data['TESTER_PS1_PATTERN']
+ self.proc.expect(TESTER_PS1_PATTERN, timeout=timeout)
+ self.setup_proxy(TESTER_PS1_PATTERN)
logging.info("System is in test image now")
def get_www_scratch_dir(self):
@@ -391,9 +386,11 @@
def boot_linaro_android_image(self):
"""Reboot the system to the test android image."""
self._boot_linaro_android_image()
- self.in_test_shell(timeout=900)
- self.proc.sendline("export PS1=\"root@linaro: \"")
- self.proc.expect(self.config.tester_str, timeout=120)
+ match_id = self.proc.expect(
+ [self.target_device.deployment_data['TESTER_PS1'], pexpect.TIMEOUT],
+ timeout=900)
+ if match_id == 1:
+ raise OperationFailed("booting into android test image failed")
#TODO: set up proxy
# we are tcp'ish adb fans here...
@@ -425,7 +422,7 @@
timeout=self.config.disablesuspend_timeout)
def _enable_network(self):
- session = TesterCommandRunner(self, wait_for_rc=False)
+ session = AndroidTesterCommandRunner(self)
session.run("netcfg", timeout=20)
session.run("netcfg %s up" % self.config.default_network_interface, timeout=20)
session.run("netcfg %s dhcp" % self.config.default_network_interface, timeout=300)
@@ -434,14 +431,14 @@
def _restart_adb_after_netup(self):
logging.info("Restart adb after netup")
- session = TesterCommandRunner(self, wait_for_rc=False)
+ session = AndroidTesterCommandRunner(self)
session.run('setprop service.adb.tcp.port 5555')
session.run('stop adbd')
session.run('start adbd')
def _disable_adb_over_usb(self):
logging.info("Disabling adb over USB")
- session = TesterCommandRunner(self, wait_for_rc=False)
+ session = AndroidTesterCommandRunner(self)
session.run('echo 0>/sys/class/android_usb/android0/enable')
=== modified file 'lava_dispatcher/client/targetdevice.py'
@@ -18,13 +18,13 @@
# along
# with this program; if not, see <http://www.gnu.org/licenses>.
+import contextlib
import logging
import os
import shutil
import time
from lava_dispatcher.client.base import (
- CommandRunner,
CriticalError,
LavaClient,
)
@@ -37,10 +37,10 @@
class TargetBasedClient(LavaClient):
- '''This is a wrapper around the lava_dispatcher.device.target class that
+ """This is a wrapper around the lava_dispatcher.device.target class that
provides the additional functionality that's needed by lava-dispatcher
actions that depend on a LavaClient
- '''
+ """
def __init__(self, context, config):
super(TargetBasedClient, self).__init__(context, config)
@@ -68,7 +68,7 @@
self.proc = self.target_device.power_on()
def _boot_linaro_android_image(self):
- ''' booting android or ubuntu style images don't differ much'''
+ """Booting android or ubuntu style images don't differ much"""
logging.info('ensuring ADB port is ready')
while logging_system("sh -c 'netstat -an | grep 5555.*TIME_WAIT'") == 0:
=== modified file 'lava_dispatcher/config.py'
@@ -51,7 +51,7 @@
interrupt_boot_command = schema.StringOption()
interrupt_boot_prompt = schema.StringOption()
lmc_dev_arg = schema.StringOption()
- master_str = schema.StringOption()
+ master_str = schema.StringOption(default="root@master")
pre_connect_command = schema.StringOption()
qemu_drive_interface = schema.StringOption()
qemu_machine_type = schema.StringOption()
@@ -62,8 +62,6 @@
soft_boot_cmd = schema.StringOption(default="reboot")
sys_part_android = schema.IntOption()
sys_part_android_org = schema.IntOption()
- tester_hostname = schema.StringOption(default="linaro")
- tester_str = schema.StringOption()
val = schema.StringOption()
sdcard_mountpoint_path = schema.StringOption(default="/storage/sdcard0")
=== modified file 'lava_dispatcher/default-config/lava-dispatcher/device-defaults.conf'
@@ -79,13 +79,9 @@
data_part_android = 6
# Master image recognization string
-MASTER_STR = root@master
-
-# Test image hostname (default: linaro)
-# tester_hostname = linaro
-
-# Test image recognization string
-TESTER_STR = root@linaro
+# This is only used to detect that the master image has booted, it is
+# overwritten after that.
+# MASTER_STR = root@master
# The string to look for to interrupt the boot process
interrupt_boot_prompt = Hit any key to stop autoboot
=== modified file 'lava_dispatcher/device/fastmodel.py'
@@ -86,17 +86,10 @@
with image_partition_mounted(self._sd_image, self.SYS_PARTITION) as d:
#make sure PS1 is what we expect it to be
logging_system(
- 'sudo sh -c \'echo "PS1=%s: ">> %s/etc/mkshrc\'' %
- (self.config.tester_str, d))
+ 'sudo sh -c \'echo "PS1=%s">> %s/etc/mkshrc\'' %
+ self.ANDROID_TESTER_PS1, d)
self.deployment_data = Target.android_deployment_data
- def _customize_ubuntu(self):
- rootpart = self.config.root_part
- with image_partition_mounted(self._sd_image, rootpart) as d:
- logging_system('sudo echo %s > %s/etc/hostname'
- % (self.config.tester_hostname, d))
- self.deployment_data = Target.ubuntu_deployment_data
-
def _copy_axf(self, partno, fname):
with image_partition_mounted(self._sd_image, partno) as mntdir:
src = '%s/%s' % (mntdir, fname)
@@ -130,13 +123,13 @@
self._sd_image = '%s/sd.img' % odir
self._axf = '%s/img.axf' % odir
- self._customize_ubuntu()
+ self._customize_ubuntu(self._sd_image)
def deploy_linaro_prebuilt(self, image):
self._sd_image = download_image(image, self.context)
self._copy_axf(self.config.root_part, 'boot/img.axf')
- self._customize_ubuntu()
+ self._customize_ubuntu(self._sd_image)
@contextlib.contextmanager
def file_system(self, partition, directory):
@@ -190,14 +183,14 @@
self._sim_proc.close()
def _create_rtsm_ostream(self, ofile):
- '''the RTSM binary uses the windows code page(cp1252), but the
- dashboard and celery needs data with a utf-8 encoding'''
+ """the RTSM binary uses the windows code page(cp1252), but the
+ dashboard and celery needs data with a utf-8 encoding"""
return codecs.EncodedFile(ofile, 'cp1252', 'utf-8')
def _drain_sim_proc(self):
- '''pexpect will continue to get data for the simproc process. We need
+ """pexpect will continue to get data for the simproc process. We need
to keep this pipe drained so that it won't get full and then stop block
- the process from continuing to execute'''
+ the process from continuing to execute"""
f = cStringIO.StringIO()
self._sim_proc.logfile = self._create_rtsm_ostream(f)
=== modified file 'lava_dispatcher/device/master.py'
@@ -56,6 +56,9 @@
class MasterImageTarget(Target):
+ MASTER_PS1 = 'root@master [rc=$(echo \$?)]# '
+ MASTER_PS1_PATTERN = 'root@master \[rc=(\d+)\]# '
+
def __init__(self, context, config):
super(MasterImageTarget, self).__init__(context, config)
@@ -78,19 +81,17 @@
# we always leave master image devices powered on
pass
- def _customize_ubuntu(self, image):
- with image_partition_mounted(image, self.config.root_part) as d:
- logging_system('sudo echo %s > %s/etc/hostname'
- % (self.config.tester_hostname, d))
-
def deploy_linaro(self, hwpack, rfs):
+ self.boot_master_image()
+
image_file = generate_image(self, hwpack, rfs, self.scratch_dir)
boot_tgz, root_tgz = self._generate_tarballs(image_file)
self._deploy_tarballs(boot_tgz, root_tgz)
- self.deployment_data = Target.ubuntu_deployment_data
def deploy_android(self, boot, system, userdata):
+ self.boot_master_image()
+
sdir = self.scratch_dir
boot = download_image(boot, self.context, sdir, decompress=False)
system = download_image(system, self.context, sdir, decompress=False)
@@ -109,7 +110,7 @@
with self._as_master() as master:
self._format_testpartition(master, 'ext4')
- _deploy_linaro_android_boot(master, boot_url)
+ _deploy_linaro_android_boot(master, boot_url, self)
_deploy_linaro_android_system(master, system_url)
_deploy_linaro_android_data(master, data_url)
@@ -120,6 +121,8 @@
self.deployment_data = Target.android_deployment_data
def deploy_linaro_prebuilt(self, image):
+ self.boot_master_image()
+
if self.context.job_data.get('health_check', False):
(boot_tgz, root_tgz) = tarballcache.get_tarballs(
self.context, image, self.scratch_dir, self._generate_tarballs)
@@ -128,12 +131,8 @@
boot_tgz, root_tgz = self._generate_tarballs(image_file)
self._deploy_tarballs(boot_tgz, root_tgz)
- self.deployment_data = Target.ubuntu_deployment_data
def _deploy_tarballs(self, boot_tgz, root_tgz):
- logging.info("Booting master image")
- self.boot_master_image()
-
tmpdir = self.context.config.lava_image_tmpdir
url = self.context.config.lava_image_url
@@ -326,71 +325,64 @@
def _close_logging_spawn(self):
self.proc.close(True)
+ def _wait_for_master_boot(self):
+ self.proc.expect(self.config.image_boot_msg, timeout=300)
+ self.proc.expect(self.config.master_str, timeout=300)
+
def boot_master_image(self):
"""
reboot the system, and check that we are in a master shell
"""
- logging.info("Boot the system master image")
+ logging.info("Booting the system master image")
try:
self._soft_reboot()
- self.proc.expect(self.config.image_boot_msg, timeout=300)
- self._in_master_shell(300)
- except:
- logging.exception("in_master_shell failed")
- self._hard_reboot()
- self.proc.expect(self.config.image_boot_msg, timeout=300)
- self._in_master_shell(300)
- self.proc.sendline('export PS1="$PS1 [rc=$(echo \$?)]: "')
+ self._wait_for_master_boot()
+ except (OperationFailed, pexpect.TIMEOUT) as e:
+ logging.info("Soft reboot failed: %s" % e)
+ try:
+ self._hard_reboot()
+ self._wait_for_master_boot()
+ except (OperationFailed, pexpect.TIMEOUT) as e:
+ msg = "Hard reboot into master image failed: %s" % e
+ logging.critical(msg)
+ raise CriticalError(msg)
+ self.proc.sendline('export PS1="%s"' % self.MASTER_PS1)
self.proc.expect(
- self.config.master_str, timeout=120, lava_no_logging=1)
+ self.MASTER_PS1_PATTERN, timeout=120, lava_no_logging=1)
+
+ runner = MasterCommandRunner(self)
+ self.master_ip = runner.get_master_ip()
lava_proxy = self.context.config.lava_proxy
if lava_proxy:
logging.info("Setting up http proxy")
- self.proc.sendline("export http_proxy=%s" % lava_proxy)
- self.proc.expect(self.config.master_str, timeout=30)
+ runner.run("export http_proxy=%s" % lava_proxy, timeout=30)
logging.info("System is in master image now")
- def _in_master_shell(self, timeout=10):
+ @contextlib.contextmanager
+ def _as_master(self):
+ """A session that can be used to run commands in the master image."""
self.proc.sendline("")
match_id = self.proc.expect(
- [self.config.master_str, pexpect.TIMEOUT],
- timeout=timeout, lava_no_logging=1)
+ [self.MASTER_PS1_PATTERN, pexpect.TIMEOUT],
+ timeout=10, lava_no_logging=1)
if match_id == 1:
- raise OperationFailed
-
- if not self.master_ip:
- runner = MasterCommandRunner(self)
- self.master_ip = runner.get_master_ip()
-
- @contextlib.contextmanager
- def _as_master(self):
- """A session that can be used to run commands in the master image.
-
- Anything that uses this will have to be done differently for images
- that are not deployed via a master image (e.g. using a JTAG to blow
- the image onto the card or testing under QEMU).
- """
- try:
- self._in_master_shell()
- yield MasterCommandRunner(self)
- except OperationFailed:
self.boot_master_image()
- yield MasterCommandRunner(self)
+ yield MasterCommandRunner(self)
def _soft_reboot(self):
logging.info("Perform soft reboot the system")
self.master_ip = None
- # make sure in the shell (sometime the earlier command has not exit)
+ # Try to C-c the running process, if any.
self.proc.sendcontrol('c')
self.proc.sendline(self.config.soft_boot_cmd)
# Looking for reboot messages or if they are missing, the U-Boot
# message will also indicate the reboot is done.
match_id = self.proc.expect(
- ['Restarting system.', 'The system is going down for reboot NOW',
- 'Will now restart', 'U-Boot', pexpect.TIMEOUT], timeout=120)
- if match_id not in [0, 1, 2, 3]:
- raise Exception("Soft reboot failed")
+ [pexpect.TIMEOUT, 'Restarting system.', 'The system is going down for reboot NOW',
+ 'Will now restart', 'U-Boot'], timeout=120)
+ if match_id == 0:
+ raise OperationFailed("Soft reboot failed")
def _hard_reboot(self):
logging.info("Perform hard reset on the system")
@@ -400,7 +392,7 @@
else:
self.proc.send("~$")
self.proc.sendline("hardreset")
- self.proc.empty_buffer()
+ self.proc.empty_buffer()
def _enter_uboot(self):
if self.proc.expect(self.config.interrupt_boot_prompt) != 0:
@@ -444,7 +436,7 @@
def __init__(self, target):
super(MasterCommandRunner, self).__init__(
- target, target.config.master_str)
+ target, target.MASTER_PS1_PATTERN, prompt_str_includes_rc=True)
def get_master_ip(self):
logging.info("Waiting for network to come up")
@@ -479,7 +471,7 @@
return self.is_file_exist(path)
def is_file_exist(self, path):
- cmd = 'ls %s' % path
+ cmd = 'ls %s > /dev/null' % path
rc = self.run(cmd, failok=True)
if rc == 0:
return True
@@ -530,11 +522,11 @@
session.run('umount /mnt/boot')
-def _deploy_linaro_android_boot(session, boottbz2):
+def _deploy_linaro_android_boot(session, boottbz2, target):
logging.info("Deploying test boot filesystem")
session.run('mount /dev/disk/by-label/testboot /mnt/lava/boot')
session._client.target_extract(session, boottbz2, '/mnt/lava')
- _recreate_uInitrd(session)
+ _recreate_uInitrd(session, target)
def _update_uInitrd_partitions(session, rc_filename):
@@ -561,7 +553,7 @@
% (sys_part_org, sys_part_lava, rc_filename), failok=True)
-def _recreate_uInitrd(session):
+def _recreate_uInitrd(session, target):
logging.debug("Recreate uInitrd")
session.run('mkdir -p ~/tmp/')
@@ -578,7 +570,8 @@
_update_uInitrd_partitions(session, 'init.partitions.rc')
session.run(
- 'sed -i "/export PATH/a \ \ \ \ export PS1 root@linaro: " init.rc')
+ 'sed -i "/export PATH/a \ \ \ \ export PS1 \'%s\'" init.rc' %
+ target.ANDROID_TESTER_PS1)
session.run("cat init.rc")
session.run("cat init.partitions.rc", failok=True)
@@ -633,8 +626,8 @@
session.run('chown :2000 %s' % script_path)
session.run(
- 'sed -i "s/^PS1=.*$/PS1=\'root@linaro: \'/" '
- '/mnt/lava/system/etc/mkshrc',
+ ('sed -i "s/^PS1=.*$/PS1=\'%s\'/" '
+ '/mnt/lava/system/etc/mkshrc') % target.ANDROID_TESTER_PS1,
failok=True)
session.run('umount /mnt/lava/system')
=== modified file 'lava_dispatcher/device/qemu.py'
@@ -43,21 +43,14 @@
super(QEMUTarget, self).__init__(context, config)
self._sd_image = None
- def _customize_ubuntu(self):
- root_part = self.config.root_part
- with image_partition_mounted(self._sd_image, root_part) as mnt:
- with open('%s/etc/hostname' % mnt, 'w') as f:
- f.write('%s\n' % self.config.tester_hostname)
- self.deployment_data = Target.ubuntu_deployment_data
-
def deploy_linaro(self, hwpack=None, rootfs=None):
odir = self.scratch_dir
self._sd_image = generate_image(self, hwpack, rootfs, odir)
- self._customize_ubuntu()
+ self._customize_ubuntu(self._sd_image)
def deploy_linaro_prebuilt(self, image):
self._sd_image = download_image(image, self.context)
- self._customize_ubuntu()
+ self._customize_ubuntu(self._sd_image)
@contextlib.contextmanager
def file_system(self, partition, directory):
@@ -80,7 +73,7 @@
self.config.qemu_drive_interface,
self._sd_image)
logging.info('launching qemu with command %r' % qemu_cmd)
- proc = logging_spawn(qemu_cmd, logfile=self.sio, timeout=None)
+ proc = logging_spawn(qemu_cmd, logfile=self.sio, timeout=1200)
return proc
target_class = QEMUTarget
=== modified file 'lava_dispatcher/device/target.py'
@@ -22,6 +22,9 @@
import logging
import sys
+from lava_dispatcher.client.lmc_utils import (
+ image_partition_mounted,
+ )
import lava_dispatcher.utils as utils
from cStringIO import StringIO
@@ -38,11 +41,21 @@
target device
"""
+ ANDROID_TESTER_PS1 = "linaro-test-android# "
+
# The target deployment functions will point self.deployment_data to
# the appropriate dictionary below. Code such as actions can contribute
# to these structures with special handling logic
- android_deployment_data = {}
- ubuntu_deployment_data = {}
+ android_deployment_data = {
+ 'TESTER_PS1': ANDROID_TESTER_PS1,
+ 'TESTER_PS1_PATTERN': ANDROID_TESTER_PS1,
+ 'TESTER_PS1_INCLUDES_RC': False,
+ }
+ ubuntu_deployment_data = {
+ 'TESTER_PS1': "linaro-test [rc=$(echo \$?)]# ",
+ 'TESTER_PS1_PATTERN': "linaro-test \[rc=(\d+)\]# ",
+ 'TESTER_PS1_INCLUDES_RC': True,
+ }
def __init__(self, context, device_config):
self.context = context
@@ -101,10 +114,13 @@
try:
proc = self.power_on()
from lava_dispatcher.client.base import CommandRunner
- runner = CommandRunner(proc, self.config.tester_str)
+ runner = CommandRunner(
+ proc,
+ self.deployment_data['TESTER_PS1_PATTERN'],
+ self.deployment_data['TESTER_PS1_INCLUDES_RC'])
yield runner
finally:
- if proc:
+ if proc and runner:
logging.info('attempting a filesystem sync before power_off')
runner.run('sync', timeout=20)
self.power_off(proc)
@@ -112,6 +128,13 @@
def get_test_data_attachments(self):
return []
+ def _customize_ubuntu(self, image):
+ self.deployment_data = Target.ubuntu_deployment_data
+ root_part = self.config.root_part
+ with image_partition_mounted(image, root_part) as mnt:
+ with open('%s/root/.bashrc' % mnt, 'a') as f:
+ f.write('export PS1="%s"\n' % self.deployment_data['TESTER_PS1'])
+
class SerialIO(file):
def __init__(self, logfile):
=== modified file 'lava_dispatcher/lava_test_shell.py'
@@ -205,6 +205,6 @@
try:
testruns.append(_get_test_run(results_dir, d, hwctx, swctx))
except:
- logging.exception('error processing results for: %d' % d)
+ logging.exception('error processing results for: %s' % d)
return {'test_runs': testruns, 'format': 'Dashboard Bundle Format 1.3'}
=== modified file 'lava_dispatcher/tests/test_config.py'
@@ -65,9 +65,3 @@
expected = "192.168.200.200"
lava_server_ip = server_config.lava_server_ip
self.assertEqual(expected, lava_server_ip)
-
- def test_default_value_for_tester_hostname(self):
- create_config('devices/qemu01.conf', { 'device_type': 'qemu' })
- config = get_device_config("qemu01", tmp_config_dir)
- client = LavaClient(None, config)
- self.assertEqual('linaro', client.config.tester_hostname)