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
6import pprint
7
8from autotest_lib.client.common_lib import error
9from autotest_lib.client.common_lib.cros.network import xmlrpc_datatypes
10from autotest_lib.server import test
11from autotest_lib.server.cros.network import chaos_clique_utils
12
13class network_WiFi_ChaosConnectDisconnect(test.test):
14    """ Dynamic Chaos test to connect and disconnect to an AP. """
15
16    version = 1
17
18
19    def run_once(self, capturer, capturer_frequency, capturer_ht_type,
20                 host, assoc_params, client, tries, debug_info=None):
21        """ Main entry function for autotest.
22
23        @param capturer: a packet capture device
24        @param capturer_frequency: integer channel frequency in MHz.
25        @param capturer_ht_type: string specifier of channel HT type.
26        @param host: an Autotest host object, DUT.
27        @param assoc_params: an AssociationParameters object.
28        @param client: WiFiClient object
29        @param tries: an integer, number of connection attempts.
30        @param debug_info: a string of additional info to display on failure
31
32        """
33
34        results = []
35
36        for i in range(1, tries + 1):
37            client.shill.disconnect(assoc_params.ssid)
38            if not client.shill.init_test_network_state():
39                return 'Failed to set up isolated test context profile.'
40
41            capturer.start_capture(capturer_frequency, ht_type=capturer_ht_type)
42            try:
43                success = False
44                logging.info('Connection attempt %d', i)
45                host.syslog('Connection attempt %d' % i)
46                start_time = host.run("date '+%FT%T.%N%:z'").stdout.strip()
47                assoc_result = xmlrpc_datatypes.deserialize(
48                        client.shill.connect_wifi(assoc_params))
49                end_time = host.run("date '+%FT%T.%N%:z'").stdout.strip()
50                success = assoc_result.success
51                if not success:
52                    logging.info('Connection attempt %d failed; reason: %s',
53                                 i, assoc_result.failure_reason)
54                    results.append(
55                            {'try' : i,
56                             'error' : assoc_result.failure_reason,
57                             'start_time': start_time,
58                             'end_time': end_time})
59                else:
60                    logging.info('Connection attempt %d passed', i)
61            finally:
62                filename = str('connect_try_%d_%s.trc' % (i,
63                               ('success' if success else 'fail')))
64                capturer.stop_capture(save_dir=self.outputdir,
65                                      save_filename=filename)
66                if not success:
67                    client.collect_debug_info('try_%d' % i)
68                    chaos_clique_utils.collect_pcap_info(self.outputdir,
69                                                         filename, i)
70                client.shill.disconnect(assoc_params.ssid)
71                client.shill.clean_profiles()
72
73        if len(results) > 0:
74            # error.TestError doesn't handle the formatting inline, doing it
75            # here so it is clearer to read in the status.log file.
76            msg = str('Failed on the following attempts:\n%s\n'
77                      'With the assoc_params:\n%s\n'
78                      'Debug info: %s\nDUT MAC:%s' %
79                      (pprint.pformat(results), assoc_params, debug_info,
80                       client.wifi_mac))
81            raise error.TestFail(msg)
82        logging.debug('Debug info: %s', debug_info)
83