Home | History | Annotate | Download | only in ap_configurators
      1 # Copyright (c) 2012 The Chromium 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 
      5 """Unit test for ap_configurator."""
      6 
      7 import os
      8 import sys
      9 import unittest
     10 
     11 # Define autotest_lib MAGIC!
     12 sys.path.append(os.path.join(
     13                 os.path.dirname(os.path.abspath(__file__)), '..', '..', '..'))
     14 from utils import common
     15 
     16 from autotest_lib.server.cros import host_lock_manager
     17 import ap_batch_locker
     18 import ap_spec
     19 
     20 
     21 class ConfiguratorTest(unittest.TestCase):
     22     """This test needs to be run against the UI interface of a real AP.
     23 
     24     The purpose of this test is to act as a basic acceptance test when
     25     developing a new AP configurator class.  Use this to make sure all core
     26     functionality is implemented.
     27 
     28     This test does not verify that everything works for ALL APs. It only
     29     tests against the AP specified below in AP_SPEC.
     30 
     31     Launch this unit test from outside chroot:
     32       $ cd ~/chromeos/src/third_party/autotest/files
     33       $ python utils/unittest_suite.py \
     34         server.cros.ap_configurators.ap_configurator_test --debug
     35 
     36     To run a single test, from outside chroot, e.g.
     37       $ cd ~/chromeos/src/third_party/autotest/files/\
     38            server/cros/ap_configurators
     39       $ python -m unittest ap_configurator_test.ConfiguratorTest.test_ssid
     40     """
     41 
     42     # Enter the hostname of the AP to test against
     43     AP_SPEC = ap_spec.APSpec(hostnames=['chromeos3-row4-rack1-host9'])
     44 
     45     # Do not actually power up the AP, assume it is on.
     46     OVERRIDE_POWER = True
     47 
     48     @classmethod
     49     def setUpClass(self):
     50         lock_manager = host_lock_manager.HostLockManager()
     51         self.batch_locker = ap_batch_locker.ApBatchLocker(lock_manager,
     52                             self.AP_SPEC, hostname_matching_only=True)
     53         ap_batch = self.batch_locker.get_ap_batch(batch_size=1)
     54         if not ap_batch:
     55             raise RuntimeError('Unable to lock AP %r' % self.AP_SPEC)
     56         self.ap = ap_batch[0]
     57         # Use a development webdriver server
     58         self.ap.webdriver_port = 9516
     59         if not self.OVERRIDE_POWER:
     60             print('Powering up the AP (this may take a minute...)')
     61             self.ap._power_up_router()
     62         else:
     63             print('Assuming AP is not, skipping power on.')
     64             self.ap.router_on = True
     65 
     66 
     67     @classmethod
     68     def tearDownClass(self):
     69         if self.batch_locker:
     70             self.batch_locker.unlock_aps()
     71         if not self.OVERRIDE_POWER:
     72             self.ap._power_down_router()
     73 
     74 
     75     def setUp(self):
     76         # All tests have to have a band pre-set.
     77         bands = self.ap.get_supported_bands()
     78         self.ap.set_band(bands[0]['band'])
     79         self.ap.apply_settings()
     80 
     81 
     82     def disabled_security_on_all_bands(self):
     83         """Disables security on all available bands."""
     84         for band in self.ap.get_supported_bands():
     85             self.ap.set_band(band['band'])
     86             self.ap.set_security_disabled()
     87             self.ap.apply_settings()
     88 
     89 
     90     def return_non_n_mode_pair(self):
     91         """Returns a mode and band that do not contain wireless mode N.
     92 
     93         Wireless N does not support several wifi security modes.  In order
     94         to test they can be configured that makes it easy to select an
     95         available compatible mode.
     96         """
     97         # Make this return something that does not contain N
     98         return_dict = {}
     99         for mode in self.ap.get_supported_modes():
    100             return_dict['band'] = mode['band']
    101             for mode_type in mode['modes']:
    102                 if (mode_type & ap_spec.MODE_N) != ap_spec.MODE_N:
    103                     return_dict['mode'] = mode_type
    104                 else:
    105                     raise RuntimeError('No modes without MODE_N')
    106         return return_dict
    107 
    108 
    109     def test_make_no_changes(self):
    110         """Test saving with no changes doesn't throw an error."""
    111         # Set to a known state.
    112         self.ap.set_radio(enabled=True)
    113         self.ap.apply_settings()
    114         # Set the same setting again.
    115         self.ap.set_radio(enabled=True)
    116         self.ap.apply_settings()
    117 
    118 
    119     def test_radio(self):
    120         """Test we can adjust the radio setting."""
    121         self.ap.set_radio(enabled=True)
    122         self.ap.apply_settings()
    123         self.ap.set_radio(enabled=False)
    124         self.ap.apply_settings()
    125 
    126 
    127     def test_channel(self):
    128         """Test adjusting the channel."""
    129         supported_bands = self.ap.get_supported_bands()
    130         for band in supported_bands:
    131             self.ap.set_band(band['band'])
    132             # Set to the second available channel
    133             self.ap.set_channel(band['channels'][1])
    134             self.ap.apply_settings()
    135 
    136 
    137     def test_visibility(self):
    138         """Test adjusting the visibility."""
    139         if not self.ap.is_visibility_supported():
    140             return
    141         self.ap.set_visibility(False)
    142         self.ap.apply_settings()
    143         self.ap.set_visibility(True)
    144         self.ap.apply_settings()
    145 
    146 
    147     def test_ssid(self):
    148         """Test setting the SSID."""
    149         bands_info = self.ap.get_supported_bands()
    150         self.assertTrue(bands_info, msg='Invalid band sent.')
    151         ssid = 'ssid2'
    152         for bands in bands_info:
    153             band = bands['band']
    154             if band == ap_spec.BAND_5GHZ:
    155                 ssid = 'ssid5'
    156             self.ap.set_band(band)
    157             self.ap.set_ssid(ssid)
    158             self.ap.apply_settings()
    159         self.assertEqual(ssid, self.ap.ssid)
    160 
    161 
    162     def test_band(self):
    163         """Test switching the band."""
    164         self.ap.set_band(ap_spec.BAND_2GHZ)
    165         self.ap.apply_settings()
    166         self.ap.set_band(ap_spec.BAND_5GHZ)
    167         self.ap.apply_settings()
    168 
    169 
    170     def test_switching_bands_and_change_settings(self):
    171         """Test switching between bands and change settings for each band."""
    172         bands_info = self.ap.get_supported_bands()
    173         self.assertTrue(bands_info, msg='Invalid band sent.')
    174         bands_set = [d['band'] for d in bands_info]
    175         for band in bands_set:
    176             self.ap.set_band(band)
    177             self.ap.set_ssid('pqrstu_' + band)
    178             if self.ap.is_visibility_supported():
    179                 self.ap.set_visibility(True)
    180             if self.ap.is_security_mode_supported(ap_spec.SECURITY_TYPE_WEP):
    181                 self.ap.set_security_wep('test2',
    182                                          ap_spec.WEP_AUTHENTICATION_OPEN)
    183             self.ap.apply_settings()
    184 
    185 
    186     def test_invalid_security(self):
    187         """Test an exception is thrown for an invalid configuration."""
    188         self.disabled_security_on_all_bands()
    189         for mode in self.ap.get_supported_modes():
    190             if not ap_spec.MODE_N in mode['modes']:
    191                 return
    192         if not self.ap.is_security_mode_supported(ap_spec.SECURITY_TYPE_WEP):
    193             return
    194         self.ap.set_mode(ap_spec.MODE_N)
    195         self.ap.set_security_wep('77777', ap_spec.WEP_AUTHENTICATION_OPEN)
    196         try:
    197             self.ap.apply_settings()
    198         except RuntimeError, e:
    199             self.ap.driver.close()
    200             message = str(e)
    201             if message.find('no handler was specified') != -1:
    202                 self.fail('Subclass did not handle an alert.')
    203             return
    204         self.fail('An exception should have been thrown but was not.')
    205 
    206 
    207     def test_security_wep(self):
    208         """Test configuring WEP security."""
    209         if not self.ap.is_security_mode_supported(ap_spec.SECURITY_TYPE_WEP):
    210             return
    211         for mode in self.ap.get_supported_modes():
    212             self.ap.set_band(mode['band'])
    213             for mode_type in mode['modes']:
    214                 if mode_type & ap_spec.MODE_N != ap_spec.MODE_N:
    215                     self.ap.set_mode(mode_type)
    216                     self.ap.set_security_wep('45678',
    217                                              ap_spec.WEP_AUTHENTICATION_OPEN)
    218                     self.ap.apply_settings()
    219                     self.ap.set_security_wep('90123',
    220                                              ap_spec.WEP_AUTHENTICATION_SHARED)
    221                     self.ap.apply_settings()
    222 
    223 
    224     def test_priority_sets(self):
    225         """Test that commands are run in the right priority."""
    226         self.ap.set_radio(enabled=False)
    227         if self.ap.is_visibility_supported():
    228             self.ap.set_visibility(True)
    229         self.ap.set_ssid('prioritytest')
    230         self.ap.apply_settings()
    231 
    232 
    233     def test_security_and_general_settings(self):
    234         """Test updating settings that are general and security related."""
    235         self.disabled_security_on_all_bands()
    236         try:
    237             good_pair = self.return_non_n_mode_pair()
    238             self.ap.set_radio(enabled=False)
    239             self.ap.set_band(good_pair['band'])
    240             self.ap.set_mode(good_pair['mode'])
    241         except RuntimeError:
    242             # AP does not support modes without MODE_N
    243             return
    244         if self.ap.is_visibility_supported():
    245             self.ap.set_visibility(True)
    246         if self.ap.is_security_mode_supported(ap_spec.SECURITY_TYPE_WEP):
    247             self.ap.set_security_wep('88888', ap_spec.WEP_AUTHENTICATION_OPEN)
    248         self.ap.set_ssid('secgentest')
    249         self.ap.apply_settings()
    250 
    251 
    252     def test_modes(self):
    253         """Tests switching modes."""
    254         # Some security settings won't work with some modes
    255         self.ap.set_security_disabled()
    256         self.ap.apply_settings()
    257         modes_info = self.ap.get_supported_modes()
    258         self.assertTrue(modes_info,
    259                         msg='Returned an invalid mode list.  Is this method'
    260                         ' implemented?')
    261         for band_modes in modes_info:
    262             self.ap.set_band(band_modes['band'])
    263             for mode in band_modes['modes']:
    264                 self.ap.set_mode(mode)
    265                 self.ap.apply_settings()
    266 
    267 
    268     def test_modes_with_band(self):
    269         """Tests switching modes that support adjusting the band."""
    270         # Different bands and security options conflict.  Disable security for
    271         # this test.
    272         self.disabled_security_on_all_bands()
    273         # Check if we support self.kModeN across multiple bands
    274         modes_info = self.ap.get_supported_modes()
    275         n_bands = []
    276         for band_modes in modes_info:
    277             if ap_spec.MODE_N in band_modes['modes']:
    278                 n_bands.append(band_modes['band'])
    279         if len(n_bands) > 1:
    280             for n_band in n_bands:
    281                 self.ap.set_mode(ap_spec.MODE_N, band=n_band)
    282                 self.ap.apply_settings()
    283 
    284 
    285     def test_fast_cycle_security(self):
    286         """Mini stress for changing security settings rapidly."""
    287         self.disabled_security_on_all_bands()
    288         self.ap.set_radio(enabled=True)
    289         if self.ap.is_security_mode_supported(ap_spec.SECURITY_TYPE_WEP):
    290             self.ap.set_security_wep('77777', ap_spec.WEP_AUTHENTICATION_OPEN)
    291         if self.ap.is_security_mode_supported(ap_spec.SECURITY_TYPE_DISABLED):
    292             self.ap.set_security_disabled()
    293         if self.ap.is_security_mode_supported(ap_spec.SECURITY_TYPE_WPAPSK):
    294             self.ap.set_security_wpapsk(ap_spec.SECURITY_TYPE_WPAPSK,
    295                                         'qwertyuiolkjhgfsdfg')
    296         self.ap.apply_settings()
    297 
    298 
    299     def test_cycle_security(self):
    300         """Test switching between different security settings."""
    301         self.disabled_security_on_all_bands()
    302         try:
    303             good_pair = self.return_non_n_mode_pair()
    304             self.ap.set_radio(enabled=True)
    305             self.ap.set_band(good_pair['band'])
    306             self.ap.set_mode(good_pair['mode'])
    307         except RuntimeError:
    308             # AP does not support modes without MODE_N
    309             return
    310         if self.ap.is_security_mode_supported(ap_spec.SECURITY_TYPE_WEP):
    311             self.ap.set_security_wep('77777', ap_spec.WEP_AUTHENTICATION_OPEN)
    312         self.ap.apply_settings()
    313         if self.ap.is_security_mode_supported(ap_spec.SECURITY_TYPE_DISABLED):
    314             self.ap.set_security_disabled()
    315         self.ap.apply_settings()
    316         if self.ap.is_security_mode_supported(ap_spec.SECURITY_TYPE_WPA2PSK):
    317             self.ap.set_security_wpapsk(ap_spec.SECURITY_TYPE_WPA2PSK,
    318                                         'qwertyuiolkjhgfsdfg')
    319         self.ap.apply_settings()
    320 
    321 
    322     def test_actions_when_radio_disabled(self):
    323         """Test making changes when the radio is disabled."""
    324         self.disabled_security_on_all_bands()
    325         try:
    326             good_pair = self.return_non_n_mode_pair()
    327             self.ap.set_radio(enabled=False)
    328             self.ap.set_band(good_pair['band'])
    329             self.ap.set_mode(good_pair['mode'])
    330         except RuntimeError:
    331             # AP does not support modes without MODE_N
    332             return
    333         self.ap.apply_settings()
    334         if self.ap.is_security_mode_supported(ap_spec.SECURITY_TYPE_WEP):
    335             self.ap.set_security_wep('77777', ap_spec.WEP_AUTHENTICATION_OPEN)
    336         self.ap.set_radio(enabled=False)
    337         self.ap.apply_settings()
    338 
    339 
    340     def test_configuring_with_ap_spec(self):
    341         """Test configuring the AP using an APSpec."""
    342         spec = ap_spec.APSpec()
    343         self.ap.set_using_ap_spec(spec)
    344         self.ap.apply_settings()
    345 
    346 
    347     def test_power_cycle_router(self):
    348         """Test powering the ap down and back up again."""
    349         self.ap.power_cycle_router_up()
    350 
    351 
    352 if __name__ == '__main__':
    353     unittest.main()
    354