1# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import logging
6
7from autotest_lib.client.common_lib import error
8from autotest_lib.client.common_lib import utils
9from autotest_lib.client.common_lib.cros.network import xmlrpc_datatypes
10from autotest_lib.client.cros import constants
11from autotest_lib.server import test
12from autotest_lib.server.cros.network import wifi_test_context_manager
13
14class WiFiCellTestBase(test.test):
15    """An abstract base class for autotests in WiFi cells.
16
17    WiFiCell tests refer to participants in the test as client, router, and
18    server.  The client is just the DUT and the router is a nearby AP which we
19    configure in various ways to test the ability of the client to connect.
20    There is a third entity called a server which is distinct from the autotest
21    server.  In WiFiTests, the server is a host which the client can only talk
22    to over the WiFi network.
23
24    WiFiTests have a notion of the control network vs the WiFi network.  The
25    control network refers to the network between the machine running the
26    autotest server and the various machines involved in the test.  The WiFi
27    network is the subnet(s) formed by WiFi routers between the server and the
28    client.
29
30    """
31
32    def initialize(self, host):
33        # There are some DUTs that have different types of wifi modules.
34        # In order to generate separate performance graphs, a variant
35        # name is needed.  Writing this key will generate results with
36        # the name of <board>-<variant>.
37        info = host.host_info_store.get()
38        variant_name = info.get_label_value('variant')
39        if variant_name:
40            self.write_test_keyval({constants.VARIANT_KEY: variant_name})
41
42    @property
43    def context(self):
44        """@return the WiFi context for this test."""
45        return self._wifi_context
46
47
48    def parse_additional_arguments(self, commandline_args, additional_params):
49        """Parse additional arguments for use in test.
50
51        Subclasses should override this method do any other commandline parsing
52        and setting grabbing that they need to do.  For test clarity, do not
53        parse additional settings in the body of run_once.
54
55        @param commandline_args dict of argument key, value pairs.
56        @param additional_params object defined by test control file.
57
58        """
59        pass
60
61
62    def warmup(self, host, raw_cmdline_args, additional_params=None):
63        """
64        Use the additional_params argument to pass in custom test data from
65        control file to reuse test logic.  This object will be passed down via
66        parse_additional_arguments.
67
68        @param host host object representing the client DUT.
69        @param raw_cmdline_args raw input from autotest.
70        @param additional_params object passed in from control file.
71
72        """
73        cmdline_args = utils.args_to_dict(raw_cmdline_args)
74        logging.info('Running wifi test with commandline arguments: %r',
75                     cmdline_args)
76        self._wifi_context = wifi_test_context_manager.WiFiTestContextManager(
77                self.__class__.__name__,
78                host,
79                cmdline_args,
80                self.debugdir)
81
82        self._wifi_context.setup()
83        self.parse_additional_arguments(cmdline_args, additional_params)
84
85        msg = '======= WiFi autotest setup complete. Starting test... ======='
86        self._wifi_context.client.shill_debug_log(msg)
87
88
89    def cleanup(self):
90        msg = '======= WiFi autotest complete. Cleaning up... ======='
91        self._wifi_context.client.shill_debug_log(msg)
92        # If we fail during initialization, we might not have a context.
93        if hasattr(self, '_wifi_context'):
94            self._wifi_context.teardown()
95
96
97    def configure_and_connect_to_ap(self, ap_config):
98        """
99        Configure the router as an AP with the given config and connect
100        the DUT to it.
101
102        @param ap_config HostapConfig object.
103
104        @return name of the configured AP
105        """
106        self.context.configure(ap_config)
107        ap_ssid = self.context.router.get_ssid()
108        assoc_params = xmlrpc_datatypes.AssociationParameters(ssid=ap_ssid)
109        self.context.assert_connect_wifi(assoc_params)
110        return ap_ssid
111