Home | History | Annotate | Download | only in network
      1 #!/usr/bin/python
      2 #
      3 # Copyright (c) 2013 The Chromium Authors. All rights reserved.
      4 # Use of this source code is governed by a BSD-style license that can be
      5 # found in the LICENSE file.
      6 
      7 import unittest
      8 
      9 import common
     10 
     11 from autotest_lib.client.common_lib.cros.network import iw_runner
     12 
     13 class IwRunnerTest(unittest.TestCase):
     14     """Unit test for the IWRunner object."""
     15 
     16 
     17     class host_cmd(object):
     18         """Mock host command class."""
     19 
     20         def __init__(self, stdout, stderr, exit_status):
     21             self._stdout = stdout
     22             self._stderr = stderr
     23             self._exit_status = exit_status
     24 
     25 
     26         @property
     27         def stdout(self):
     28             """Returns stdout."""
     29             return self._stdout
     30 
     31 
     32         @property
     33         def stderr(self):
     34             """Returns stderr."""
     35             return self._stderr
     36 
     37 
     38         @property
     39         def exit_status(self):
     40             """Returns the exit status."""
     41             return self._exit_status
     42 
     43 
     44     class host(object):
     45         """Mock host class."""
     46 
     47         def __init__(self, host_cmd):
     48             self._host_cmd = IwRunnerTest.host_cmd(host_cmd, 1.0, 0)
     49 
     50 
     51         def run(self, cmd, ignore_status=False):
     52             """Returns the mocked output.
     53 
     54             @param cmd: a stub input ignore
     55             @param ignore_status: a stub input ignore
     56 
     57             """
     58             return self._host_cmd
     59 
     60 
     61     HT20 = str('BSS aa:aa:aa:aa:aa:aa (on wlan0)\n'
     62         '    freq: 2412\n'
     63         '    signal: -50.00 dBm\n'
     64         '    SSID: support_ht20\n'
     65         '    HT operation:\n'
     66         '         * secondary channel offset: no secondary\n')
     67 
     68     HT20_IW_BSS = iw_runner.IwBss('aa:aa:aa:aa:aa:aa', 2412,
     69                                   'support_ht20', iw_runner.SECURITY_OPEN,
     70                                   iw_runner.HT20, -50.00)
     71 
     72     HT20_2 = str('BSS 11:11:11:11:11:11 (on wlan0)\n'
     73         '     freq: 2462\n'
     74         '     signal: -42.00 dBm\n'
     75         '     SSID: support_ht20\n'
     76         '     WPA:          * Version: 1\n'
     77         '     HT operation:\n'
     78         '          * secondary channel offset: below\n')
     79 
     80     HT20_2_IW_BSS = iw_runner.IwBss('11:11:11:11:11:11', 2462,
     81                                     'support_ht20', iw_runner.SECURITY_WPA,
     82                                     iw_runner.HT40_BELOW, -42.00)
     83 
     84     HT40_ABOVE = str('BSS bb:bb:bb:bb:bb:bb (on wlan0)\n'
     85         '    freq: 5180\n'
     86         '    signal: -55.00 dBm\n'
     87         '    SSID: support_ht40_above\n'
     88         '    RSN:          * Version: 1\n'
     89         '    HT operation:\n'
     90         '         * secondary channel offset: above\n')
     91 
     92     HT40_ABOVE_IW_BSS = iw_runner.IwBss('bb:bb:bb:bb:bb:bb', 5180,
     93                                         'support_ht40_above',
     94                                         iw_runner.SECURITY_WPA2,
     95                                         iw_runner.HT40_ABOVE, -55.00)
     96 
     97     HT40_BELOW = str('BSS cc:cc:cc:cc:cc:cc (on wlan0)\n'
     98         '    freq: 2462\n'
     99         '    signal: -44.00 dBm\n'
    100         '    SSID: support_ht40_below\n'
    101         '    RSN:          * Version: 1\n'
    102         '    WPA:          * Version: 1\n'
    103         '    HT operation:\n'
    104         '        * secondary channel offset: below\n')
    105 
    106     HT40_BELOW_IW_BSS = iw_runner.IwBss('cc:cc:cc:cc:cc:cc', 2462,
    107                                         'support_ht40_below',
    108                                         iw_runner.SECURITY_MIXED,
    109                                         iw_runner.HT40_BELOW, -44.00)
    110 
    111     NO_HT = str('BSS dd:dd:dd:dd:dd:dd (on wlan0)\n'
    112         '    freq: 2412\n'
    113         '    signal: -45.00 dBm\n'
    114         '    SSID: no_ht_support\n')
    115 
    116     NO_HT_IW_BSS = iw_runner.IwBss('dd:dd:dd:dd:dd:dd', 2412,
    117                                    'no_ht_support', iw_runner.SECURITY_OPEN,
    118                                    None, -45.00)
    119 
    120     HIDDEN_SSID = str('BSS ee:ee:ee:ee:ee:ee (on wlan0)\n'
    121         '    freq: 2462\n'
    122         '    signal: -70.00 dBm\n'
    123         '    SSID: \n'
    124         '    HT operation:\n'
    125         '         * secondary channel offset: no secondary\n')
    126 
    127     SCAN_TIME_OUTPUT = str('real 4.5\n'
    128         'user 2.1\n'
    129         'system 3.1\n')
    130 
    131     HIDDEN_SSID_IW_BSS = iw_runner.IwBss('ee:ee:ee:ee:ee:ee', 2462,
    132                                          None, iw_runner.SECURITY_OPEN,
    133                                          iw_runner.HT20, -70.00)
    134 
    135     STATION_LINK_INFORMATION = str(
    136         'Connected to 12:34:56:ab:cd:ef (on wlan0)\n'
    137         '      SSID: PMKSACaching_4m9p5_ch1\n'
    138         '      freq: 5220\n'
    139         '      RX: 5370 bytes (37 packets)\n'
    140         '      TX: 3604 bytes (15 packets)\n'
    141         '      signal: -59 dBm\n'
    142         '      tx bitrate: 13.0 MBit/s MCS 1\n'
    143         '\n'
    144         '      bss flags:      short-slot-time\n'
    145         '      dtim period:    5\n'
    146         '      beacon int:     100\n')
    147 
    148     STATION_LINK_BSSID = '12:34:56:ab:cd:ef'
    149 
    150     STATION_LINK_IFACE = 'wlan0'
    151 
    152     STATION_LINK_FREQ = '5220'
    153 
    154     STATION_LINK_PARSED = {
    155         'SSID': 'PMKSACaching_4m9p5_ch1',
    156         'freq': '5220',
    157         'RX': '5370 bytes (37 packets)',
    158         'TX': '3604 bytes (15 packets)',
    159         'signal': '-59 dBm',
    160         'tx bitrate': '13.0 MBit/s MCS 1',
    161         'bss flags': 'short-slot-time',
    162         'dtim period': '5',
    163         'beacon int': '100'
    164         }
    165 
    166     STATION_DUMP_INFORMATION = str(
    167         'Station dd:ee:ff:33:44:55 (on mesh-5000mhz)\n'
    168         '        inactive time:  140 ms\n'
    169         '        rx bytes:       2883498\n'
    170         '        rx packets:     31981\n'
    171         '        tx bytes:       1369934\n'
    172         '        tx packets:     6615\n'
    173         '        tx retries:     4\n'
    174         '        tx failed:      0\n'
    175         '        signal:         -4 dBm\n'
    176         '        signal avg:     -11 dBm\n'
    177         '        Toffset:        81715566854 us\n'
    178         '        tx bitrate:     866.7 MBit/s VHT-MCS 9 80MHz '
    179         'short GI VHT-NSS 2\n'
    180         '        rx bitrate:     866.7 MBit/s VHT-MCS 9 80MHz '
    181         'short GI VHT-NSS 2\n'
    182         '        mesh llid:      0\n'
    183         '        mesh plid:      0\n'
    184         '        mesh plink:     ESTAB\n'
    185         '        mesh local PS mode:     ACTIVE\n'
    186         '        mesh peer PS mode:      ACTIVE\n'
    187         '        mesh non-peer PS mode:  ACTIVE\n'
    188         '        authorized:     yes\n'
    189         '        authenticated:  yes\n'
    190         '        preamble:       long\n'
    191         '        WMM/WME:        yes\n'
    192         '        MFP:            yes\n'
    193         '        TDLS peer:      no\n'
    194         '        connected time: 8726 seconds\n'
    195         'Station aa:bb:cc:00:11:22 (on mesh-5000mhz)\n'
    196         '        inactive time:  140 ms\n'
    197         '        rx bytes:       2845200\n'
    198         '        rx packets:     31938\n'
    199         '        tx bytes:       1309945\n'
    200         '        tx packets:     6672\n'
    201         '        tx retries:     0\n'
    202         '        tx failed:      0\n'
    203         '        signal:         -21 dBm\n'
    204         '        signal avg:     -21 dBm\n'
    205         '        tx bitrate:     866.7 MBit/s VHT-MCS 9 80MHz '
    206         'short GI VHT-NSS 2\n'
    207         '        rx bitrate:     650.0 MBit/s VHT-MCS 7 80MHz '
    208         'short GI VHT-NSS 2\n'
    209         '        mesh llid:      0\n'
    210         '        mesh plid:      0\n'
    211         '        mesh plink:     ESTAB\n'
    212         '        mesh local PS mode:     ACTIVE\n'
    213         '        mesh peer PS mode:      ACTIVE\n'
    214         '        mesh non-peer PS mode:  ACTIVE\n'
    215         '        authorized:     yes\n'
    216         '        authenticated:  yes\n'
    217         '        preamble:       long\n'
    218         '        WMM/WME:        yes\n'
    219         '        MFP:            yes\n'
    220         '        TDLS peer:      no\n'
    221         '        connected time: 8724 seconds\n'
    222         'Station ff:aa:bb:aa:44:55 (on mesh-5000mhz)\n'
    223         '        inactive time:  304 ms\n'
    224         '        rx bytes:       18816\n'
    225         '        rx packets:     75\n'
    226         '        tx bytes:       5386\n'
    227         '        tx packets:     21\n'
    228         '        signal:         -29 dBm\n'
    229         '        tx bitrate:     65.0 MBit/s VHT-MCS 0 80MHz short GI VHT-NSS 2\n'
    230         '        mesh llid:      0\n'
    231         '        mesh plid:      0\n'
    232         '        mesh plink:     ESTAB\n'
    233         '        mesh local PS mode:     ACTIVE\n'
    234         '        mesh peer PS mode:      ACTIVE\n'
    235         '        mesh non-peer PS mode:  ACTIVE\n'
    236         '        authorized:     yes\n'
    237         '        authenticated:  yes\n'
    238         '        preamble:       long\n'
    239         '        WMM/WME:        yes\n'
    240         '        MFP:            yes\n'
    241         '        TDLS peer:      no\n'
    242         '        connected time: 824 seconds\n')
    243 
    244     STATION_DUMP_INFORMATION_PARSED = [
    245         {'mac': 'aa:bb:cc:00:11:22', 'rssi_str': '-21 dBm', 'rssi_int': -21,
    246         'tx_bitrate': '866.7 MBit/s VHT-MCS 9 80MHz short GI VHT-NSS 2',
    247         'rx_bitrate': '650.0 MBit/s VHT-MCS 7 80MHz short GI VHT-NSS 2'},
    248         {'mac': 'dd:ee:ff:33:44:55', 'rssi_str': '-4 dBm', 'rssi_int': -4,
    249         'tx_bitrate': '866.7 MBit/s VHT-MCS 9 80MHz short GI VHT-NSS 2',
    250         'rx_bitrate': '866.7 MBit/s VHT-MCS 9 80MHz short GI VHT-NSS 2'},
    251         {'mac': 'ff:aa:bb:aa:44:55', 'rssi_str': '-29 dBm', 'rssi_int': -29,
    252         'tx_bitrate': '65.0 MBit/s VHT-MCS 0 80MHz short GI VHT-NSS 2',
    253         'rx_bitrate': None},
    254         ]
    255 
    256     STATION_DUMP_IFACE = 'mesh-5000mhz'
    257 
    258     INFO_MESH_MODE = str(
    259         'Interface wlan-2400mhz\n'
    260         '        ifindex 10\n'
    261         '        wdev 0x100000002\n'
    262         '        addr aa:bb:cc:dd:ee:ff\n'
    263         '        type mesh point\n'
    264         '        wiphy 1\n'
    265         '        channel 149 (5745 MHz), width: 80 MHz, center1: 5775 MHz\n')
    266 
    267     INFO_AP_MODE = str(
    268         'Interface wlan-2400mhz\n'
    269         '        ifindex 8\n'
    270         '        wdev 0x1\n'
    271         '        addr 00:11:22:33:44:55\n'
    272         '        ssid testap_170501151530_wsvx\n'
    273         '        type AP\n'
    274         '        wiphy 0\n'
    275         '        channel 11 (2462 MHz), width: 20 MHz, center1: 2462 MHz\n')
    276 
    277     RADIO_CONFIG_AP_MODE = {'number': 11, 'freq': 2462, 'width': 20,
    278                             'center1_freq': 2462}
    279 
    280     INFO_STA_MODE = str(
    281         'Interface wlan-2400mhz\n'
    282         '        ifindex 9\n'
    283         '        wdev 0x1\n'
    284         '        addr 44:55:66:77:88:99\n'
    285         '        type managed\n'
    286         '        wiphy 0\n'
    287         '        channel 11 (2462 MHz), width: 20 MHz, center1: 2462 MHz\n')
    288 
    289     INFO_IFACE = 'wlan-2400mhz'
    290 
    291 
    292     def verify_values(self, iw_bss_1, iw_bss_2):
    293         """Checks all of the IWBss values
    294 
    295         @param iw_bss_1: an IWBss object
    296         @param iw_bss_2: an IWBss object
    297 
    298         """
    299         self.assertEquals(iw_bss_1.bss, iw_bss_2.bss)
    300         self.assertEquals(iw_bss_1.ssid, iw_bss_2.ssid)
    301         self.assertEquals(iw_bss_1.frequency, iw_bss_2.frequency)
    302         self.assertEquals(iw_bss_1.security, iw_bss_2.security)
    303         self.assertEquals(iw_bss_1.ht, iw_bss_2.ht)
    304         self.assertEquals(iw_bss_1.signal, iw_bss_2.signal)
    305 
    306 
    307     def search_by_bss(self, scan_output, test_iw_bss):
    308         """
    309 
    310         @param scan_output: the output of the scan as a string
    311         @param test_iw_bss: an IWBss object
    312 
    313         Uses the runner to search for a network by bss.
    314         """
    315         host = self.host(scan_output + self.SCAN_TIME_OUTPUT)
    316         runner = iw_runner.IwRunner(remote_host=host)
    317         network = runner.wait_for_scan_result('wlan0', bsses=[test_iw_bss.bss])
    318         self.verify_values(test_iw_bss, network[0])
    319 
    320 
    321     def test_find_first(self):
    322         """Test with the first item in the list."""
    323         scan_output = self.HT20 + self.HT40_ABOVE
    324         self.search_by_bss(scan_output, self.HT20_IW_BSS)
    325 
    326 
    327     def test_find_last(self):
    328         """Test with the last item in the list."""
    329         scan_output = self.HT40_ABOVE + self.HT20
    330         self.search_by_bss(scan_output, self.HT20_IW_BSS)
    331 
    332 
    333     def test_find_middle(self):
    334         """Test with the middle item in the list."""
    335         scan_output = self.HT40_ABOVE + self.HT20 + self.NO_HT
    336         self.search_by_bss(scan_output, self.HT20_IW_BSS)
    337 
    338 
    339     def test_ht40_above(self):
    340         """Test with a HT40+ network."""
    341         scan_output = self.HT20 + self.HT40_ABOVE + self.NO_HT
    342         self.search_by_bss(scan_output, self.HT40_ABOVE_IW_BSS)
    343 
    344 
    345     def test_ht40_below(self):
    346         """Test with a HT40- network."""
    347         scan_output = self.HT20 + self.HT40_BELOW + self.NO_HT
    348         self.search_by_bss(scan_output, self.HT40_BELOW_IW_BSS)
    349 
    350 
    351     def test_no_ht(self):
    352         """Test with a network that doesn't have ht."""
    353         scan_output = self.HT20 + self.NO_HT + self.HT40_ABOVE
    354         self.search_by_bss(scan_output, self.NO_HT_IW_BSS)
    355 
    356 
    357     def test_hidden_ssid(self):
    358         """Test with a network with a hidden ssid."""
    359         scan_output = self.HT20 + self.HIDDEN_SSID + self.NO_HT
    360         self.search_by_bss(scan_output, self.HIDDEN_SSID_IW_BSS)
    361 
    362 
    363     def test_multiple_ssids(self):
    364         """Test with multiple networks with the same ssids."""
    365         scan_output = self.HT40_ABOVE + self.HT20 + self.NO_HT + self.HT20_2
    366         host = self.host(scan_output + self.SCAN_TIME_OUTPUT)
    367         runner = iw_runner.IwRunner(remote_host=host)
    368         networks = runner.wait_for_scan_result('wlan 0',
    369                                                ssids=[self.HT20_2_IW_BSS.ssid])
    370         for iw_bss_1, iw_bss_2 in zip([self.HT20_IW_BSS, self.HT20_2_IW_BSS],
    371                                       networks):
    372             self.verify_values(iw_bss_1, iw_bss_2)
    373 
    374 
    375     def test_station_bssid(self):
    376         """Test parsing of the bssid of a station-mode link."""
    377         host = self.host(self.STATION_LINK_INFORMATION)
    378         runner = iw_runner.IwRunner(remote_host=host)
    379         self.assertEquals(
    380             runner.get_current_bssid(self.STATION_LINK_IFACE),
    381             self.STATION_LINK_BSSID)
    382 
    383 
    384     def test_station_link_parsing(self):
    385         """Test all link keys can be parsed from station link information."""
    386         self.assertEquals(
    387             iw_runner._get_all_link_keys(self.STATION_LINK_INFORMATION),
    388             self.STATION_LINK_PARSED)
    389 
    390 
    391     def test_station_link_key(self):
    392         """Test a link key is extracted from station link information."""
    393         host = self.host(self.STATION_LINK_INFORMATION)
    394         runner = iw_runner.IwRunner(remote_host=host)
    395         self.assertEquals(
    396             runner.get_link_value(self.STATION_LINK_INFORMATION,
    397                                   iw_runner.IW_LINK_KEY_FREQUENCY),
    398             self.STATION_LINK_FREQ)
    399 
    400 
    401     def test_station_dump(self):
    402         """Test parsing of a station dump."""
    403         host = self.host(self.STATION_DUMP_INFORMATION)
    404         runner = iw_runner.IwRunner(remote_host=host)
    405         self.assertEquals(
    406             runner.get_station_dump(self.STATION_DUMP_IFACE),
    407             self.STATION_DUMP_INFORMATION_PARSED)
    408 
    409 
    410     def test_operating_mode_mesh(self):
    411         """Test mesh operating mode parsing."""
    412         host = self.host(self.INFO_MESH_MODE)
    413         runner = iw_runner.IwRunner(remote_host=host)
    414         self.assertEquals(
    415             runner.get_operating_mode(self.INFO_IFACE),
    416             iw_runner.DEV_MODE_MESH_POINT)
    417 
    418 
    419     def test_operating_mode_ap(self):
    420         """Test AP operating mode parsing."""
    421         host = self.host(self.INFO_AP_MODE)
    422         runner = iw_runner.IwRunner(remote_host=host)
    423         self.assertEquals(
    424             runner.get_operating_mode(self.INFO_IFACE),
    425             iw_runner.DEV_MODE_AP)
    426 
    427 
    428     def test_operating_mode_station(self):
    429         """Test STA operating mode parsing."""
    430         host = self.host(self.INFO_STA_MODE)
    431         runner = iw_runner.IwRunner(remote_host=host)
    432         self.assertEquals(
    433             runner.get_operating_mode(self.INFO_IFACE),
    434             iw_runner.DEV_MODE_STATION)
    435 
    436 
    437     def test_radio_information(self):
    438         """Test radio information parsing."""
    439         host = self.host(self.INFO_AP_MODE)
    440         runner = iw_runner.IwRunner(remote_host=host)
    441         self.assertEquals(
    442             runner.get_radio_config(self.INFO_IFACE),
    443             self.RADIO_CONFIG_AP_MODE)
    444 
    445 
    446 if __name__ == '__main__':
    447     unittest.main()
    448