# Copyright (c) 2012 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 common
import datetime
import fnmatch
import logging
import os
import re
import string
import threading
import time
import traceback

from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import utils
from autotest_lib.server import autotest
from autotest_lib.server import hosts
from autotest_lib.server import site_bsd_router
from autotest_lib.server import site_cisco_router
from autotest_lib.server import site_eap_certs
from autotest_lib.server import site_host_attributes
from autotest_lib.server import site_host_route
from autotest_lib.server import site_linux_bridge_router
from autotest_lib.server import site_linux_router
from autotest_lib.server import site_linux_server
from autotest_lib.server import site_linux_system
from autotest_lib.server import site_linux_vm_router
from autotest_lib.server import subcommand
from autotest_lib.server import test


class NotImplemented(Exception):
    def __init__(self, what):
        self.what = what


    def __str__(self):
        return repr("Test method '%s' not implemented" % self.what)


class WiFiTest(object):
    """
    WiFi Test.

    Each test is specified as a dict.  There must be a "name" entry that
    gives the test name (a string) and a "steps" entry that has an ordered
    tuple of test steps, where each step is a tuple [func, {args}].

    Step funcs are one of:
      config                  configure the router/AP using the specified params
                              (ssid automatically supplied); params are give as
                              BSD ifconfig(8) parameters and translated to match
                              the target router/AP's cli syntax
      deconfig                de-configure/shut-off the router/AP
      connect                 connect client to AP using specified parameters
                              (ssid automatically supplied)
      disconnect              disconnect client from AP
      client_check_*          check the client's connection state to verify
                              a parameter was setup as expected; e.g.
                              client_check_bintval checks the beacon interval
                              set on the AP was adopted by the client
      client_monitor_start    start monitoring for wireless system events as
                              needed (e.g, kick off a process that listens)
      client_monitor_stop     stop monitoring for wireless system events
      client_check_event_*    check the client's event log for an event;
                              should always be preceded by client_monitor_start
      sleep                   pause on the autotest server for a time
      client_ping             ping the server on the client machine
      server_ping             ping the client on the server machine
      client_iperf            run iperf on the client to the server
      server_iperf            run iperf on the server to the client
      client_netperf          run netperf on the client to the server
      server_netperf          run netperf on the server to the client
      vpn_client_load_tunnel  load 'tun' device for VPN client
      vpn_client_kill         Kill the running VPN client.  Do nothing
                              if not running.
      vpn_client_config       launch a VPN client to connect with the
                              VPN server
      client_reboot           reboots the client and waits for it to come back.
                              The amount of time to wait can be specified by a
                              'timeout' parameter, in seconds.

    Steps that are done on the client or server machine are implemented in
    this class.  Steps that are done on the wifi router are implemented in
    a separate class that knows how to control the router.  There are presently
    two classes: BSDRouter for routers based on FreeBSD and LinuxRouter for
    those based on Linux/mac80211.  Additional router support can be added
    by adding a new class and auto-selecting it in __init__.

    The WiFiTest class could be generalized to handle clients other than
    ChromeOS; this would useful for systems that use Network Manager or
    wpa_supplicant directly.
    """

    _result_expect_failure = 1
    _result_expect_success = 2
    _result_dont_care = 3

    _capability_5ghz = "5ghz"

    def __init__(self, name, steps, requirements, config):
        self.name = name
        self.steps = steps
        self.test_requirements = (requirements + self.__get_step_requirements())
        self.perf_keyvals = {}

        self.cur_frequency = None
        self.cur_phymode   = None
        self.cur_security  = None
        self.vpn_kind      = None

        router = config['router']
        #
        # 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.
        #
        server = config['server']
        # NB: server may not be reachable on the control network

        if not router['addr'].startswith('cisco'):
            self.router = hosts.SSHHost(router['addr'],
                                        port=int(router.get('port',22)))
            # NB: truncate SSID to 32 characters
            self.defssid = self.__get_defssid(router['addr'])[0:32]
        else:
            # NB: router address isn't unique enough
            self.defssid = self.__get_defssid(server['addr'])[0:32]

        defaults = config.get('defaults', {})
        self.deftimeout = defaults.get('timeout', 30)
        self.defpingcount = defaults.get('pingcount', 10)
        self.defwaittime = defaults.get('netperf_wait_time', 3)
        self.defiperfport = str(defaults.get('iperf_port', 12866))
        self.defnetperfport = str(defaults.get('netperf_port', 12865))
        if 'type' not in router:
            # auto-detect router type
            if router['addr'].startswith('cisco:'):
                router['addr'] = router['addr'][6:]
                router['type'] = 'cisco'
            elif site_linux_router.isLinuxRouter(self.router):
                router['type'] = 'linux'
            elif site_bsd_router.isBSDRouter(self.router):
                router['type'] = 'bsd'
            else:
                 raise error.TestFail('Unable to autodetect router type')
        if router['type'] == 'linux':
            if config['router']['addr'] == config['client']['addr']:
                self.wifi = site_linux_vm_router.LinuxVMRouter(
                    self.router, router, self.defssid)
            else:
                self.wifi = site_linux_bridge_router.LinuxBridgeRouter(
                    self.router, router, self.defssid)
        elif router['type'] == 'bsd':
            self.wifi = site_bsd_router.BSDRouter(self.router, router,
                self.defssid)
        elif router['type'] == 'cisco':
            self.wifi = site_cisco_router.CiscoRouter(server['addr'], router,
                self.defssid, router['addr'])
            self.router = self.wifi.get_proxy()
        else:
            raise error.TestFail('Unsupported router')

        #
        # The client machine must be reachable from the control machine.
        # The address on the wifi network is retrieved each time it
        # associates to the router.
        #
        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
        self.client_wifi_device_path = None   # client's flimflam wifi path
        self.client_signal_info = {}
        self.client_installed_scripts = {}
        self.client_logfile = client.get("logfile", "/var/log/messages")
        self.ping_stats = {}

        if 'addr' in server:
            self.server = hosts.SSHHost(server['addr'],
                                        port=int(server.get('port', 22)))
            self.server_at = autotest.Autotest(self.server)
            # if not specified assume the same as the control address
            self.server_wifi_ip = server.get('wifi_addr', self.server.ip)
            self.__server_discover_commands(server)
        else:
            self.server = None
            # NB: wifi address must be set if not reachable from control
            self.server_wifi_ip = server['wifi_addr']

        # The 'hosting_server' is a machine which hosts network
        # services, such as OpenVPN or StrongSwan.
        self.hosting_server = site_linux_server.LinuxServer(self.server, server)

        # potential bg thread for ping untilstop
        self.ping_thread = None

        # potential bg thread for client network monitoring
        self.client_netdump_thread = None
        self.client_stats_thread = None
        self.__client_discover_commands(client)

        self.firewall_rules = []
        self.host_route_args = {}

        # interface name on client
        devs = self.__get_wlan_devs(self.client)
        if len(devs) == 0:
            raise error.TestFail('No wlan devices found on %s' % client['addr'])
        self.client_wlanif = client.get('wlandev', devs[0])
        self.client.wlan_mac = self.__get_interface_mac(self.client,
                                                        self.client_wlanif)

        # Synchronize time on all devices
        self.time_sync([])

        # Find all repeated steps and create iterators for them
        self.iterated_steps = {}
        step_names = [step[0] for step in steps]
        for step_name in list(set(step_names)):
            if step_names.count(step_name) > 1:
                self.iterated_steps[step_name] = 0

        self.run_options = config['run_options']

        self.command_hooks = {}

        if 'server_capture_all' in self.run_options:
            self.__add_hook('config', self.hosting_server.start_capture)
        if 'router_capture_all' in self.run_options:
            self.__add_hook('config', self.wifi.start_capture)
        if 'client_capture_all' in self.run_options:
            self.__add_hook('config', self.client_start_capture)
        if 'client_stats_all' in self.run_options:
            self.__add_hook('config', self.client_start_statistics)

        self.ethernet_mac_address = None
        string = self.__get_interface_mac(self.client, "eth0")
        if string:
          pieces = string.split(":")
          self.ethernet_mac_address = "".join(pieces)

        # NB: do last so code above doesn't need to cleanup on failure
        self.test_profile = {'name':'test'}
        # cleanup in case a previous failure left the profile around
        self.profile_pop(self.test_profile, ignore_status=True)
        self.profile_remove(self.test_profile, ignore_status=True)
        self.profile_create(self.test_profile)
        self.profile_push(self.test_profile)

        self.client_capabilities = self.__get_client_capabilities()


    def cleanup(self, params):
        """ Cleanup state: disconnect client and destroy ap """
        if 'no_cleanup_disconnect' not in self.run_options:
            self.disconnect({})
            self.wifi.destroy({})

        self.wifi.cleanup({})
        self.profile_pop(self.test_profile)
        self.profile_remove(self.test_profile)
        self.client_stop_capture({})
        self.client_stop_statistics({})
        self.firewall_cleanup({})
        self.host_route_cleanup({})
        self.wifi.stop_capture({})
        self.hosting_server.stop_capture({})


    def __must_be_installed(self, host, cmd):
        if not self.__is_installed(host, cmd):
            # TODO(sleffler): temporary debugging
            host.run("ls -a /usr{/local,}/bin/%s" % cmd, ignore_status=True)
            raise error.TestFail('Unable to find %s on %s' % (cmd, host.ip))
        return cmd


    def __client_discover_commands(self, client):
        self.client_cmd_netdump = client.get('cmd_netdump', 'tcpdump')
        self.client_cmd_ifconfig = client.get('cmd_ifconfig', 'ifconfig')
        self.client_cmd_iw = client.get('cmd_iw', 'iw')
        self.client_cmd_netperf = self.__must_be_installed(self.client,
                                        client.get('cmd_netperf_client',
                                            '/usr/local/bin/netperf'))
        self.client_cmd_netserv = self.__must_be_installed(self.client,
                                        client.get('cmd_netperf_server',
                                            '/usr/local/sbin/netserver'))
        self.client_cmd_iperf = self.__must_be_installed(self.client,
                                        client.get('cmd_iperf_client',
                                            '/usr/local/bin/iperf'))
        self.client_cmd_ip = self.__must_be_installed(self.client,
                                        client.get('cmd_ip',
                                            '/usr/local/sbin/ip'))
        self.client_cmd_iptables = '/sbin/iptables'
        self.client_cmd_flimflam_lib = client.get('flimflam_lib',
                                                  '/usr/local/lib/flimflam')
        self.client_cmd_ping = client.get('cmd_ping', 'ping')
        self.client_cmd_ping6 = client.get('cmd_ping6', 'ping6')

    def __get_wlan_devs(self, host):
        ret = []
        result = host.run("%s dev" % self.client_cmd_iw)
        current_if = None
        for line in result.stdout.splitlines():
            ifmatch = re.search("Interface (\S*)", line)
            if ifmatch is not None:
                current_if = ifmatch.group(1)
            elif ('type managed' in line or 'type IBSS' in line) and current_if:
                ret.append(current_if)
        logging.info("Found wireless interfaces %s" % str(ret))
        return ret


    def __get_interface_mac(self, host, ifname):
        result = host.run("%s link show %s" % (self.client_cmd_ip, ifname))
        macmatch = re.search("link/ether (\S*)", result.stdout)
        if macmatch is not None:
            return macmatch.group(1)
        return None


    def __server_discover_commands(self, server):
        self.server_cmd_netperf = self.__must_be_installed(self.server,
                                        server.get('cmd_netperf_client',
                                            '/usr/bin/netperf'))
        self.server_cmd_netserv = self.__must_be_installed(self.server,
                                        server.get('cmd_netperf_server',
                                            '/usr/bin/netserver'))
        self.server_cmd_iperf = self.__must_be_installed(self.server,
                                        server.get('cmd_iperf_client',
                                            '/usr/bin/iperf'))
        # /usr/bin/ping is preferred, as it is likely to be iputils
        if self.__is_installed(self.server, '/usr/bin/ping'):
            self.server_ping_cmd = '/usr/bin/ping'
        else:
            self.server_ping_cmd = 'ping'


    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, ipaddr))


    def __get_client_capabilities(self):
        caps = []

        # Find out if this device supports 5GHz
        system = site_linux_system.LinuxSystem(self.client, {}, '')
        if [freq for freq in system.phy_for_frequency.keys() if freq > 5000]:
            caps.append(WiFiTest._capability_5ghz)
        logging.info("Client system capabilities: %s" % repr(caps))
        return caps


    def __get_step_requirements(self):
        # This finds out what additional requirements are implicit based on
        # the steps outlined in the test description.
        reqs = []
        for step in self.steps:
            if len(step) < 2 or step[1].__class__ != dict:
                continue
            method = step[0]
            params = step[1]
            if method != 'config' or 'channel' not in params:
                continue
            if int(params['channel']) > 5000:
                reqs.append(WiFiTest._capability_5ghz)
                break
        logging.info("Step requirements: %s" % repr(reqs))
        return reqs


    def __add_hook(self, hook, fn):
        if hook not in self.command_hooks:
            self.command_hooks[hook] = []

        self.command_hooks[hook].append(fn)


    def __run_hooks(self, hook, params):
        if hook not in self.command_hooks:
            return

        for fn in self.command_hooks[hook]:
            if getattr(fn, 'im_class', None):
                hook_name = "%s.%s" % (fn.im_class.__name__, fn.__name__)
            else:
                hook_name = fn.__name__
            logging.info("%s: hook '%s' for method '%s' params %s", self.name,
                         hook_name, hook, params)
            fn(params)


    def run(self):
        """
        Run a WiFi test.  Each step is interpreted as a method either in this
        class or in one of the ancillary router or server classes and invoked
        with the supplied parameter dictionary.

        This routine bases its expectation of the method's result on the value
        (if any) of a prefix before the method name:

          - No prefix: The operation is expected to succeed.

          - '!': The operation is expected to fail; this is useful, for
            example, for testing parameter checking in flimflam.

          - '~': We don't care whether the operation succeeds or fails; this
            is especially useful during cleanup (e.g., deleting profiles).
        """
        for requirement in self.test_requirements:
            if not requirement in self.client_capabilities:
                logging.info("%s: SKIP: "
                             "client is missing required capability: %s",
                             self.name, requirement)
                return

        for step_number, s in enumerate(self.steps):
            method = s[0]
            if method[0] == '!':
                expect_result = WiFiTest._result_expect_failure
                method = method[1:]
            elif method[0] == '~':
                expect_result = WiFiTest._result_dont_care
                method = method[1:]
            else:
                expect_result = WiFiTest._result_expect_success
            if len(s) > 1:
                params = s[1]
            else:
                params = {}
            if len(s) > 2:
                failure_string = s[2]
            else:
                failure_string = None

            # What should perf data be prefixed with?
            if 'perf_prefix' in params:
                self.prefix = '%s_%s' % (method, params.pop('perf_prefix'))
            elif method in self.iterated_steps:
                self.prefix = '%s_%02d' % (method, self.iterated_steps[method])
                self.iterated_steps[method] += 1
            else:
                self.prefix = method

            self.__run_hooks(method, params)

            expectation = (" (expect failure)"
                           if expect_result is WiFiTest._result_expect_failure
                           else "")

            logging.info("-------------------------------------------")
            logging.info("%s: step %d '%s'%s params %s",
                         self.name, step_number+1, method, expectation, params)

            self.error_message = ''
            func = getattr(self, method, None)
            if func is None:
                func = getattr(self.wifi, method, None)
            if func is None:
                func = getattr(self.hosting_server, method, None)
            if func is not None:
                try:
                    func(params)
                    if expect_result is WiFiTest._result_expect_failure:
                        # TODO(wdg): This should be rewritten so that we don't
                        # swap the expectation value of a succeeding test,
                        # here.  It's non-intuitive.
                        expect_result = WiFiTest._result_expect_success
                        raise error.TestFail("Succeeded (but expected "
                                             "failure).")
                except Exception, e:
                    if expect_result is WiFiTest._result_dont_care:
                        logging.info("%s: Failed (but we don't care).",
                                     self.name)
                        continue
                    elif expect_result is WiFiTest._result_expect_failure:
                        if not failure_string:
                            logging.info("%s: Failed (but we expected that).",
                                         self.name)
                            continue

                        # If test did not explicitly specify an error message,
                        # perhaps we can scoop one out of the exception
                        if not self.error_message and hasattr(e, 'result_obj'):
                            self.error_message = (e.result_obj.stderr +
                                                  e.result_obj.stdout)
                        if re.search(failure_string, self.error_message):
                            logging.info("%s: Failed (but we expected that).",
                                         self.name)
                            continue

                        logging.error("Expected failure, but error string does "
                                      "not match what was expected. Got %s but "
                                      "expected %s.",
                                      self.error_message,
                                      failure_string)
                    logging.error("%s: Step '%s' failed: %s; abort test",
                        self.name, method, str(e))
                    logging.info("===========================================")
                    self.cleanup({})
                    traceback.print_exc()
                    raise e
            else:
                logging.error("%s: Step '%s' unknown; abort test",
                    self.name, method)
                logging.info("===========================================")
                self.cleanup({})
                break
        else:
            logging.info("===========================================")
            # If all steps ran successfully perform the normal cleanup steps
            self.cleanup({})


    def write_keyvals(self, job):
        job.write_perf_keyval(self.perf_keyvals)

    def write_perf(self, data):
        for key, value in data.iteritems():
            if value is not None:
                self.perf_keyvals['%s_%s' % (self.prefix, key)] = value


    def __get_interface_addresses(self, host, ifname, ip_version):
        addresses = []
        result = host.run("%s -%d addr show dev %s" %
                          (self.client_cmd_ip, ip_version, ifname))
        for line in result.stdout.splitlines():
            addr_match = re.search("inet\S* (\S*)", line)
            if addr_match is not None:
                addresses.append(addr_match.group(1))
        return addresses


    def __get_ipaddr(self, host, ifnet):
        addrs = self.__get_interface_addresses(host, ifnet, 4)
        if not addrs:
             raise error.TestFail("No inet address found")
        return addrs[0].split('/')[0]


    def __get_ip6addrs(self, host, ifnet):
        return self.__get_interface_addresses(host, ifnet, 6)


    def __get_local_file(self, pattern):
        """
        Pass a string pattern with a "%...d" in it, and get back a unique
        string with the number of times this pattern has been used.  This
        is useful for creating unique local file names to store data
        related to each test run.
        """
        if not getattr(self, 'local_file_counts', None):
            self.local_file_counts = {}
        file_count = self.local_file_counts.get(pattern, 0)
        self.local_file_counts[pattern] = file_count + 1
        return './debug/%s' % (pattern % file_count)


    def install_script(self, script_name, *support_scripts):
        if script_name in self.client_installed_scripts:
            return self.client_installed_scripts[script_name]
        script_client_dir = self.client.get_tmp_dir()
        script_client_file = os.path.join(script_client_dir, script_name)
        for copy_file in [script_name] + list(support_scripts):
            src_file = os.path.join(os.path.dirname(os.path.realpath(__file__)),
                                    copy_file)
            dest_file = os.path.join(script_client_dir,
                                     os.path.basename(src_file))
            self.client.send_file(src_file, dest_file, delete_dest=True)
        self.client_installed_scripts[script_name] = script_client_file
        return script_client_file

    def insert_file(self, host, filename, contents):
        """
        If config files are too big, the "host.run()" never returns.
        As a workaround, break the file up into lines and append the
        file piece by piece
        """
        host.run('rm -f %s >/dev/null 2>&1' % filename, ignore_status=True)
        content_lines = contents.splitlines()
        while content_lines:
            buflist = []
            buflen = 0
            while content_lines and buflen + len(content_lines[0]) < 200:
                line = content_lines.pop(0)
                buflen += len(line) + 1
                buflist.append(line)

            if not buflist:
                raise error.TestFail('Cert profile: line too long: %s' %
                                         content_lines[0])
            host.run('cat <<EOF >>%s\n%s\nEOF\n' %
                     (filename, '\n'.join(buflist)))

    def install_files(self, params):
        """ Install files on the client or router with the provided
        contents"""

        systemname = params.get('system', None)
        if systemname == 'router':
            system = self.router
        elif systemname == 'client':
            system = self.client
        elif systemname == 'server':
            system = self.server
        else:
            raise error.TestFail('install_files: Must specify router, '
                                 'server or client')

        for name,contents in params.get('files', {}).iteritems():
            self.insert_file(system, name, contents)


    def __clean_tpm(self):
        self.client.run("initctl restart chapsd")
        cryptohome_cmd = "/usr/sbin/cryptohome"
        self.client.run(cryptohome_cmd + " --action=tpm_take_ownership",
                ignore_status = True)
        self.client.run(cryptohome_cmd + " --action=tpm_wait_ownership",
                ignore_status = True)


    def __load_tpm_token(self, token_auth):
        chaps_dir = "/tmp/chaps/"
        self.client.run("rm -rf " + chaps_dir)
        self.client.run("mkdir " + chaps_dir)
        self.client.run("chown %s:%s %s" % (
                "chaps",
                "chronos-access",
                chaps_dir))
        self.client.run("chaps_client --load --path=%s --auth=\"%s\"" % (
                chaps_dir,
                token_auth))

    def install_tpm_object(self, params):
        if not "data" in params:
            raise error.TestFail("Need a data parameter to install a TPM"
                                 "certificate")
        if not "id" in params:
            raise error.TestFail("Need an object id to install a TPM"
                                 "certificate")
        if not "object_type" in params:
            raise error.TestFail("Need to know whether the requested TPM "
                                 "object is a private key or a certificate.")
        if params["object_type"] == "cert":
            conv_cmd = "openssl x509 -in %s -inform PEM -out %s -outform DER"
            load_cmd = "p11_replay --import --path=%s --type=cert --id=%s"
        elif params["object_type"] == "key":
            conv_cmd = "openssl rsa -in %s -inform PEM -out %s -outform DER"
            load_cmd = "p11_replay --import --path=%s --type=privkey --id=%s"
        else:
            raise error.TestFail("Invalid object type, expected either cert "
                                 "or key.")
        data = params["data"]
        object_id = params["id"]
        pem_path = self.client.run("mktemp").stdout.strip()
        der_path = self.client.run("mktemp").stdout.strip()
        self.install_files({ "system":"client", "files":{ pem_path:data } } )
        # Convert those keys into DER format
        self.client.run(conv_cmd % (pem_path, der_path))
        # load that stuff into the TPM
        self.client.run(load_cmd % (der_path, object_id))


    def initialize_tpm(self, params):
        """ Remove past state from TPM, and install a new token so that we can
        later install objects to the TPM.  Call this function before calling
        install_tpm_object. """
        self.__clean_tpm()
        token_auth = site_eap_certs.auth_pin
        self.__load_tpm_token(token_auth)



    def connect(self, params):
        """ Connect client to AP/router """

        script_client_file = self.install_script('site_wlan_connect.py',
                                                 'site_wlan_dbus_setup.py',
                                                 'site_wlan_wait_state.py')

        flags = []
        if params.get('debug', True):
            flags.append('--debug')
        if params.get('hidden', False):
            flags.append('--hidden')
        if 'mode' in params:
            flags.append('--mode=%s' % params['mode'])
        if params.get('nosave', False):
            flags.append('--nosave')

        result = self.client.run('python "%s" %s "%s" "%s" "%s" "%d" "%d"' %
            (script_client_file,
             ' '.join(flags),
             params.get('ssid', self.wifi.get_ssid()),
             params.get('security', ''),
             params.get('psk', ''),
             params.get('assoc_timeout', self.deftimeout),
             params.get('config_timeout', self.deftimeout))).stdout.rstrip()

        result_times = re.match('OK ([0-9\.]*) ([0-9\.]*) ([0-9\.]*) '
                                '([0-9\.]*) ([0-9]+) (\S+) (\w+) .*',
                                result)

        self.write_perf({'acquire_s'    : result_times.group(1),
                         'select_s'     : result_times.group(2),
                         'assoc_s'      : result_times.group(3),
                         'config_s'     : result_times.group(4),
                         'frequency'    : result_times.group(5)})
        for k in ('already_connected', 'clear_error', 'fast_fail',
                  'get_prop', 'in_progress', 'lost_dbus', 'multiple_attempts'):
            if re.search(k, result) is not None:
                self.write_perf({k:'true'})

        print "%s: %s" % (self.name, result)

        # stash connection state to emit for each test result
        self.cur_frequency = result_times.group(5)
        self.cur_phymode = result_times.group(6)
        self.cur_security = result_times.group(7)

        # fetch IP address of wireless device
        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)
        # TODO(sleffler) not right for non-mac80211 devices
        # TODO(sleffler) verify debugfs is mounted @ /sys/kernel/debug
        self.client_debugfs_path = "/sys/kernel/debug/ieee80211/%s/netdev:%s" \
            % ("phy0", self.client_wlanif)


    def disconnect(self, params):
        """ Disconnect previously connected client """

        self.client_ping_bg_stop({})

        script_client_file = self.install_script('site_wlan_disconnect.py',
                                                 'site_wlan_dbus_setup.py')
        result = self.client.run('python "%s" "%s" "%d"' %
            (script_client_file,
            params.get('ssid', self.defssid),
            params.get('wait_timeout', self.deftimeout))).stdout.rstrip()

        print "%s: %s" % (self.name, result)


    def profile(self, params):
        """ Display profile information -- for debugging. """

        print "\nSERVICES:"
        result = self.client.run('%s/test/list-services' %
                        (self.client_cmd_flimflam_lib),
                        ignore_status=True)
        print "%s: %s" % (self.name, result)

        print "\nENTRIES:"
        result = self.client.run('%s/test/list-entries' %
                        (self.client_cmd_flimflam_lib),
                        ignore_status=True)
        print "%s: %s" % (self.name, result)

    def client_check_profile_properties(self, params):
        """ Verify that profile/entries properties equal expected values. """

        args = ['--param %s:%s' % (var, val) for var, val in params.iteritems()]
        if self.ethernet_mac_address:
          args.append('--ethmac %s' % self.ethernet_mac_address)
        args.append('--command ClientCheckProfileProperties')

        script_client_file = self.install_script('site_wlan_profiles.py',
                                                 'site_wlan_dbus_setup.py')

        result = self.client.run('python "%s" %s' %
             (script_client_file, ' '.join(args))).stdout.rstrip()

        print "%s: %s" % (self.name, result)

    def client_profile_delete_entry(self, params):
        """ Verify that profile/entries properties equal expected values. """

        args = ['--param %s:%s' % (var, val) for var, val in params.iteritems()]
        if self.ethernet_mac_address:
          args.append('--ethmac %s' % self.ethernet_mac_address)
        args.append('--command ClientProfileDeleteEntry')

        script_client_file = self.install_script('site_wlan_profiles.py',
                                                 'site_wlan_dbus_setup.py')

        result = self.client.run('python "%s" %s' %
             (script_client_file, ' '.join(args))).stdout.rstrip()

        print "%s: %s" % (self.name, result)

    def __wait_service_start(self, params):
        """ Wait for service transitions on client. """

        script_client_file = self.install_script('site_wlan_wait_state.py',
                                                 'site_wlan_dbus_setup.py')
        args = []

        # Whether to print out all state transitions of watched services to
        # stderr
        if params.get('debug', True):
            args.append('--debug')
        # Time limit on the execution of a single step
        if 'step_timeout' in params:
            args.append('--step_timeout %d' % int(params['step_timeout']))
        # Time limit to wait for a service to appear in the service list
        if 'service_timeout' in params:
            args.append('--svc_timeout %d' % int(params['service_timeout']))
        # Time limit on the execution of the entire series of steps
        args.append('--run_timeout=%d' % int(params.get('run_timeout', 10)))

        states = params.get('states', [])
        if not states:
            raise error.TestFail('No states given to wait for')

        for service, state in states:
            args.append('"%s=%s"' % (service or self.wifi.get_ssid(), state))

        self.wait_service_states = states
        return 'python "%s" %s' % (script_client_file, ' '.join(args))


    def __wait_service_complete(self, params, result):
        print "%s: %s" % (self.name, result)

        states = self.wait_service_states
        cstates = []
        counts = {}
        for service, state in states:
            cstate = state.strip('+-').replace(':', '_')
            cstates.append(cstate)
            if state in counts:
                counts[cstate] = 1
            else:
                counts[cstate] = 0

        for cstate, intr in zip(cstates, result.stdout.split(' ')):
            if intr.startswith('ERR_'):
                raise error.TestFail('Wait for step %s failed with error %s' %
                                     (cstate, intr))
            if counts[cstate]:
                index = '%s%d' % (cstate, counts[cstate] - 1)
                counts[cstate] += 1
            else:
                index = cstate

            self.write_perf({ index:float(intr) })
            print "  %s: %s" % (state, intr)

            max = 'max_' + cstate
            if max in params and float(intr) > float(params[max]):
                raise error.TestFail('Too long to reach %s state: %f > %f' %
                                     (cstate, float(intr), float(params[max])))


    def wait_service(self, params):
        result = self.client.run(self.__wait_service_start(params))
        self.__wait_service_complete(params, result)


    def wait_service_suspend_bg(self, params):
        params['after_command'] = self.__wait_service_start(params)
        self.client_suspend_bg(params)


    def wait_service_suspend_end(self, params):
        self.client_suspend_end(params)
        self.__wait_service_complete(params, self.client_suspend_thread.result)


    def client_powersave_on(self, params):
        """ Enable power save operation """
        self.client.run("iw dev %s set power_save on" % self.client_wlanif)


    def client_powersave_off(self, params):
        """ Disable power save operation """
        self.client.run("iw dev %s set power_save off" % self.client_wlanif)


    def client_check_powersave(self, params):
        """ Check status of power save mode """
        result = self.client.run("iw dev %s get power_save" %
                                 self.client_wlanif)
        output = result.stdout.rstrip()       # NB: chop \n
        # output should be either "Power save: on" or "Power save: off"
        find_re = re.compile('([^:]+):\s+(\w+)')
        find_results = find_re.match(output)
        want = params[0]
        if not find_results:
            raise error.TestFail("wanted %s but not found" % want)
        got = find_results.group(2)
        if got != want:
            raise error.TestFail("client_check_powersave: wanted %s got %s" %
                                 (want, got))


    def __client_check(self, param, want):
        """ Verify negotiated station mode parameter """
        result = self.client.run("cat '%s/%s'" %
            (self.client_debugfs_path, param))
        got = result.stdout.rstrip()       # NB: chop \n
        if got != want:
            raise error.TestFail("client_check_%s: wanted %s got %s" %
                                 (param, want, got))


    def __client_check_iw_link(self, param, want):
        """ Verify negotiated station mode parameter """
        result = self.client.run("%s dev %s link" %
                                 (self.client_cmd_iw, self.client_wlanif))
        find_re = re.compile("\s*%s:\s*(.*\S)\s*$" % param)
        find_results = filter(bool, map(find_re.match,
                                        result.stdout.splitlines()))
        if not find_results:
            raise error.TestFail("wanted %s but %s not found" % (want, param))
        got = find_results[0].group(1)
        if not re.match(want, got):
            raise error.TestFail("wanted %s got %s" % (want, got))

    def client_check_bintval(self, params):
        """ Verify negotiated beacon interval """
        self.__client_check_iw_link("beacon int", params[0])


    def client_check_dtimperiod(self, params):
        """ Verify negotiated DTIM period """
        self.__client_check_iw_link("dtim period", params[0])


    def client_check_rifs(self, params):
        """ Verify negotiated RIFS setting """
        self.__client_check("rifs", params[0])


    def client_check_shortgi20(self, params):
        """ Verify negotiated Short GI setting """
        self.__client_check("sgi20", params[0])


    def client_check_shortgi40(self, params):
        """ Verify negotiated Short GI setting """
        self.__client_check("sgi40", params[0])


    def client_check_shortslot(self, params):
        """ Verify negotiated Short Slot setting """
        self.__client_check("short_slot", params[0])


    def client_check_protection(self, params):
        """ Verify negotiated CTS protection setting """
        self.__client_check("cts_prot", params[0])


    def client_monitor_start(self, params):
        """ Start monitoring system events """
        raise NotImplemented("client_monitor_start")


    def client_monitor_stop(self, params):
        """ Stop monitoring system events """
        raise NotImplemented("client_monitor_stop")


    def client_check_event_mic(self, params):
        """ Check for MIC error event """
        raise NotImplemented("client_check_event_mic")


    def client_check_event_countermeasures(self, params):
        """ Check for WPA CounterMeasures event """
        raise NotImplemented("client_check_event_countermeasures")


    def client_check_frequency(self, params):
        """ Verify current frequency """
        self.__client_check_iw_link("freq", params[0])


    def client_check_service_properties(self, params):
        """ Verify that service properties attained their expected values. """
        service = params.pop("service", None)
        if self.ethernet_mac_address and service == "ethernet":
          service = "ethernet_%s" % self.ethernet_mac_address
        states = [(service, "%s:%s" % (var, val))
                  for var, val in params.iteritems()]
        self.wait_service({ "run_timeout": 0, "states": states})

    def sleep(self, params):
        time.sleep(float(params['time']))


    def __unreachable(self, method):
        logging.info("%s: SKIP step %s; server is unreachable",
            self.name, method)


    def __ping_args(self, params):
        args = ""
        if 'count' in params:
            args += " -c %s" % params['count']
        if 'size' in params:
            args += " -s %s" % params['size']
        if 'bcast' in params:
            args += " -b"
        if 'flood' in params:
            args += " -f"
        if 'interval' in params:
            args += " -i %s" % params['interval']
        if 'interface' in params:
            args += " -I %s" % params['interface']
        if 'qos' in params:
            ac = string.lower(params['qos'])
            if ac == 'be':
                args += " -Q 0x04"
            elif ac == 'bk':
                args += " -Q 0x02"
            elif ac == 'vi':
                args += " -Q 0x08"
            elif ac == 'vo':
                args += " -Q 0x10"
            else:
                args += " -Q %s" % ac
        return args


    def __get_pingstats(self, str):
        stats = {
            'frequency' : self.cur_frequency,
            'phymode'   : self.cur_phymode,
            'security'  : self.cur_security,
        }
        for k in ('xmit', 'recv', 'loss', 'min', 'avg', 'max', 'dev'):
            stats[k] = '???'
        m = re.search('([0-9]*) packets transmitted,[ ]*([0-9]*)[ ]'
            '(packets |)received, ([0-9]*)', str)
        if m is not None:
            stats['xmit'] = m.group(1)
            stats['recv'] = m.group(2)
            stats['loss'] = m.group(4)
        m = re.search('(round-trip|rtt) min[^=]*= '
                      '([0-9.]*)/([0-9.]*)/([0-9.]*)/([0-9.]*)', str)
        if m is not None:
            stats['min'] = m.group(2)
            stats['avg'] = m.group(3)
            stats['max'] = m.group(4)
            stats['dev'] = m.group(5)
        return stats


    def __print_pingstats(self, label, stats):
        logging.info("%s: %s%s/%s, %s%% loss, rtt %s/%s/%s",
            self.name, label, stats['xmit'], stats['recv'], stats['loss'],
             stats['min'], stats['avg'], stats['max'])


    def iw_event_scan(self, params):
        """ Obtain the event scan output and store it

        Params:
            duration: Indicates time in seconds.  If no duration
                      provided, iw even runs until iw_even_scan_stop
                      is called.
        """
        duration = params.get('duration', 0)
        cmd = '%s event -f' % self.client_cmd_iw
        self.iw_event_thread = HelperThread(self.client, cmd)
        self.iw_event_thread.start()

        if duration:
            time.sleep(float(duration))
            self.iw_event_thread_stop({})


    def iw_event_scan_stop(self, params):
        """ Stops the iw event thread """
        self.client.run('pkill %s' % os.path.basename(self.client_cmd_iw))
        self.iw_event_thread.join()
        self.iw_event_thread_output = self.iw_event_thread.result.stdout
        logging.debug('Output of iw scan is %s' % self.iw_event_thread_output)


    def search_iw_events(self, params):
        """ Searches through the last run iw event scan for strings

        Params:
            match: A list of strings to match.

        Raises:
            error.TestFail if any strings in match are not found in
                iw event output.
        """
        match_list = params.get('match', [])
        if not hasattr(self, 'iw_event_thread_output'):
            return

        for match in match_list:
            if match not in self.iw_event_thread_output:
                raise error.TestFail("Expecting %s in iw event output but "
                               "it wasn't present.")


    def client_ping(self, params):
        """ Ping the server from the client """
        if 'ping_ip' in params:
            ping_ip = params['ping_ip']
        else:
            if 'dest' in params:
                ping_dest = params['dest']
            else:
                if self.wifi.has_local_server():
                    ping_dest = 'router'
                else:
                    ping_dest = 'server'

            if ping_dest == 'server':
                ping_ip = self.server_wifi_ip
            elif ping_dest == 'router':
                ping_ip = self.wifi.get_wifi_ip(params.get('ap', 0))
            else:
                raise error.TestFail('Unknown ping destination "%s"' %
                                     ping_dest)
        count = params.get('count', self.defpingcount)
        # set timeout for 3s / ping packet
        result = self.client.run("%s %s %s" % (
            self.client_cmd_ping, self.__ping_args(params), ping_ip),
                                 timeout=3*int(count))

        stats = self.__get_pingstats(result.stdout)
        if "save_stats" in params:
            self.ping_stats[params["save_stats"]] = stats
        self.write_perf(stats)
        self.__print_pingstats("client_ping ", stats)


    def client_ping_bg(self, params):
        """ Ping the server from the client """
        ping_ip = params.get('ping_ip', self.server_wifi_ip)
        cmd = "%s %s %s" % \
            (self.client_cmd_ping, self.__ping_args(params), ping_ip)
        self.ping_thread = HelperThread(self.client, cmd)
        self.ping_thread.start()


    def client_ping_bg_stop(self, params):
        if self.ping_thread is None:
            logging.info("Tried to stop a bg ping, but none was started")
            return
        # Sending SIGINT gives us stats at the end, how nice.
        self.client.run("pkill -INT %s"
                % os.path.basename(self.client_cmd_ping))
        self.ping_thread.join()
        if "save_stats" in params:
            stats = self.__get_pingstats(self.ping_thread.result.stdout)
            self.ping_stats[params["save_stats"]] = stats
        self.ping_thread = None


    def assert_ping_similarity(self, params):
        """ Assert that two specified sets of ping parameters are 'similar' """
        if "stats0" not in params or "stats1" not in params:
            raise error.TestFail("Missing ping statistics keys")
        stats0 = self.ping_stats[params["stats0"]]
        stats1 = self.ping_stats[params["stats1"]]
        if "dev" not in stats0 or "dev" not in stats1:
            raise error.TestFail("Missing standard dev from ping stats")
        if "min" not in stats0 or "min" not in stats1:
            raise error.TestFail("Missing max rtt from ping stats")
        if "avg" not in stats0 or "avg" not in stats1:
            raise error.TestFail("Missing avg rtt from ping stats")
        if "max" not in stats0 or "max" not in stats1:
            raise error.TestFail("Missing max rtt from ping stats")
        avg0 = float(stats0["avg"])
        max0 = float(stats0["max"])
        avg1 = float(stats1["avg"])
        max1 = float(stats1["max"])
        # This check is meant to assert that ping latency remains 'similar'
        # during WiFi background scans.  APs typically send beacons every 100ms,
        # (the period is configurable) so bgscan algorithms like to sit in a
        # channel for 100ms to see if they can catch a beacon.
        #
        # Assert that the maximum latency is under 200 ms + whatever the
        # average was for the other sample.  This allows us to go off chanel,
        # but forces us to serve some real traffic when we go back on.
        # We'll do this check symmetrically because we don't actually know
        # which is the control distribution and which is the potentially dirty
        # distribution.
        if max0 > 200 + avg1 or max1 > 200 + avg0:
            logging.error(
                    "Ping0 min/avg/max/dev = {0}/{1}/{2}/{3}".format(
                        stats0["min"],
                        stats0["avg"],
                        stats0["max"],
                        stats0["dev"],
                        )
                    )
            logging.error(
                    "Ping1 min/avg/max/dev = {0}/{1}/{2}/{3}".format(
                        stats1["min"],
                        stats1["avg"],
                        stats1["max"],
                        stats1["dev"],
                        )
                    )
            raise error.TestFail("Significant difference in rtt due to bgscan")


    def server_ping(self, params):
        """ Ping the client from the server """
        if self.server is None:
            self.__unreachable("server_ping")
            return
        ping_ip = params.get('ping_ip', self.client_wifi_ip)
        count = params.get('count', self.defpingcount)
        # set timeout for 3s / ping packet
        result = self.server.run("%s %s %s" % \
            (self.server_ping_cmd, self.__ping_args(params),
             ping_ip), timeout=3*int(count))

        stats = self.__get_pingstats(result.stdout)
        self.write_perf(stats)
        self.__print_pingstats("server_ping ", stats)


    def server_ping_bg(self, params):
        """ Ping the client from the server """
        if self.server is None:
            self.__unreachable("server_ping_bg")
            return
        ping_ip = params.get('ping_ip', self.client_wifi_ip)
        cmd = "ping %s %s" % (self.__ping_args(params), ping_ip)
        self.ping_thread = HelperThread(self.server, cmd)
        self.ping_thread.start()


    def server_ping_bg_stop(self, params):
        if self.server is None:
            self.__unreachable("server_ping_bg_stop")
            return
        if self.ping_thread is not None:
            self.server.run("pkill ping")
            self.ping_thread.join()
            self.ping_thread = None


    def client_ping6(self, params):
        """ Ping the server from the client via IPv6 """
        if 'ping_ip' in params:
            ping_ip = params['ping_ip']
        else:
            result = self.client.run('%s -6 route show dev %s default' %
                                     (self.client_cmd_ip, self.client_wlanif))
            router_match = re.search('via (\S*)', result.stdout)
            if not router_match:
                raise error.TestFail('Cannot find default router')
            ping_ip = router_match.group(1)
            params.setdefault('interface', self.client_wlanif)
        count = params.get('count', self.defpingcount)
        # set timeout for 3s / ping packet
        result = self.client.run("%s %s %s" % (
            self.client_cmd_ping6, self.__ping_args(params), ping_ip),
            timeout=3*int(count))

        stats = self.__get_pingstats(result.stdout)
        self.write_perf(stats)
        self.__print_pingstats("client_ping6 ", stats)


    def __run_iperf(self, mode, params):
        iperf_args = ""
        if 'udp' in params:
            iperf_args += " -u"
            test = "UDP"
        else:
            test = "TCP"
        if 'nodelay' in params:
            iperf_args += " -N"
            self.write_perf({'nodelay':'true'})
        if 'window' in params:
            iperf_args += " -w %s" % params['window']
            self.write_perf({'window':params['window']})
        iperf_args += " -p %s" % self.defiperfport

        # Assemble client-specific arguments
        client_args = iperf_args + " -f m -t %s" % params.get('test_time', 15)
        if 'bandwidth' in params:
            client_args += " -b %s" % params['bandwidth']
            self.write_perf({'bandwidth':params['bandwidth']})
        elif 'udp' in params:
            bw = None
            # Supply nominal channel bandwidth
            if self.cur_phymode == '802.11b':
                bw = '7m'
            elif self.cur_phymode == '802.11a':
                bw = '30m'              # assumes no bursting
            elif self.cur_phymode == '802.11g':
                bw = '30m'              # assumes no bursting
            elif self.cur_phymode == '802.11n':
                # TODO(sleffler) distinguish HT20/HT40 and # streams
                bw = '110m'
            if bw is not None:
                client_args += " -b %s" % bw
                self.write_perf({'bandwidth':bw})

        ip_rules = []
        if mode == 'server':
            server = { 'host': self.client, 'cmd': self.client_cmd_iperf }
            client = { 'host': self.server, 'cmd': self.server_cmd_iperf,
                       'target': self.client_wifi_ip }

            # Open up access from the server into our DUT
            ip_rules.append(self.__firewall_open('tcp', self.server_wifi_ip))
            ip_rules.append(self.__firewall_open('udp', self.server_wifi_ip))
        else:
            server = { 'host': self.server, 'cmd': self.server_cmd_iperf }
            client = { 'host': self.client, 'cmd': self.client_cmd_iperf,
                       'target': self.server_wifi_ip }

        iperf_thread = HelperThread(server['host'],
            "%s -s %s" % (server['cmd'], iperf_args))
        iperf_thread.start()
        # NB: block to allow server time to startup
        time.sleep(self.defwaittime)

        # Run iperf command and receive command results
        t0 = time.time()
        results = client['host'].run("%s -c %s%s" % \
            (client['cmd'], client['target'], client_args))
        actual_time = time.time() - t0
        logging.info('actual_time: %f', actual_time)

        server['host'].run("pkill iperf", ignore_status=True)
        iperf_thread.join()

        # Close up whatever firewall rules we created for iperf
        for rule in ip_rules:
            self.__firewall_close(rule)

        self.write_perf({
            'frequency'  : self.cur_frequency,
            'phymode'    : self.cur_phymode,
            'security'   : self.cur_security,
            'test'       : test,
            'mode'       : mode,
            'actual_time': actual_time,
        })

        logging.info(results)

        lines = results.stdout.splitlines()

        # Each test type has a different form of output
        if test in ['TCP', 'TCP_NODELAY']:
            """Parses the following and returns a singleton containing
            throughput.

            ------------------------------------------------------------
            Client connecting to localhost, TCP port 5001
            TCP window size: 49.4 KByte (default)
            ------------------------------------------------------------
            [  3] local 127.0.0.1 port 57936 connected with 127.0.0.1 port 5001
            [ ID] Interval       Transfer     Bandwidth
            [  3]  0.0-10.0 sec  2.09 GBytes  1.79 Gbits/sec
            """
            tcp_tokens = lines[6].split()
            if len(tcp_tokens) >= 6 and tcp_tokens[-1].endswith('bits/sec'):
                self.write_perf({'throughput':float(tcp_tokens[-2])})
        elif test in ['UDP', 'UDP_NODELAY']:
            """Parses the following and returns a tuple containing throughput
            and the number of errors.

            ------------------------------------------------------------
            Client connecting to localhost, UDP port 5001
            Sending 1470 byte datagrams
            UDP buffer size:   108 KByte (default)
            ------------------------------------------------------------
            [  3] local 127.0.0.1 port 54244 connected with 127.0.0.1 port 5001
            [ ID] Interval       Transfer     Bandwidth
            [  3]  0.0-10.0 sec  1.25 MBytes  1.05 Mbits/sec
            [  3] Sent 893 datagrams
            [  3] Server Report:
            [ ID] Interval       Transfer     Bandwidth       Jitter   Lost/Total Datagrams
            [  3]  0.0-10.0 sec  1.25 MBytes  1.05 Mbits/sec  0.032 ms    1/  894 (0.11%)
            [  3]  0.0-15.0 sec  14060 datagrams received out-of-order
            """
            # Search for the last row containing the word 'Bytes'
            mb_row = [row for row,data in enumerate(lines)
                      if 'Bytes' in data][-1]
            udp_tokens = lines[mb_row].replace('/', ' ').split()
            # Find the column ending with "...Bytes"
            mb_col = [col for col,data in enumerate(udp_tokens)
                      if data.endswith('Bytes')]
            if len(mb_col) > 0 and len(udp_tokens) >= mb_col[0] + 9:
                # Make a sublist starting after the column named "MBytes"
                stat_tokens = udp_tokens[mb_col[0]+1:]
                self.write_perf({'throughput':float(stat_tokens[0]),
                                 'jitter':float(stat_tokens[3]),
                                 'lost':float(stat_tokens[7].strip('()%'))})
        else:
            raise error.TestError('Unhandled test')

        return True


    def client_iperf(self, params):
        """ Run iperf on the client against the server """
        self.__run_iperf('client', params)


    def server_iperf(self, params):
        """ Run iperf on the server against the client """
        if self.server is None:
            self.__unreachable("server_iperf")
            return
        self.__run_iperf('server', params)


    def __is_installed(self, host, filename):
        result = host.run("ls %s" % filename, ignore_status=True)
        m = re.search(filename, result.stdout)
        return m is not None


    def __firewall_open(self, proto, src):
        rule = 'INPUT -s %s/32 -p %s -m %s -j ACCEPT' % (src, proto, proto)
        result = self.client.run('%s -S INPUT' % self.client_cmd_iptables)
        if '-A %s ' % rule in result.stdout.splitlines():
            return None
        self.client.run('%s -A %s' % (self.client_cmd_iptables, rule))
        self.firewall_rules.append(rule)
        return rule


    def __firewall_close(self, rule):
        if rule in self.firewall_rules:
            self.client.run('%s -D %s' % (self.client_cmd_iptables, rule))
            self.firewall_rules.remove(rule)

    def firewall_cleanup(self, params):
        for rule in self.firewall_rules:
            self.__firewall_close(rule)

    def __run_netperf(self, mode, params):
        np_rules = []
        if mode == 'server':
            server = { 'host': self.client, 'cmd': self.client_cmd_netserv }
            client = { 'host': self.server, 'cmd': self.server_cmd_netperf,
                       'target': self.client_wifi_ip }

            # Open up access from the server into our DUT
            np_rules.append(self.__firewall_open('tcp', self.server_wifi_ip))
            np_rules.append(self.__firewall_open('udp', self.server_wifi_ip))
        else:
            server = { 'host': self.server, 'cmd': self.server_cmd_netserv }
            client = { 'host': self.client, 'cmd': self.client_cmd_netperf,
                       'target': self.server_wifi_ip }

        netperf_thread = HelperThread(server['host'],
            "%s -p %s" % (server['cmd'],  self.defnetperfport))
        netperf_thread.start()
        # NB: block to allow server time to startup
        time.sleep(self.defwaittime)

        # Assemble arguments for client command
        test = params.get('test', 'TCP_STREAM')
        netperf_args = '-H %s -p %s -t %s -l %d' % (client['target'],
                        self.defnetperfport, test, params.get('test_time', 15))

        # Run netperf command and receive command results
        t0 = time.time()
        results = client['host'].run("%s %s" % (client['cmd'], netperf_args))
        actual_time = time.time() - t0
        logging.info('actual_time: %f', actual_time)

        server['host'].run("pkill netserver", ignore_status=True)
        netperf_thread.join()

        # Close up whatever firewall rules we created for netperf
        for rule in np_rules:
            self.__firewall_close(rule)

        self.write_perf({
            'frequency'  : self.cur_frequency,
            'phymode'    : self.cur_phymode,
            'security'   : self.cur_security,
            'test'       : test,
            'mode'       : mode,
            'actual_time': actual_time,
        })

        logging.info(results)

        lines = results.stdout.splitlines()

        # Each test type has a different form of output
        if test in ['TCP_STREAM', 'TCP_MAERTS', 'TCP_SENDFILE']:
            """Parses the following (works for both TCP_STREAM, TCP_MAERTS and
            TCP_SENDFILE) and returns a singleton containing throughput.

            TCP STREAM TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET to \
            foo.bar.com (10.10.10.3) port 0 AF_INET
            Recv   Send    Send
            Socket Socket  Message  Elapsed
            Size   Size    Size     Time     Throughput
            bytes  bytes   bytes    secs.    10^6bits/sec

            87380  16384  16384    2.00      941.28
            """
            self.write_perf({'Throughput':float(lines[6].split()[4])})
        elif test == 'UDP_STREAM':
            """Parses the following and returns a touple containing throughput
            and the number of errors.

            UDP UNIDIRECTIONAL SEND TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET \
            to foo.bar.com (10.10.10.3) port 0 AF_INET
            Socket  Message  Elapsed      Messages
            Size    Size     Time         Okay Errors   Throughput
            bytes   bytes    secs            #      #   10^6bits/sec

            129024   65507   2.00         3673      0     961.87
            131072           2.00         3673            961.87
            """
            udp_tokens = lines[5].split()
            self.write_perf({'Throughput':float(udp_tokens[5]),
                             'Errors':float(udp_tokens[4])})
        elif test in ['TCP_RR', 'TCP_CRR', 'UDP_RR']:
            """Parses the following which works for both rr (TCP and UDP)
            and crr tests and returns a singleton containing transfer rate.

            TCP REQUEST/RESPONSE TEST from 0.0.0.0 (0.0.0.0) port 0 AF_INET \
            to foo.bar.com (10.10.10.3) port 0 AF_INET
            Local /Remote
            Socket Size   Request  Resp.   Elapsed  Trans.
            Send   Recv   Size     Size    Time     Rate
            bytes  Bytes  bytes    bytes   secs.    per sec

            16384  87380  1        1       2.00     14118.53
            16384  87380
            """
            self.write_perf({'Transfer_Rate':float(lines[6].split()[5])})
        else:
            raise error.TestError('Unhandled test')

        return True


    def client_netperf(self, params):
        """ Run netperf on the client against the server """
        self.__run_netperf('client', params)


    def server_netperf(self, params):
        """ Run netperf on the server against the client """
        if self.server is None:
            self.__unreachable("server_netperf")
            return
        self.__run_netperf('server', params)


    def __create_netdump_dev(self, devname='mon0'):
        self.client.run("%s dev %s del" % (self.client_cmd_iw, devname),
                        ignore_status=True)
        self.client.run("%s dev %s interface add %s type monitor" %
                        (self.client_cmd_iw, self.client_wlanif, devname))
        self.client.run("%s %s up" % (self.client_cmd_ifconfig, devname))
        return devname


    def __destroy_netdump_dev(self, devname='mon0'):
        self.client.run("%s dev %s del" % (self.client_cmd_iw, devname))


    def client_start_capture(self, params):
        """ Start capturing network traffic on the client """
        self.client_stop_capture({})
        devname = self.__create_netdump_dev()
        self.client_netdump_dir = self.client.get_tmp_dir()
        self.client_netdump_file = os.path.join(self.client_netdump_dir,
                                                "client.pcap")
        cmd = "%s -i %s -w %s -s %s" % (self.client_cmd_netdump, devname,
                                  self.client_netdump_file,
                                  params.get('snaplen', '152'))
        logging.info(cmd)
        self.client_netdump_thread = HelperThread(self.client, cmd)
        self.client_netdump_thread.start()


    def client_stop_capture(self, params):
        if self.client_netdump_thread is not None:
            self.__destroy_netdump_dev()
            self.client.run("pkill %s" % self.client_cmd_netdump,
                            ignore_status=True)
            self.client.get_file(
                self.client_netdump_file,
                self.__get_local_file('client_capture_%02d.pcap'))
            self.client.delete_tmp_dir(self.client_netdump_dir)
            self.client_netdump_thread.join()
            self.client_netdump_thread = None
        else:
            # Just in case something got leftover from a previous run...
            self.client.run("pkill %s" % self.client_cmd_netdump,
                            ignore_status=True)


    def client_suspend(self, params):
        """ Suspend the system """

        script_client_file = self.install_script('site_system_suspend.py',
                                                 '../client/cros/rtc.py',
                                                 '../client/cros/'
                                                 'sys_power.py',
                                                 '../client/cros/'
                                                 'upstart.py')
        result = self.client.run('python "%s" %d' %
            (script_client_file, int(params.get("suspend_time", 5))))


    def client_suspend_bg(self, params):
        """ Suspend the system in the background """

        script_client_file = self.install_script('site_system_suspend.py',
                                                 '../client/cros/rtc.py',
                                                 '../client/cros/'
                                                 'sys_power.py',
                                                 '../client/cros/'
                                                 'upstart.py')
        cmd = ('python "%s" %d %s' %
               (script_client_file,
                int(params.get("suspend_time", 5)),
                params.get("after_command", '')))
        self.client_suspend_thread = HelperThread(self.client, cmd)
        self.client_suspend_thread.start()


    def client_suspend_end(self, params):
        """ Join the backgrounded suspend thread """

        self.client_suspend_thread.join()
        if self.client_suspend_thread.result.exit_status:
            raise error.TestError('suspend failed')

    def restart_supplicant(self, params):
        """ Restart wpa_supplicant.  Cert params are unfortunately "sticky". """

        self.client.run("stop wpasupplicant; start wpasupplicant")


    def profile_create(self, params):
        """ Create a profile with the specified name """
        self.client.run('%s/test/create-profile %s' %
                        (self.client_cmd_flimflam_lib, params['name']))

    def profile_remove(self, params, ignore_status=False):
        """ Remove the specified profile """
        self.client.run('%s/test/rm-profile %s' %
                        (self.client_cmd_flimflam_lib, params['name']),
                         ignore_status=ignore_status)

    def profile_push(self, params):
        """ Push the specified profile on the stack """
        self.client.run('%s/test/push-profile %s' %
                        (self.client_cmd_flimflam_lib, params['name']))

    def profile_pop(self, params, ignore_status=False):
        """ Pop the specified profile from the stack or any profile
            if no name is specified.
        """
        if 'name' in params:
            self.client.run('%s/test/pop-profile %s' %
                            (self.client_cmd_flimflam_lib, params['name']),
                            ignore_status=ignore_status)
        else:
            self.client.run('%s/test/pop-profile' %
                            (self.client_cmd_flimflam_lib),
                            ignore_status=ignore_status)


    def __get_wifi_device_path(self):
        if self.client_wifi_device_path:
            return self.client_wifi_device_path
        ret = []
        result = self.client.run('%s/test/list-devices' %
                                 self.client_cmd_flimflam_lib)
        device_path = None
        for line in result.stdout.splitlines():
            m = re.match('\[\s*(\S*)\s*\]', line)
            if m is not None:
                device_path = m.group(1)
                continue
            if re.search('Name = Wireless', line) is not None:
                self.client_wifi_device_path = device_path
                break

        return self.client_wifi_device_path

    def enable_wifi(self, params):
        wifi = self.__get_wifi_device_path()
        if wifi:
            self.client.run('%s/test/enable-device %s' %
                            (self.client_cmd_flimflam_lib, wifi))

    def disable_wifi(self, params):
        wifi = self.__get_wifi_device_path()
        if wifi:
            self.client.run('%s/test/disable-device %s' %
                            (self.client_cmd_flimflam_lib, wifi))


    def client_get_signal(self, params):
        result = self.client.run('%s dev %s link; '
                                 '%s dev %s station dump; '
                                 '%s dev %s survey dump' %
                                 ((self.client_cmd_iw, self.client_wlanif) * 3))
        current_frequency = None
        link_frequency = None
        signal_info = {}
        signal_values = ( 'frequency', 'signal', 'signal avg', 'noise' )
        for line in result.stdout.splitlines():
            m = re.match('\s*(\S.*):\s*(\S*)', line)
            if m is None:
                continue
            var, val = m.groups()
            if var == 'freq':
                link_frequency = val
            elif var == 'frequency':
                current_frequency = val
            if (var in signal_values and
                (current_frequency == None or
                 current_frequency == link_frequency)):
                signal_info[var] = val

        self.client_signal_info = signal_info
        logging.info('Signal Info: %s' % repr(signal_info))


    def bgscan_set(self, params):
        """ Control wpa_supplicant bgscan """
        opts = ""
        if params.get('short_interval', None):
            opts += " BgscanShortInterval=%s" % params['short_interval']
        if params.get('long_interval', None):
            opts += " ScanInterval=%s" % params['long_interval']
        if params.get('signal', None):
            signal = params['signal']
            if signal == 'auto':
                if 'signal avg' not in self.client_signal_info:
                    raise error.TestError('No signal info')
                else:
                    signal = int(self.client_signal_info['signal avg'])
                    if 'offset' in params:
                        signal += int(params['offset'])
                    if 'noise' in self.client_signal_info:
                        # Compensate for real noise vs standard estimate
                        signal -= 95 + int(self.client_signal_info['noise'])
                logging.info('Auto signal: %s' % repr(signal))
            opts += " BgscanSignalThreshold=%s" % signal
        if params.get('method', None):
            opts += " BgscanMethod=%s" % params['method']
        self.client.run('%s/test/set-bgscan --interface %s %s' %
                        (self.client_cmd_flimflam_lib, self.client_wlanif,
                         opts))


    def bgscan_disable(self, params):
        """ Disable wpa_supplicant bgscan """
        self.bgscan_set({'method' : 'none'})


    def bgscan_enable(self, params):
        """ Enable wpa_supplicant bgscan """
        self.bgscan_set({'method' : 'default'})


    def scan(self, params):
        self.client.run("%s dev %s scan" %
                        (self.client_cmd_iw, self.client_wlanif))


    def time_sync(self, params):
        for name in params or ['client', 'server', 'router']:
            system = { 'client': self.client,
                       'server': self.server,
                       'router': self.router }.get(name)
            epoch_seconds = time.time()
            busybox_format = '%Y%m%d%H%M.%S'
            busybox_date = datetime.datetime.utcnow().strftime(busybox_format)
            system.run('date -u --set=@%s 2>/dev/null || date -u %s' % \
                (epoch_seconds, busybox_date))

    def vpn_client_load_tunnel(self, params):
        """ Load the 'tun' device.

            Necessary when the VPN Server is configured with 'dev tun'.
        """
        result = self.client.run('modprobe tun') # When server using tunnel.

    def vpn_client_config(self, params):
        """ Configure & launch the VPN client.

            Parameters:

              'kind'      : required
                  Indicates the kind of VPN which is to be used.
                  Valid values are:

                    l2tpipsec-cert
                    l2tpipsec-psk
                    openvpn

              'vpn-host-ip': optional
                  Specifies the IP of the VPN server.  If not provided,
                  defaults to 'self.server_wifi_ip'

              'files'      : required
                  A dict which contains a set of file names.

                     'ca-certificate'     : path to CA certificate file
                     'client-certificate' : path to client certificate file
                     'client-key'         : path to client key file

              'remote-cert-tls' : optional
                    If provided, this option can be 'server', 'client' or
                    'none'.
                    If not specified, the default is 'none'.
                    The value provided is passed directly to 'connect-vpn'.
        """
        self.vpn_client_kill({}) # Must be first.  Relies on self.vpn_kind.
        self.vpn_kind = params.get('kind', None)

        # Starting up the VPN client may cause the DUT's routing table (esp.
        # the default route) to change.  Set up a host route backwards so
        # we don't lose our control connection in that event.
        self.__add_host_route(self.client)

        if self.vpn_kind is None:
            raise error.TestFail('No VPN kind specified for this test.')
        elif self.vpn_kind == 'openvpn':
            # 'ca_certificate', 'client-certificate' and 'client-key'.
            vpn_host_ip            = params.get('vpn-host-ip',
                                                self.server_wifi_ip)
            cert_pathnames         = params.get('files', {})
            remote_cert_tls_option = ""
            remote_cert_tls        = params.get('remote-cert-tls', None)

            if remote_cert_tls is not None:
                remote_cert_tls_option = "--remote-cert-tls " + remote_cert_tls

            result = self.client.run('%s/test/connect-vpn '
                                     '--verbose '
                                     '%s '
                                     'openvpn vpn-name %s vpn-domain '
                                     '%s '   # ca certificate
                                     '%s '   # client certificate
                                     '%s' %  # client key
                                     (self.client_cmd_flimflam_lib,
                                      remote_cert_tls_option,
                                      vpn_host_ip,
                                      cert_pathnames['ca-certificate'],
                                      cert_pathnames['client-certificate'],
                                      cert_pathnames['client-key']))
        elif self.vpn_kind == 'l2tpipsec-psk':
            # vpn_host_ip is self.server.ip because that is the
            # adapter that ipsec listens on.
            vpn_host_ip = params.get('vpn-host-ip', self.server.ip)
            password    = params.get('password'  , None)
            chapuser    = params.get('chapuser'  , None)
            chapsecret  = params.get('chapsecret', None)
            result = self.client.run('%s/test/connect-vpn '
                                     '--verbose '
                                     'l2tpipsec-psk vpn-name %s vpn-domain '
                                     '%s '  # password
                                     '%s '  # chapuser
                                     '%s' % # chapsecret
                                     (self.client_cmd_flimflam_lib,
                                      vpn_host_ip,
                                      password, chapuser, chapsecret))
        elif self.vpn_kind == 'l2tpipsec-cert':
            label = 'vpn'
            nss_dir = '/home/chronos/user/.pki/nssdb'
            ca_nickname = 'test_nickname'
            pkcs11_lib = 'libchaps.so'
            slot_id = '07'
            user_pin = '111111'

            # 'ca_certificate', 'client-certificate' and 'client-key'.
            cert_pathnames = params.get('files', {})
            der_pathnames = dict(
                [[k, v + '.der'] for k, v in cert_pathnames.items()])

            # Set up dummy certificate database.
            self.client.run('cryptohome --action=unmount')
            self.client.run('rm -rf %s' % nss_dir)
            self.client.run('mkdir -p %s' % nss_dir)
            # Create an empty database with no password.
            self.client.run('echo "\n\n" | nsscertutil '
                            '-N '
                            '-d sql:%s' % nss_dir)
            self.client.run('nsscertutil '
                            '-A '
                            ' -t P,, '
                            ' -n %s '
                            ' -i %s '
                            ' -d sql:%s' %
                            (ca_nickname,
                             cert_pathnames['ca-certificate'],
                             nss_dir))

            # Set up pkcs11.
            self.client.run('rm -rf /home/chronos/user/.tpm')
            self.client.run('cryptohome --action=force_pkcs11_init')
            # TODO(gauravsh): pkcs11_init shouldn't be needed after
            # force_pkcs11_init.
            self.client.run('cryptohome --action=pkcs11_init')
            self.client.run('openssl '
                            'x509 '
                            '-in %s '
                            '-out %s '
                            '-outform DER' %
                            (cert_pathnames['client-certificate'],
                             der_pathnames['client-certificate']))
            self.client.run('openssl '
                            'rsa '
                            '-in %s '
                            '-out %s '
                            '-outform DER' %
                            (cert_pathnames['client-key'],
                             der_pathnames['client-key']))
            self.__store_pkcs11_resource(pkcs11_lib,
                                         user_pin,
                                         slot_id,
                                         label,
                                         der_pathnames['client-certificate'],
                                         'cert')
            self.__store_pkcs11_resource(pkcs11_lib,
                                         user_pin,
                                         slot_id,
                                         label,
                                         der_pathnames['client-key'],
                                         'privkey')

            # vpn_host_ip is self.server.ip because that is the
            # adapter that ipsec listens on.
            vpn_host_ip = params.get('vpn-host-ip', self.server.ip)
            chapuser    = params.get('chapuser'  , None)
            chapsecret  = params.get('chapsecret', None)
            result = self.client.run('%s/test/connect-vpn '
                                     '--verbose '
                                     'l2tpipsec-cert vpn-name %s vpn-domain '
                                     '%s '   # CACertNSS
                                     '0 '    # ClientCertSlot
                                     '%s '   # ClientCertID
                                     '%s '   # PIN
                                     '%s '   # chapuser
                                     '%s' %  # chapsecret
                                     (self.client_cmd_flimflam_lib,
                                      vpn_host_ip,
                                      ca_nickname,
                                      slot_id,
                                      user_pin,
                                      chapuser,
                                      chapsecret))
            self.client.run('pkill pkcsslotd')
        else:
            raise error.TestFail('(internal error): No launch case '
                                 'for VPN kind (%s)' % self.vpn_kind)

    def vpn_client_kill(self, params):
        """ Kill the VPN client if it's running. """
        if self.vpn_kind is not None:
            if self.vpn_kind == 'openvpn':
                self.client.run("pkill openvpn")
            elif self.vpn_kind in ('l2tpipsec-psk', 'l2tpipsec-cert'):
                self.client.run("/usr/sbin/ipsec stop")
            else:
                raise error.TestFail('(internal error): No kill case '
                                     'for VPN kind (%s)' % self.vpn_kind)
            self.vpn_kind = None

        self.__del_host_route(self.client)


    def __add_host_route(self, host):
        # What is the local address we use to get to the test host?
        local_ip = site_host_route.LocalHostRoute(host.ip).route_info["src"]

        # How does the test host currently get to this local address?
        host_route = site_host_route.RemoteHostRoute(host, local_ip).route_info

        # Flatten the returned dict into a single string
        route_args = " ".join(" ".join(x) for x in host_route.iteritems())

        self.host_route_args[host.ip] = "%s %s" % (local_ip, route_args)
        host.run("ip route add %s" % self.host_route_args[host.ip])

    def __del_host_route(self, host):
        if host.ip in self.host_route_args:
            host.run("ip route del %s" % self.host_route_args.pop(host.ip))

    def host_route_cleanup(self, params):
        for host in (self.client, self.server, self.router):
            self.__del_host_route(host)

    def log_time_diff(self, params):
        log_file = self.client_logfile

        time_diff = self.install_script('site_log_time_diff.py')
        result = self.client.run("python '%s' --from='%s' --to='%s'" %
                                      (time_diff, params['from'], params['to']))

        if '-' in result.stdout:
            logging.info("Unable to find timespan")
            return

        if "perf" in params:
            self.write_perf({params['perf']:float(result.stdout)})

    def client_deauth(self, params):
        self.wifi.deauth({'client': self.client.wlan_mac})

    def client_reboot(self, params):
        self.client_installed_scripts = {}

        if 'timeout' not in params:
            logging.info("Using default reboot timeout")
            self.client.reboot()
        else:
            reboot_timeout = float(params['timeout'])
            logging.info("Reboot timeout is %f seconds", reboot_timeout)
            self.client.reboot(timeout=reboot_timeout)

        self.profile_pop(self.test_profile, ignore_status=True)
        self.profile_remove(self.test_profile, ignore_status=True)
        self.profile_create(self.test_profile)
        self.profile_push(self.test_profile)

    def __store_pkcs11_resource(self, pkcs11_lib, user_pin, slot_id,
                                label, der_file_path, resource_type):
        self.client.run('pkcs11-tool '
                        '--module=%s '
                        '--pin %s '
                        '--id %s '
                        '--label %s '
                        '--write-object %s '
                        '--type %s' %
                        (pkcs11_lib,
                         user_pin,
                         slot_id,
                         label,
                         der_file_path,
                         resource_type))

    def client_check_ipv6(self, params):
        addrs = self.__get_ip6addrs(self.client, self.client_wlanif)
        errors = []
        if 'address_count' in params:
            expected = int(params['address_count'])
            if expected != len(addrs):
                errors.append('IPv6 address count %d is different from '
                              'expected %d' % (len(addrs), expected))

        if 'local_count' in params:
            local_count = 0
            expected = int(params['local_count'])
            for addr in addrs:
                if addr.startswith('fe80'):
                    local_count += 1
            if local_count != expected:
                errors.append('IPv6 address local count %d is different from '
                              'expected %d' % (local_count, expected))

        if 'mac_count' in params:
            mac_count = 0
            expected = int(params['mac_count'])
            mac_parts = self.client.wlan_mac.split(':')
            # Convert last 3 octets of MAC into suffix of IPv6 address
            shorts = [int(mac_parts[-3], 16), int(''.join(mac_parts[-2:]), 16)]
            mac_suffix_re = re.compile('%x:%x/' % tuple(shorts))
            for addr in addrs:
                if mac_suffix_re.search(addr):
                    mac_count += 1
            if mac_count != expected:
                errors.append('IPv6 address mac count %d is different from '
                              'expected %d' % (mac_count, expected))

        if 'default_route' in params:
            result = self.client.run('%s -6 route show dev %s default' %
                                     (self.client_cmd_ip, self.client_wlanif))

            found = bool('default' in result.stdout)
            expected = bool(params['default_route'])
            if found != expected:
                errors.append('IPv6 default route found == %s '
                              'from expected %s' % (found, expected))


        if errors:
            errors.append('Addresses are: %s' % ', '.join(addrs))
            raise error.TestFail('\n'.join(errors))

    def client_start_statistics(self, params):
        """ Start capturing network statistics on the client """
        self.client_stop_statistics({})
        script = 'site_wlan_statistics.py'
        script_client_file = self.install_script(script)

        cmd = ('python %s --count=%s --period=%s' %
               (script_client_file,
                params.get('count', '-1'),
                params.get('period', '1')))
        logging.info(cmd)
        self.client_stats_thread = HelperThread(self.client, cmd)
        self.client_stats_thread.start()

    def client_stop_statistics(self, params):
        self.client.run('pkill -f site_wlan_statistics.py',
                        ignore_status=True)
        if self.client_stats_thread is not None:
            self.client_stats_thread.join()
            stats = self.client_stats_thread.result.stdout
            logging.info(stats)
            file(self.__get_local_file(
                    'client_interface_statistics_%02d.txt'), 'w').write(stats)
            self.client_stats_thread = None

    def client_test_ipaddr(self, params):
        interface = params.get('interface', self.client_wlanif)
        self.__get_ipaddr(self.client, interface)


class HelperThread(threading.Thread):
    # Class that wraps a ping command in a thread so it can run in the bg.
    def __init__(self, client, cmd):
        threading.Thread.__init__(self)
        self.client = client
        self.cmd = cmd

    def run(self):
        # NB: set ignore_status as we're always terminated w/ pkill
        self.result = self.client.run(self.cmd, ignore_status=True)

def __byfile(a, b):
    if a['file'] < b['file']:
        return -1
    elif a['file'] > b['file']:
        return 1
    else:
        return 0


def read_tests(dir, *args):
    """
    Collect WiFi test tuples from files.  File names are used to
    sort the test objects so the convention is to name them NNN<test>
    where NNN is a decimal number used to sort and <test> is an
    identifying name for the test; e.g. 000Check11b
    """
    tests = []
    for file in os.listdir(dir):
        if any(fnmatch.fnmatch(file, pat) for pat in args):
            fd = open(os.path.join(dir, file))
            try:
                test = eval(fd.read())
            except Exception, e:
                logging.error("%s: %s", os.path.join(dir, file), str(e))
                raise e
            test['file'] = file
            tests.append(test)
    # 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())

    # Read in attributes from host config database
    client_attributes = site_host_attributes.HostAttributes(client_addr)

    # 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 None and hasattr(client_attributes, 'router_addr'):
        router_addr = client_attributes.router_addr
    if router_addr is not None:
        router['addr'] = router_addr

    server = config['server']
    if server_addr is None and hasattr(client_attributes, 'server_addr'):
        server_addr = client_attributes.server_addr
    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

def run_test_dir(test_name, job, args, machine):
    # convert autoserv args to something usable
    opts = dict([[k, v] for (k, e, v) in [x.partition('=') for x in args]])

    config_file = opts.get('config_file', 'wifi_testbed_config')
    test_pat = opts.get('test_pat', '[0-9]*')
    if utils.host_is_in_lab_zone(machine):
        # If we are in the lab use the names for the server, AKA rspro,
        # and the router as defined in:
        # go/chromeos-lab-hostname-convention
        server_addr = '%s-rspro' % machine
        router_addr = '%s-router' % machine
    else:
        server_addr = opts.get('server_addr', None)
        router_addr = opts.get('router_addr', None)

    run_options = opts.get('run_options', '').split(',')

    config = read_wifi_testbed_config(
        os.path.join(job.configdir, config_file),
        client_addr = machine,    # NB: take client identity from command line
        router_addr = router_addr,
        server_addr = server_addr)
    server = config['server']
    router = config['router']
    config['run_options'] = run_options

    logging.info("Client %s, Server %s, AP %s" % \
        (machine, server.get('addr', 'N/A'), router['addr']))

    test_dir = os.path.join(job.serverdir, "site_tests", test_name)

    for t in read_tests(test_dir, test_pat):
       job.run_test(test_name, testcase=t, config=config, tag=t['file'])


class test(test.test):
  """
  Base class for network_WiFi* classes that are created in the control
  directory for each test suite
  """
  version = 1

  def expect_failure(self, name, reason):
    if reason is None:
      reason = "no reason given"
    logging.info("%s: ignore failure (%s)", name, reason)


  # The testcase config, setup, etc are done out side the individual
  # test loop, in the control file.
  def run_once(self, testcase, config):
    name = testcase['name']
    try:
      if 'skip_test' in testcase and 'no_skip' not in config['run_options']:
        logging.info("%s: SKIP: %s", name, testcase['skip_test'])
      else:
        wt = WiFiTest(name, testcase['steps'], testcase.get('requires', []),
                      config)
        wt.run()
        wt.write_keyvals(self)
    except error.TestFail:
      if 'expect_failure' in testcase:
        self.expect_failure(name, testcase['expect_failure'])
      else:
        raise
    except Exception, e:
      if 'expect_failure' in testcase:
        self.expect_failure(name, testcase['expect_failure'])
      else:
        raise
