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