# Copyright (c) 2011 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 optparse
import pickle
import re
import subprocess
import common
from autotest_lib.client.cros.cellular import cellular
from autotest_lib.client.cros.cellular import cellular_logging
from autotest_lib.client.cros.cellular import labconfig_data
log = cellular_logging.SetupCellularLogging('labconfig')
class LabConfigError(Exception):
"""Exception thrown on bad lab configuration"""
pass
def get_interface_ip(interface='eth0'):
"""Returns the IP address for an interface, or None if not found.
@param interface: the interface to request IP address for.
"""
# We'd like to use
# utils.system_output('ifconfig eth0 2>&1', retain_output=True)
# but that gives us a dependency on the rest of autotest, which
# means that running the unit test requires pythonpath manipulation
stdout = subprocess.Popen(['ip', '-4', 'addr', 'show', 'dev', interface],
stdout=subprocess.PIPE).communicate()[0]
match = re.search(r'inet ([0-9.]+)[/ ]', stdout)
if not match:
return None
return match.group(1)
class Configuration(object):
"""Configuration for a cellular test.
This includes things like the address of the cell emulator device
and details of the RF switching between the emulated basestation
and the DUT."""
def __init__(self, args):
# For server tests, this constructor runs as part of the
# server control file, on whatever machine the test was
# started on.
parser = optparse.OptionParser()
# Record our args so we can serialize ourself.
self.args = args
self.ip = None
parser.add_option('--cell', dest='cell', default=None,
help='Cellular test cell to use')
parser.add_option(
'--technology', dest='technology', default='all',
help='Radio access technologies to use (e.g. "WCDMA")')
(self.options, _) = parser.parse_args(args)
self.cell = self._get_cell(self.options.cell)
def _get_cell(self, name):
"""Extracts the named cell from labconfig_data.CELLS."""
if not name:
raise LabConfigError(
'Could not find --cell argument. ' +
'To specify a cell, pass --args=--cell=foo to test_that')
if name not in labconfig_data.CELLS:
raise LabConfigError(
'Could not find cell %s, valid cells are %s' % (
name, labconfig_data.CELLS.keys()))
return labconfig_data.CELLS[name]
def _get_dut(self, machine=None):
"""Returns the DUT record for machine from cell["duts"]
Args:
machine: name or IP of machine. None: for "the current machine".
Right now, we use the interface of eth0 to figure out which
machine we're running on. The important thing is that this
matches the IP address in the cell duts configuration. We'll
have to come up with a better way if this proves brittle."""
# TODO(byronk) : crosbug.com/235911:
# autotest: Getting IP address from eth0 by name is brittle
if self.ip and not machine:
machine = self.ip
ifconfig = ''
if not machine:
log.debug('self.ip is : %s ' % self.ip)
# TODO(byronk): use sysfs to find network interface
possible_interfaces = ['eth0', 'eth1', 'eth_test']
log.debug('Looking for an up network interface in : %s' %
possible_interfaces)
for interface in possible_interfaces:
machine = get_interface_ip(interface)
if machine:
log.debug('Got an IP address: %s Stopping the search.. ' %
machine)
self.ip = machine
break
else:
ifconfig = subprocess.Popen(['ip', 'addr', 'show'],
stdout=subprocess.PIPE).communicate()[0]
if not machine:
raise LabConfigError(
'Could not determine which machine we are.\n'
' Cell = %s \n' % self.options.cell +
'Tried these interface names: %s \n' % possible_interfaces +
'`ip addr show` output:\n%s' % ifconfig
)
for dut in self.cell["duts"]:
if machine == dut["address"] or machine == dut["name"]:
return dut
raise LabConfigError(
'This machine %s not matching: (%s,%s) in config. Cell = %s: %s' %
(machine, dut['address'],
dut['name'], self.options.cell, self.cell['duts']))
def get_technologies(self, machine=None):
"""Gets technologies to use for machine; defaults to all available.
@param machine: Machine to get technologies for.
"""
technologies_list = self.options.technology.split(',')
if 'all' in technologies_list:
m = self._get_dut(machine)
technologies_list = m["technologies"]
enums = [getattr(cellular.Technology, t, None)
for t in technologies_list]
if None in enums:
raise LabConfigError(
'Could not understand a technology in %s' % technologies_list)
return enums
def get_rf_switch_port(self, machine=None):
"""Get the RF Switch Port for the specified machine.
@param machine: machine to get rf switch port for
"""
dut = self._get_dut(machine)
print dut
return dut['rf_switch_port']
def get_pickle(self):
"""Get pickled object."""
return pickle.dumps(self)