WiFi test cleanups
- move config file handling into WiFiTest class
- move router autodetect to router classes
- auto-detect BSD router wireless and wired nics
Review URL: http://codereview.chromium.org/1512032
diff --git a/server/site_bsd_router.py b/server/site_bsd_router.py
index f7679a8..8ba9a44 100644
--- a/server/site_bsd_router.py
+++ b/server/site_bsd_router.py
@@ -4,6 +4,19 @@
import logging, re
+def isBSDRouter(router):
+ router_uname = router.run('uname').stdout
+ return re.search('BSD', router_uname)
+
+def find_ifnet(host, pattern):
+ list = host.run("ifconfig -l").stdout
+ for ifnet in list.split():
+ status = host.run("ifconfig %s" % ifnet).stdout
+ m = re.search(pattern, status)
+ if m:
+ return ifnet
+ return None
+
class NotImplemented(Exception):
def __init__(self, what):
self.what = what
@@ -26,10 +39,20 @@
def __init__(self, host, params, defssid):
self.router = host
- # TODO(sleffler) default to 1st available wireless nic
- self.phydev = params['phydev']
- # TODO(sleffler) default to 1st available wired nic
- self.wiredif = params['wiredev']
+ # default to 1st available wireless nic
+ if "phydev" not in params:
+ self.phydev = find_ifnet(host, ".*media:.IEEE.802.11.*")
+ if self.phydev is None:
+ raise Exception("No wireless NIC found")
+ else:
+ self.phydev = params['phydev']
+ # default to 1st available wired nic
+ if "wiredev" not in params:
+ self.wiredif = find_ifnet(host, ".*media:.Ethernet.*")
+ if self.wiredif is None:
+ raise Exception("No wired NIC found")
+ else:
+ self.wiredif = params['wiredev']
self.defssid = defssid;
self.wlanif = None
self.bridgeif = None
@@ -49,7 +72,6 @@
ignore_status=True)
self.router.run("killall hostapd >/dev/null 2>&1", ignore_status=True)
-
def create(self, params):
""" Create a wifi device of the specified type """
diff --git a/server/site_linux_router.py b/server/site_linux_router.py
index f3f5e38..4c00c6a 100644
--- a/server/site_linux_router.py
+++ b/server/site_linux_router.py
@@ -2,6 +2,12 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import re
+
+def isLinuxRouter(router):
+ router_uname = router.run('uname').stdout
+ return re.search('Linux', router_uname)
+
class LinuxRouter(object):
"""
Linux/mac80211-style WiFi Router support for WiFiTest class.
diff --git a/server/site_tests/network_WiFiMatFunc/control b/server/site_tests/network_WiFiMatFunc/control
index 1732c23..4294d41 100644
--- a/server/site_tests/network_WiFiMatFunc/control
+++ b/server/site_tests/network_WiFiMatFunc/control
@@ -8,7 +8,7 @@
TEST_CATEGORY = "Stress"
TEST_CLASS = "network"
TEST_TYPE = "Server"
-SYNC_COUNT = 2
+SYNC_COUNT = 1
DOC = """
WiFiMatFunc is a suite of 3-machine tests to validate basic WiFi functionality.
One client, one server, and one programmable WiFi AP/Router are required
@@ -27,26 +27,22 @@
import os
-fd = open(os.path.join(job.configdir, "wifi_testbed_config"))
-config = eval(fd.read())
-client = config['client']
-client['addr'] = machines[0] # NB: take client identity from command line
-client['host'] = hosts.create_host(client['addr'])
+config = site_wifitest.read_wifi_testbed_config(
+ os.path.join(job.configdir, "wifi_testbed_config"),
+ client_addr = machines[0]) # NB: take client identity from command line
+
server = config['server']
-if 'addr' in server:
- server['host'] = hosts.create_host(server['addr'])
router = config['router']
-router['host'] = hosts.create_host(router['addr'])
logging.info("Client %s, Server %s, AP %s" % \
- (client['addr'], getattr(server, 'addr', 'N/A'), router['addr']))
+ (machines[0], server.get('addr', 'N/A'), router['addr']))
-tagname = router['addr']
+tagname = config['tagname']
dir = os.path.join(job.serverdir, "site_tests", "network_WiFiMatFunc")
# TODO(sleffler) allow test list override from command line
tests = site_wifitest.read_tests(dir, '[0-9]*')
for t in tests:
- wt = site_wifitest.WiFiTest(t['name'], t['steps'], router, client, server)
+ wt = site_wifitest.WiFiTest(t['name'], t['steps'], config)
wt.run()
diff --git a/server/site_tests/network_WiFiSecMat/control b/server/site_tests/network_WiFiSecMat/control
index c8eea28..8e2a8f7 100644
--- a/server/site_tests/network_WiFiSecMat/control
+++ b/server/site_tests/network_WiFiSecMat/control
@@ -8,7 +8,7 @@
TEST_CATEGORY = "Stress"
TEST_CLASS = "network"
TEST_TYPE = "Server"
-SYNC_COUNT = 2
+SYNC_COUNT = 1
DOC = """
WiFiMatFunc is a suite of 3-machine tests to validate basic WiFi functionality.
One client, one server, and one programmable WiFi AP/Router are required
@@ -27,25 +27,22 @@
import os
-fd = open(os.path.join(job.configdir, "wifi_testbed_config"))
-config = eval(fd.read())
-client = config['client']
-client['addr'] = machines[0] # NB: take client identity from command line
-client['host'] = hosts.create_host(client['addr'])
+config = site_wifitest.read_wifi_testbed_config(
+ os.path.join(job.configdir, "wifi_testbed_config"),
+ client_addr = machines[0]) # NB: take client identity from command line
+
server = config['server']
-server['host'] = hosts.create_host(server['addr'])
router = config['router']
-router['host'] = hosts.create_host(router['addr'])
logging.info("Client %s, Server %s, AP %s" % \
- (client['addr'], server['addr'], router['addr']))
+ (machines[0], server.get('addr', 'N/A'), router['addr']))
-tagname = router['addr']
+tagname = config['tagname']
dir = os.path.join(job.serverdir, "site_tests", "network_WiFiSecMat")
# TODO(sleffler) allow test list override from command line
tests = site_wifitest.read_tests(dir, '[0-9]*')
for t in tests:
- wt = site_wifitest.WiFiTest(t['name'], t['steps'], router, client, server)
+ wt = site_wifitest.WiFiTest(t['name'], t['steps'], config)
wt.run()
diff --git a/server/site_wifitest.py b/server/site_wifitest.py
index 13672b1..0fb080a 100644
--- a/server/site_wifitest.py
+++ b/server/site_wifitest.py
@@ -4,7 +4,7 @@
import common, fnmatch, logging, os, re, string, threading, time
-from autotest_lib.server import autotest, subcommand
+from autotest_lib.server import autotest, hosts, subcommand
from autotest_lib.server import site_bsd_router
from autotest_lib.server import site_linux_router
@@ -63,46 +63,61 @@
wpa_supplicant directly.
"""
- def __init__(self, name, steps, router, client, server):
+ def __init__(self, name, steps, config):
self.name = name
self.steps = steps
- self.router = router['host']
+
+ router = config['router']
+ self.router = hosts.create_host(router['addr'])
+ # NB: truncate SSID to 32 characters
+ self.defssid = self.__get_defssid(router['addr'])[0:32]
+
+ if 'type' not in router:
+ # auto-detect router type
+ if site_linux_router.isLinuxRouter(self.router):
+ router['type'] = 'linux'
+ if site_bsd_router.isBSDRouter(self.router):
+ router['type'] = 'bsd'
+ else:
+ raise Exception('Unable to autodetect router type')
+ if router['type'] == 'linux':
+ self.wifi = site_linux_router.LinuxRouter(self.router, router,
+ self.defssid)
+ elif router['type'] == 'bsd':
+ self.wifi = site_bsd_router.BSDRouter(self.router, router,
+ self.defssid)
+ else:
+ raise Exception('Unsupported router')
+
#
# The client machine must be reachable from the control machine.
- # The address on the wifi network is retrieved after it each time
- # it associates to the router.
+ # The address on the wifi network is retrieved each time it
+ # associates to the router.
#
- self.client = client['host']
+ client = config['client']
+ self.client = hosts.create_host(client['addr'])
self.client_at = autotest.Autotest(self.client)
self.client_wifi_ip = None # client's IP address on wifi net
+ # interface name on client
+ self.client_wlanif = client.get('wlandev', "wlan0")
+
#
# The server machine may be multi-homed or only on the wifi
# network. When only on the wifi net we suppress server_*
# requests since we cannot initiate them from the control machine.
#
- self.server = getattr(server, 'host', None)
- if self.server is not None:
+ server = config['server']
+ # NB: server may not be reachable on the control network
+ if 'addr' in server:
+ self.server = hosts.create_host(server['addr'])
self.server_at = autotest.Autotest(self.server)
# if not specified assume the same as the control address
self.server_wifi_ip = getattr(server, 'wifi_addr', self.server.ip)
else:
- # NB: must be set if not reachable from control
+ self.server = None;
+ # NB: wifi address must be set if not reachable from control
self.server_wifi_ip = server['wifi_addr']
- # NB: truncate SSID to 32 characters
- self.defssid = self.__get_defssid()[0:32]
- # interface name on client
- self.wlanif = "wlan0"
-
- # auto-detect router type
- router_uname = self.router.run('uname').stdout
- if re.search('Linux', router_uname):
- self.wifi = site_linux_router.LinuxRouter(self.router, router, self.defssid)
- elif re.search('BSD', router_uname):
- self.wifi = site_bsd_router.BSDRouter(self.router, router, self.defssid)
- else:
- raise Exception('Unsupported router')
-
# potential bg thread for ping untilstop
self.ping_thread = None
@@ -113,13 +128,12 @@
self.wifi.destroy({})
- def __get_defssid(self):
+ def __get_defssid(self, ipaddr):
#
# Calculate ssid based on test name; this lets us track progress
# by watching beacon frames.
#
- return re.sub('[^a-zA-Z0-9_]', '_', \
- "%s_%s" % (self.name, self.router.ip))
+ return re.sub('[^a-zA-Z0-9_]', '_', "%s_%s" % (self.name, ipaddr))
def run(self):
@@ -250,7 +264,7 @@
print "%s: %s" % (self.name, result.stdout[0:-1])
# fetch IP address of wireless device
- self.client_wifi_ip = self.__get_ipaddr(self.client, self.wlanif)
+ self.client_wifi_ip = self.__get_ipaddr(self.client, self.client_wlanif)
logging.info("%s: client WiFi-IP is %s", self.name, self.client_wifi_ip)
@@ -303,7 +317,7 @@
def client_check_bintval(self, params):
""" Verify negotiated beacon interval """
- result = self.router.run("ifconfig %s" % self.wlanif)
+ result = self.router.run("ifconfig %s" % self.client_wlanif)
want = params[0]
m = re.search('bintval ([0-9]*)', result.stdout)
if m is None:
@@ -316,7 +330,7 @@
def client_check_dtimperiod(self, params):
""" Verify negotiated DTIM period """
- result = self.router.run("ifconfig %s" % self.wlanif)
+ result = self.router.run("ifconfig %s" % self.client_wlanif)
want = params[0]
m = re.search('dtimperiod ([0-9]*)', result.stdout)
if m is None:
@@ -329,7 +343,7 @@
def client_check_rifs(self, params):
""" Verify negotiated RIFS setting """
- result = self.router.run("ifconfig %s" % self.wlanif)
+ result = self.router.run("ifconfig %s" % self.client_wlanif)
m = re.search('[^-]rifs', result.stdout)
if m is None:
raise AssertionError
@@ -337,7 +351,7 @@
def client_check_shortgi(self, params):
""" Verify negotiated Short GI setting """
- result = self.router.run("ifconfig %s" % self.wlanif)
+ result = self.router.run("ifconfig %s" % self.client_wlanif)
m = re.search('[^-]shortgi', result.stdout)
if m is None:
raise AssertionError
@@ -634,3 +648,29 @@
# use filenames to sort
return sorted(tests, cmp=__byfile)
+
+def read_wifi_testbed_config(file, client_addr=None, server_addr=None,
+ router_addr=None):
+ # read configuration file
+ fd = open(file)
+ config = eval(fd.read())
+
+ # client must be reachable on the control network
+ client = config['client']
+ if client_addr is not None:
+ client['addr'] = client_addr;
+
+ # router must be reachable on the control network
+ router = config['router']
+ if router_addr is not None:
+ server['router'] = router_addr;
+
+ server = config['server']
+ if server_addr is not None:
+ server['addr'] = server_addr;
+ # TODO(sleffler) check for wifi_addr when no control address
+
+ # tag jobs w/ the router's address on the control network
+ config['tagname'] = router['addr']
+
+ return config