Home | History | Annotate | Download | only in hosts
      1 # Copyright 2015 The Chromium OS Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 """This class defines the TestStationHost class."""
      6 
      7 import logging
      8 import os
      9 
     10 import common
     11 
     12 from autotest_lib.client.bin import local_host
     13 from autotest_lib.client.common_lib import error
     14 from autotest_lib.client.cros import constants as cros_constants
     15 from autotest_lib.server.hosts import base_classes
     16 from autotest_lib.server.hosts import moblab_host
     17 from autotest_lib.server.hosts import ssh_host
     18 
     19 
     20 # TODO(kevcheng): Update the creation method so it's not a research project
     21 # determining the class inheritance model (same for factory.create_host).
     22 def create_teststationhost(hostname, **kwargs):
     23     """Creates the TestStationHost object.
     24 
     25     @param hostname: Hostname of the test station.
     26     @param kwargs: Keyword args to pass to the testbed initialization.
     27 
     28     @return: A Test Station Host object.
     29     """
     30     classes = [TestStationHost]
     31     if hostname == 'localhost':
     32         classes.append(local_host.LocalHost)
     33     else:
     34         classes.append(ssh_host.SSHHost)
     35     host_class = type('new_teststationhost', tuple(classes), {})
     36     return host_class(hostname, **kwargs)
     37 
     38 
     39 class TestStationHost(base_classes.Host):
     40     """This class represents a linux box accessible via ssh."""
     41 
     42 
     43     def check_credentials(self, hostname):
     44         """Make sure teststation credentials work if we're doing ssh.
     45 
     46         @param hostname: Hostname of the machine.
     47         """
     48         if hostname != 'localhost':
     49             try:
     50                 self.run('true')
     51             except error.AutoservRunError:
     52                 # Some test stations may not have root access, try user adb.
     53                 logging.debug('Switching to user adb.')
     54                 self.user = 'adb'
     55 
     56 
     57     def _initialize(self, hostname='localhost', *args, **dargs):
     58         """Initialize a Test Station Host.
     59 
     60         This will create a Test Station Host. Hostname should always refer
     61         to the host machine connected to the devices under test.
     62 
     63         @param hostname: Hostname of the machine, default to localhost.
     64         """
     65         logging.debug('Initializing Test Station Host running on host: %s.',
     66                       hostname)
     67 
     68         # Do parent class initializations.
     69         super(TestStationHost, self)._initialize(hostname=hostname, *args,
     70                                                  **dargs)
     71 
     72         self.check_credentials(hostname)
     73 
     74         # We'll want to do certain things differently if we're on a moblab.
     75         self._is_host_moblab = None
     76         # Keep track of whether the host was closed since multiple AdbHost
     77         # might have an instance of this teststation.
     78         self._is_closed = False
     79 
     80 
     81     @property
     82     def is_moblab(self):
     83         """Check if the host running adb command is a Moblab.
     84 
     85         @return: True if the host running adb command is a Moblab, False
     86                  otherwise.
     87         """
     88         if self._is_host_moblab is None:
     89             try:
     90                 self.run('cat %s | grep -q moblab' % cros_constants.LSB_RELEASE)
     91                 self._is_host_moblab = True
     92             except (error.AutoservRunError, error.AutotestHostRunError):
     93                 self._is_host_moblab = False
     94         return self._is_host_moblab
     95 
     96 
     97     def get_tmp_dir(self, parent='/tmp'):
     98         """Return pathname of a temporary directory on the test station.
     99 
    100         If parent folder is supplied and the teststation is a moblab.  Then
    101         the parent will have the moblab tmp directory prepended to it.
    102 
    103         @param parent: The parent dir to create the temporary dir.
    104 
    105         @return: Path of the newly created temporary dir.
    106         """
    107         if self.is_moblab:
    108             parent = (moblab_host.MOBLAB_TMP_DIR if parent == '/tmp'
    109                       else os.path.join(moblab_host.MOBLAB_TMP_DIR,
    110                                         parent.lstrip('/')))
    111         return super(TestStationHost, self).get_tmp_dir(parent=parent)
    112 
    113 
    114     def run(self, cmd, *args, **dargs):
    115         """Run a command on the adb device.
    116 
    117         This will run the command on the test station.  This method only
    118         exists to modify the command supplied if we're running a fastboot
    119         command on a moblab, otherwise we leave the command untouched.
    120 
    121         @param cmd: The command line string.
    122 
    123         @returns A CMDResult object or None if the call timed out and
    124                  ignore_timeout is True.
    125         """
    126         # TODO (sbasi/kevcheng) - Make teststation_host check if running
    127         # on Chrome OS, rather than MobLab when prepending sudo to fastboot.
    128         if cmd.startswith('fastboot ') and self.is_moblab:
    129             cmd = 'sudo -n ' + cmd
    130         return super(TestStationHost, self).run(cmd, *args, **dargs)
    131 
    132 
    133     def close(self):
    134         if not self._is_closed:
    135             self._is_closed = True
    136             super(TestStationHost, self).close()
    137         else:
    138             logging.debug('Teststaion already closed.')
    139