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 6import optparse 7import pickle 8import re 9import subprocess 10 11import common 12from autotest_lib.client.cros.cellular import cellular 13from autotest_lib.client.cros.cellular import cellular_logging 14from autotest_lib.client.cros.cellular import labconfig_data 15 16log = cellular_logging.SetupCellularLogging('labconfig') 17 18 19class LabConfigError(Exception): 20 """Exception thrown on bad lab configuration""" 21 pass 22 23 24def 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 42class 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