blob: 9db2bcc54551cff67219f255599a8154892c606e [file] [log] [blame]
# Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import common
import logging
import re
from autotest_lib.client.common_lib import error, global_config
from autotest_lib.server.cros.dynamic_suite import frontend_wrappers
from autotest_lib.server.hosts import cros_host
AUTOTEST_INSTALL_DIR = global_config.global_config.get_config_value(
'SCHEDULER', 'drone_installation_directory')
#'/usr/local/autotest'
SHADOW_CONFIG_PATH = '%s/shadow_config.ini' % AUTOTEST_INSTALL_DIR
ATEST_PATH = '%s/cli/atest' % AUTOTEST_INSTALL_DIR
SUBNET_DUT_SEARCH_RE = (
r'/?.*\((?P<ip>192.168.231.*)\) at '
'(?P<mac>[0-9a-fA-F][0-9a-fA-F]:){5}([0-9a-fA-F][0-9a-fA-F])')
MOBLAB_IMAGE_STORAGE = '/mnt/moblab/static'
class MoblabHost(cros_host.CrosHost):
"""Moblab specific host class."""
def _initialize(self, *args, **dargs):
super(MoblabHost, self)._initialize(*args, **dargs)
self.afe = frontend_wrappers.RetryingAFE(timeout_min=1,
server=self.hostname)
# Clear the Moblab Image Storage so that staging an image is properly
# tested.
self.run('rm -rf %s/*' % MOBLAB_IMAGE_STORAGE)
# Ensure the autotest install directory exists.
self.run('mkdir -p %s' % self.get_autodir())
@staticmethod
def check_host(host, timeout=10):
"""
Check if the given host is an moblab host.
@param host: An ssh host representing a device.
@param timeout: The timeout for the run command.
@return: True if the host device has adb.
@raises AutoservRunError: If the command failed.
@raises AutoservSSHTimeout: Ssh connection has timed out.
"""
try:
result = host.run('grep -q moblab /etc/lsb-release',
ignore_status=True, timeout=timeout)
except (error.AutoservRunError, error.AutoservSSHTimeout):
return False
return result.exit_status == 0
def get_autodir(self):
"""Return the directory to install autotest for client side tests."""
return '/usr/local/autodir'
def run_as_moblab(self, command, **kwargs):
"""Moblab commands should be ran as the moblab user not root.
@param command: Command to run as user moblab.
"""
command = "su - moblab -c '%s'" % command
return self.run(command, **kwargs)
def reboot(self, **dargs):
"""Reboot the Moblab Host and wait for its services to restart."""
super(MoblabHost, self).reboot(**dargs)
self.wait_afe_up()
def wait_afe_up(self, timeout_min=5):
"""Wait till the AFE is up and loaded.
Attempt to reach the Moblab's AFE and database through its RPC
interface.
@param timeout_min: Minutes to wait for the AFE to respond. Default is
5 minutes.
@raises TimeoutException if AFE does not respond within the timeout.
"""
# Use a new AFE object with a longer timeout to wait for the AFE to
# load.
afe = frontend_wrappers.RetryingAFE(timeout_min=timeout_min,
server=self.hostname)
# Verify the AFE can handle a simple request.
afe.get_hosts()
def find_and_add_duts(self):
"""Discover DUTs on the testing subnet and add them to the AFE.
Runs 'arp -a' on the Moblab host and parses the output to discover DUTs
and if they are not already in the AFE, adds them.
"""
existing_hosts = [host.hostname for host in self.afe.get_hosts()]
# Wake up devices on the subnet so they fill the arp table.
self.run('ping -b 192.168.231.255 -w 1', ignore_status=True)
arp_command = self.run('arp -a')
for line in arp_command.stdout.splitlines():
match = re.match(SUBNET_DUT_SEARCH_RE, line)
if match:
dut_hostname = match.group('ip')
if dut_hostname in existing_hosts:
break
result = self.run_as_moblab('%s host create %s' %
(ATEST_PATH, dut_hostname))
logging.debug('atest host create output for host %s:\n%s',
dut_hostname, result.stdout)