# 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 base64
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'], self.router)[0:32]
        else:
            # NB: router address isn't unique enough
            self.defssid = self.__get_defssid(server['addr'], None)[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)

        self.init_profile()
        self.client_capabilities = self.__get_client_capabilities()


    def init_profile(self):
       # 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)


    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({})
        if hasattr(self, 'test_profile'):
          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, host):
        #
        # Calculate ssid based on test name; this lets us track progress
        # by watching beacon frames.  Generate a unique suffix for this
        # SSID based either a unique MAC address on the AP, or failing
        # this, the IP address of the AP.
        #
        address_lines = []
        if host:
            # This executes before __server_discover_commands() so we
            # can't discover the "ip" command.  Instead, we're lenient
            # about it being missing.
            address_lines = host.run('/usr/sbin/ip addr show',
                                     ignore_status=True).stdout.splitlines()

        mac_re = re.compile('link/ether (?P<mac>(([0-9a-f]{2}):?){6}) ',
                            flags=re.IGNORECASE)
        for line in address_lines:
            mac_match = mac_re.search(line)
            if mac_match:
                mac_string = mac_match.group('mac')
                if mac_string not in ['00:00:00:00:00:00', 'ff:ff:ff:ff:ff:ff']:
                    mac_bytes = ''
                    for octet in mac_string.split(':'):
                        mac_bytes += chr(int(octet, 16))
                    unique_name = base64.b64encode(mac_bytes)
                    break
        else:
            unique_name = ipaddr
        return re.sub('[^a-zA-Z0-9_]', '_', "%s_%s" % (self.name, unique_name))


    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', '0'))
        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)

    def client_configure_service(self, params):
        guid = params.pop('GUID', '')
        args = ''
        for var, val in params.iteritems():
            args += ' %s %s' % (var, val)
        self.client.run('%s/test/configure-service %s %s' %
                        (self.client_cmd_flimflam_lib, guid, args))

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
  testtype = WiFiTest

  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 = self.testtype(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
