Home | History | Annotate | Download | only in cellular
      1 # Copyright (c) 2011 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 
      6 import optparse
      7 import pickle
      8 import re
      9 import subprocess
     10 
     11 import common
     12 from autotest_lib.client.cros.cellular import cellular
     13 from autotest_lib.client.cros.cellular import cellular_logging
     14 from autotest_lib.client.cros.cellular import labconfig_data
     15 
     16 log = cellular_logging.SetupCellularLogging('labconfig')
     17 
     18 
     19 class LabConfigError(Exception):
     20     """Exception thrown on bad lab configuration"""
     21     pass
     22 
     23 
     24 def get_interface_ip(interface='eth0'):
     25     """Returns the IP address for an interface, or None if not found.
     26     @param interface: the interface to request IP address for.
     27     """
     28 
     29     # We'd like to use
     30     #  utils.system_output('ifconfig eth0 2>&1', retain_output=True)
     31     # but that gives us a dependency on the rest of autotest, which
     32     # means that running the unit test requires pythonpath manipulation
     33     stdout = subprocess.Popen(['ip', '-4', 'addr', 'show', 'dev', interface],
     34                               stdout=subprocess.PIPE).communicate()[0]
     35 
     36     match = re.search(r'inet ([0-9.]+)[/ ]', stdout)
     37     if not match:
     38         return None
     39     return match.group(1)
     40 
     41 
     42 class Configuration(object):
     43     """Configuration for a cellular test.
     44 
     45     This includes things like the address of the cell emulator device
     46     and details of the RF switching between the emulated basestation
     47     and the DUT."""
     48 
     49     def __init__(self, args):
     50         # For server tests, this constructor runs as part of the
     51         # server control file, on whatever machine the test was
     52         # started on.
     53         parser = optparse.OptionParser()
     54 
     55         # Record our args so we can serialize ourself.
     56         self.args = args
     57 
     58         self.ip = None
     59 
     60         parser.add_option('--cell', dest='cell', default=None,
     61                           help='Cellular test cell to use')
     62         parser.add_option(
     63             '--technology', dest='technology', default='all',
     64             help='Radio access technologies to use (e.g. "WCDMA")')
     65         (self.options, _) = parser.parse_args(args)
     66 
     67         self.cell = self._get_cell(self.options.cell)
     68 
     69     def _get_cell(self, name):
     70         """Extracts the named cell from labconfig_data.CELLS."""
     71         if not name:
     72             raise LabConfigError(
     73                 'Could not find --cell argument.  ' +
     74                 'To specify a cell, pass --args=--cell=foo to test_that')
     75 
     76         if name not in labconfig_data.CELLS:
     77             raise LabConfigError(
     78                 'Could not find cell %s, valid cells are %s' % (
     79                     name, labconfig_data.CELLS.keys()))
     80 
     81         return labconfig_data.CELLS[name]
     82 
     83     def _get_dut(self, machine=None):
     84         """Returns the DUT record for machine from cell["duts"]
     85         Args:
     86             machine:  name or IP of machine.  None: for "the current machine".
     87 
     88         Right now, we use the interface of eth0 to figure out which
     89         machine we're running on.  The important thing is that this
     90         matches the IP address in the cell duts configuration.  We'll
     91         have to come up with a better way if this proves brittle."""
     92 
     93         # TODO(byronk) : crosbug.com/235911:
     94         # autotest: Getting IP address from eth0 by name is brittle
     95         if self.ip and not machine:
     96             machine = self.ip
     97         ifconfig = ''
     98         if not machine:
     99             log.debug('self.ip is : %s ' % self.ip)
    100             # TODO(byronk): use sysfs to find network interface
    101             possible_interfaces = ['eth0', 'eth1', 'eth_test']
    102             log.debug('Looking for an up network interface in : %s' %
    103                       possible_interfaces)
    104             for interface in possible_interfaces:
    105                 machine = get_interface_ip(interface)
    106                 if machine:
    107                     log.debug('Got an IP address: %s Stopping the search.. ' %
    108                               machine)
    109                     self.ip = machine
    110                     break
    111             else:
    112                 ifconfig = subprocess.Popen(['ip', 'addr', 'show'],
    113                         stdout=subprocess.PIPE).communicate()[0]
    114         if not machine:
    115             raise LabConfigError(
    116                 'Could not determine which machine we are.\n'
    117                 '  Cell =  %s \n' % self.options.cell +
    118                 'Tried these interface names: %s \n' % possible_interfaces +
    119                 '`ip addr show` output:\n%s' % ifconfig
    120             )
    121 
    122         for dut in self.cell["duts"]:
    123             if machine == dut["address"] or machine == dut["name"]:
    124                 return dut
    125 
    126         raise LabConfigError(
    127             'This machine %s not matching: (%s,%s) in config. Cell = %s: %s' %
    128             (machine, dut['address'],
    129              dut['name'], self.options.cell, self.cell['duts']))
    130 
    131     def get_technologies(self, machine=None):
    132         """Gets technologies to use for machine; defaults to all available.
    133         @param machine: Machine to get technologies for.
    134         """
    135         technologies_list = self.options.technology.split(',')
    136 
    137         if 'all' in technologies_list:
    138             m = self._get_dut(machine)
    139             technologies_list = m["technologies"]
    140 
    141         enums = [getattr(cellular.Technology, t, None)
    142                  for t in technologies_list]
    143 
    144         if None in enums:
    145             raise LabConfigError(
    146                 'Could not understand a technology in %s' % technologies_list)
    147 
    148         return enums
    149 
    150     def get_rf_switch_port(self, machine=None):
    151         """Get the RF Switch Port for the specified machine.
    152         @param machine: machine to get rf switch port for
    153         """
    154         dut = self._get_dut(machine)
    155         print dut
    156         return dut['rf_switch_port']
    157 
    158     def get_pickle(self):
    159         """Get pickled object."""
    160         return pickle.dumps(self)
    161