1#!/usr/bin/env python3 2# 3# Copyright 2020 - The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17import itertools 18import os 19import time 20 21from multiprocessing import Process 22 23from acts import asserts 24from acts import context 25from acts import utils 26from acts.controllers import iperf_client 27from acts.controllers import iperf_server 28from acts.controllers import pdu 29from acts.controllers.access_point import setup_ap 30from acts.controllers.ap_lib import hostapd_constants 31from acts.controllers.ap_lib.hostapd_security import Security 32from acts.controllers.ap_lib.hostapd_utils import generate_random_password 33from acts.controllers.ap_lib.radvd import Radvd 34from acts.controllers.ap_lib import radvd_constants 35from acts.controllers.ap_lib.radvd_config import RadvdConfig 36from acts_contrib.test_utils.abstract_devices.wlan_device import create_wlan_device 37from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest 38 39# Constants, for readibility 40AP = 'ap' 41DUT = 'dut' 42SOFT = 'soft' 43HARD = 'hard' 44BAND_2G = '2g' 45BAND_5G = '5g' 46BANDS = [BAND_2G, BAND_5G] 47IPV4 = 'ipv4' 48IPV6 = 'ipv6' 49DUAL_IPV4_IPV6 = {IPV4: True, IPV6: True} 50IPV4_ONLY = {IPV4: True, IPV6: False} 51IPV6_ONLY = {IPV4: False, IPV6: True} 52INTERRUPTS = [True, False] 53DEFAULT_IPERF_TIMEOUT = 30 54 55DUT_NETWORK_CONNECTION_TIMEOUT = 60 56DUT_IP_ADDRESS_TIMEOUT = 15 57 58# Constants for Custom Reboot Tests 59ALL = 'all' 60BOTH = 'both' 61 62CUSTOM_TEST_REBOOT_DEVICES = {AP: [AP], DUT: [DUT], ALL: [AP, DUT]} 63CUSTOM_TEST_REBOOT_TYPES = {SOFT: [SOFT], HARD: [HARD], ALL: [SOFT, HARD]} 64CUSTOM_TEST_BANDS = { 65 BAND_2G: [BAND_2G], 66 BAND_5G: [BAND_5G], 67 ALL: [BAND_2G, BAND_5G] 68} 69CUSTOM_TEST_IP_VERSIONS = { 70 IPV4: [IPV4_ONLY], 71 IPV6: [IPV6_ONLY], 72 BOTH: [DUAL_IPV4_IPV6], 73 ALL: [IPV4_ONLY, IPV6_ONLY, DUAL_IPV4_IPV6] 74} 75CUSTOM_TEST_INTERRUPTS = {'true': [True], 'false': [False], ALL: [True, False]} 76 77 78def create_custom_test_name(reboot_device, reboot_type, band, ip_version, 79 interrupt, iterations): 80 """Creates custom base test name, from custom test parameters""" 81 return ('test_custom_reboot_device_%s_type_%s_band_%s_ip_version_%s%s_with' 82 '_%s_iterations_each' % 83 (reboot_device, reboot_type, band, ip_version, 84 '_interrupt' if interrupt else '', iterations)) 85 86 87def create_custom_subtest_name(settings): 88 """Creates custom subtest name, from subtest parameters.""" 89 ipv4_str = '_ipv4' if settings[IPV4] else '' 90 ipv6_str = '_ipv6' if settings[IPV6] else '' 91 return 'test_custom_%s_reboot_%s_band_%s%s%s%s%s_with_%s_iterations' % ( 92 settings['reboot_type'], settings['reboot_device'], settings['band'], 93 ipv4_str, ipv6_str, '_interrupt' if settings['interrupt'] else '', 94 '_%s' % settings['security_mode'] if settings['security_mode'] else '', 95 settings['iterations']) 96 97 98def get_test_name(settings): 99 """Returns test_name from custom generated subtest settings.""" 100 return settings['test_name'] 101 102 103class WlanRebootTest(WifiBaseTest): 104 """Tests wlan reconnects in different reboot scenarios. 105 106 Testbed Requirement: 107 * One ACTS compatible device (dut) 108 * One Whirlwind Access Point (will also serve as iperf server) 109 * One PduDevice 110 """ 111 def __init__(self, controllers): 112 WifiBaseTest.__init__(self, controllers) 113 114 def setup_class(self): 115 super().setup_class() 116 self.android_devices = getattr(self, 'android_devices', []) 117 self.fuchsia_devices = getattr(self, 'fuchsia_devices', []) 118 119 if 'dut' in self.user_params: 120 if self.user_params['dut'] == 'fuchsia_devices': 121 self.dut = create_wlan_device(self.fuchsia_devices[0]) 122 elif self.user_params['dut'] == 'android_devices': 123 self.dut = create_wlan_device(self.android_devices[0]) 124 else: 125 raise ValueError('Invalid DUT specified in config. (%s)' % 126 self.user_params['dut']) 127 else: 128 # Default is an android device, just like the other tests 129 self.dut = create_wlan_device(self.android_devices[0]) 130 131 self.access_point = self.access_points[0] 132 133 # Times (in seconds) to wait for DUT network connection and assigning an 134 # ip address to the wlan interface. 135 self.wlan_reboot_test_params = self.user_params.get( 136 'wlan_reboot_test_params', {}) 137 self.dut_network_connection_timeout = self.wlan_reboot_test_params.get( 138 'dut_network_connection_timeout', DUT_NETWORK_CONNECTION_TIMEOUT) 139 self.dut_ip_address_timeout = self.wlan_reboot_test_params.get( 140 'dut_ip_address_timeout', DUT_IP_ADDRESS_TIMEOUT) 141 self.skip_iperf = self.wlan_reboot_test_params.get('skip_iperf', False) 142 143 self.iperf_server_on_ap = None 144 self.iperf_client_on_dut = None 145 if not self.skip_iperf: 146 try: 147 self.iperf_client_on_dut = self.iperf_clients[0] 148 except AttributeError: 149 self.iperf_client_on_dut = self.dut.create_iperf_client() 150 else: 151 self.log.info( 152 'Skipping iperf throughput validation as requested by ACTS ' 153 'config') 154 155 self.router_adv_daemon = None 156 157 def setup_test(self): 158 self.access_point.stop_all_aps() 159 if self.router_adv_daemon: 160 self.router_adv_daemon.stop() 161 self.dut.wifi_toggle_state(True) 162 for ad in self.android_devices: 163 ad.droid.wakeLockAcquireBright() 164 ad.droid.wakeUpNow() 165 self.dut.disconnect() 166 self.router_adv_daemon = None 167 self.ssid = utils.rand_ascii_str(hostapd_constants.AP_SSID_LENGTH_2G) 168 169 def teardown_test(self): 170 self.access_point.stop_all_aps() 171 if self.router_adv_daemon: 172 self.router_adv_daemon.stop() 173 self.router_adv_daemon = None 174 self.dut.disconnect() 175 for ad in self.android_devices: 176 ad.droid.wakeLockRelease() 177 ad.droid.goToSleepNow() 178 self.dut.turn_location_off_and_scan_toggle_off() 179 self.dut.reset_wifi() 180 181 def on_fail(self, test_name, begin_time): 182 self.dut.take_bug_report(test_name, begin_time) 183 self.dut.get_log(test_name, begin_time) 184 185 def setup_ap(self, 186 ssid, 187 band, 188 ipv4=True, 189 ipv6=False, 190 security_mode=None, 191 password=None): 192 """Setup ap with basic config. 193 194 Args: 195 ssid: string, ssid to setup on ap 196 band: string ('2g' or '5g') of band to setup. 197 ipv4: True if using ipv4 (dhcp), else False. 198 ipv6: True if using ipv6 (radvd), else False. 199 """ 200 # TODO(fxb/63719): Add varying AP parameters 201 security_profile = None 202 if security_mode: 203 security_profile = Security(security_mode=security_mode, 204 password=password) 205 if band == BAND_2G: 206 setup_ap(access_point=self.access_point, 207 profile_name='whirlwind', 208 channel=11, 209 ssid=ssid, 210 security=security_profile) 211 elif band == BAND_5G: 212 setup_ap(access_point=self.access_point, 213 profile_name='whirlwind', 214 channel=36, 215 ssid=ssid, 216 security=security_profile) 217 218 if not ipv4: 219 self.access_point.stop_dhcp() 220 if ipv6: 221 radvd_config = RadvdConfig( 222 prefix='fd00::/64', 223 adv_send_advert=radvd_constants.ADV_SEND_ADVERT_ON, 224 adv_on_link=radvd_constants.ADV_ON_LINK_ON, 225 adv_autonomous=radvd_constants.ADV_AUTONOMOUS_ON) 226 227 if band == BAND_2G: 228 self.router_adv_daemon = Radvd(self.access_point.ssh, 229 self.access_point.wlan_2g) 230 elif band == BAND_5G: 231 self.router_adv_daemon = Radvd(self.access_point.ssh, 232 self.access_point.wlan_5g) 233 self.router_adv_daemon.start(radvd_config) 234 235 self.log.info('Network (SSID: %s) is up.' % ssid) 236 237 def wait_until_dut_gets_ipv4_addr(self, interface): 238 """Checks if device has an ipv4 private address. Sleeps 1 second between 239 retries. 240 241 Args: 242 interface: string, name of interface from which to get ipv4 address. 243 244 Raises: 245 ConnectionError, if DUT does not have an ipv4 address after all 246 timeout. 247 """ 248 self.log.info( 249 'Checking if DUT has received an ipv4 addr. Will retry for %s ' 250 'seconds.' % self.dut_ip_address_timeout) 251 timeout = time.time() + self.dut_ip_address_timeout 252 while time.time() < timeout: 253 ip_addrs = self.dut.get_interface_ip_addresses(interface) 254 255 if len(ip_addrs['ipv4_private']) > 0: 256 self.log.info('DUT has an ipv4 address: %s' % 257 ip_addrs['ipv4_private'][0]) 258 break 259 else: 260 self.log.debug( 261 'DUT does not yet have an ipv4 address...retrying in 1 ' 262 'second.') 263 time.sleep(1) 264 else: 265 raise ConnectionError('DUT failed to get an ipv4 address.') 266 267 def wait_until_dut_gets_ipv6_addr(self, interface): 268 """Checks if device has an ipv6 private local address. Sleeps 1 second 269 between retries. 270 271 Args: 272 interface: string, name of interface from which to get ipv6 address. 273 274 Raises: 275 ConnectionError, if DUT does not have an ipv6 address after all 276 timeout. 277 """ 278 self.log.info( 279 'Checking if DUT has received an ipv6 addr. Will retry for %s ' 280 'seconds.' % self.dut_ip_address_timeout) 281 timeout = time.time() + self.dut_ip_address_timeout 282 while time.time() < timeout: 283 ip_addrs = self.dut.get_interface_ip_addresses(interface) 284 if len(ip_addrs['ipv6_private_local']) > 0: 285 self.log.info('DUT has an ipv6 private local address: %s' % 286 ip_addrs['ipv6_private_local'][0]) 287 break 288 else: 289 self.log.debug( 290 'DUT does not yet have an ipv6 address...retrying in 1 ' 291 'second.') 292 time.sleep(1) 293 else: 294 raise ConnectionError('DUT failed to get an ipv6 address.') 295 296 def setup_iperf_server_on_ap(self, band): 297 """Configures iperf server based on the tests band. 298 299 Args: 300 band: string ('2g' or '5g') of band to setup. 301 """ 302 if band == BAND_2G: 303 return iperf_server.IPerfServerOverSsh( 304 self.user_params['AccessPoint'][0]['ssh_config'], 305 5201, 306 test_interface=self.access_point.wlan_2g) 307 elif band == BAND_5G: 308 return iperf_server.IPerfServerOverSsh( 309 self.user_params['AccessPoint'][0]['ssh_config'], 310 5201, 311 test_interface=self.access_point.wlan_5g) 312 313 def get_iperf_server_address(self, iperf_server_on_ap, ip_version): 314 """Retrieves the ip address of the iperf server. 315 316 Args: 317 iperf_server_on_ap: IPerfServer object, linked to AP 318 ip_version: string, the ip version (ipv4 or ipv6) 319 320 Returns: 321 String, the ip address of the iperf_server 322 """ 323 iperf_server_addresses = iperf_server_on_ap.get_interface_ip_addresses( 324 iperf_server_on_ap.test_interface) 325 if ip_version == IPV4: 326 iperf_server_ip_address = ( 327 iperf_server_addresses['ipv4_private'][0]) 328 elif ip_version == IPV6: 329 if iperf_server_addresses['ipv6_private_local']: 330 iperf_server_ip_address = ( 331 iperf_server_addresses['ipv6_private_local'][0]) 332 else: 333 iperf_server_ip_address = ( 334 '%s%%%s' % (iperf_server_addresses['ipv6_link_local'][0], 335 self.iperf_client_on_dut.test_interface)) 336 else: 337 raise ValueError('Invalid IP version: %s' % ip_version) 338 339 return iperf_server_ip_address 340 341 def verify_traffic_between_dut_and_ap(self, 342 iperf_server_on_ap, 343 iperf_client_on_dut, 344 ip_version=IPV4): 345 """Runs IPerf traffic from the iperf client (dut) and the iperf 346 server (and vice versa) and verifies traffic was able to pass 347 successfully. 348 349 Args: 350 iperf_server_on_ap: IPerfServer object, linked to AP 351 iperf_client_on_dut: IPerfClient object, linked to DUT 352 ip_version: string, the ip version (ipv4 or ipv6) 353 354 Raises: 355 ValueError, if invalid ip_version is passed. 356 ConnectionError, if traffic is not passed successfully in both 357 directions. 358 """ 359 dut_ip_addresses = self.dut.get_interface_ip_addresses( 360 iperf_client_on_dut.test_interface) 361 362 iperf_server_ip_address = self.get_iperf_server_address( 363 iperf_server_on_ap, ip_version) 364 365 self.log.info( 366 'Attempting to pass traffic from DUT to IPerf server (%s).' % 367 iperf_server_ip_address) 368 tx_file = iperf_client_on_dut.start(iperf_server_ip_address, 369 '-i 1 -t 3 -J', 370 'reboot_tx', 371 timeout=DEFAULT_IPERF_TIMEOUT) 372 tx_results = iperf_server.IPerfResult(tx_file) 373 if not tx_results.avg_receive_rate or tx_results.avg_receive_rate == 0: 374 raise ConnectionError( 375 'Failed to pass IPerf traffic from DUT to server (%s). TX ' 376 'Average Receive Rate: %s' % 377 (iperf_server_ip_address, tx_results.avg_receive_rate)) 378 else: 379 self.log.info( 380 'Success: Traffic passed from DUT to IPerf server (%s).' % 381 iperf_server_ip_address) 382 self.log.info( 383 'Attempting to pass traffic from IPerf server (%s) to DUT.' % 384 iperf_server_ip_address) 385 rx_file = iperf_client_on_dut.start(iperf_server_ip_address, 386 '-i 1 -t 3 -R -J', 387 'reboot_rx', 388 timeout=DEFAULT_IPERF_TIMEOUT) 389 rx_results = iperf_server.IPerfResult(rx_file) 390 if not rx_results.avg_receive_rate or rx_results.avg_receive_rate == 0: 391 raise ConnectionError( 392 'Failed to pass IPerf traffic from server (%s) to DUT. RX ' 393 'Average Receive Rate: %s' % 394 (iperf_server_ip_address, rx_results.avg_receive_rate)) 395 else: 396 self.log.info( 397 'Success: Traffic passed from IPerf server (%s) to DUT.' % 398 iperf_server_ip_address) 399 400 def start_dut_ping_process(self, iperf_server_on_ap, ip_version=IPV4): 401 """Creates a process that pings the AP from the DUT. 402 403 Runs in parallel for 15 seconds, so it can be interrupted by a reboot. 404 Sleeps for a few seconds to ensure pings have started. 405 406 Args: 407 iperf_server_on_ap: IPerfServer object, linked to AP 408 ip_version: string, the ip version (ipv4 or ipv6) 409 """ 410 ap_address = self.get_iperf_server_address(iperf_server_on_ap, 411 ip_version) 412 if ap_address: 413 self.log.info( 414 'Starting ping process to %s in parallel. Logs from this ' 415 'process will be suppressed, since it will be intentionally ' 416 'interrupted.' % ap_address) 417 ping_proc = Process(target=self.dut.ping, 418 args=[ap_address], 419 kwargs={'count': 15}) 420 with utils.SuppressLogOutput(): 421 ping_proc.start() 422 # Allow for a few seconds of pinging before allowing it to be 423 # interrupted. 424 time.sleep(3) 425 else: 426 raise ConnectionError('Failed to retrieve APs iperf address.') 427 428 def prepare_dut_for_reconnection(self): 429 """Perform any actions to ready DUT for reconnection. 430 431 These actions will vary depending on the DUT. eg. android devices may 432 need to be woken up, ambient devices should not require any interaction, 433 etc. 434 """ 435 self.dut.wifi_toggle_state(True) 436 for ad in self.android_devices: 437 ad.droid.wakeUpNow() 438 439 def wait_for_dut_network_connection(self, ssid): 440 """Checks if device is connected to given network. Sleeps 1 second 441 between retries. 442 443 Args: 444 ssid: string of ssid 445 Raises: 446 ConnectionError, if DUT is not connected after all timeout. 447 """ 448 self.log.info( 449 'Checking if DUT is connected to %s network. Will retry for %s ' 450 'seconds.' % (ssid, self.dut_network_connection_timeout)) 451 timeout = time.time() + self.dut_network_connection_timeout 452 while time.time() < timeout: 453 try: 454 is_connected = self.dut.is_connected(ssid=ssid) 455 except Exception as err: 456 self.log.debug('SL4* call failed. Retrying in 1 second.') 457 is_connected = False 458 finally: 459 if is_connected: 460 self.log.info('Success: DUT has connected.') 461 break 462 else: 463 self.log.debug( 464 'DUT not connected to network %s...retrying in 1 second.' 465 % ssid) 466 time.sleep(1) 467 else: 468 raise ConnectionError('DUT failed to connect to the network.') 469 470 def write_csv_time_to_reconnect(self, test_name, time_to_reconnect): 471 """Writes the time to reconnect to a csv file. 472 Args: 473 test_name: the name of the test case 474 time_to_reconnect: the time from when the rebooted device came back 475 up to when it reassociated (or 'FAIL'), if it failed to 476 reconnect. 477 """ 478 log_context = context.get_current_context() 479 log_path = os.path.join(log_context.get_base_output_path(), 480 'WlanRebootTest/') 481 csv_file_name = '%stime_to_reconnect.csv' % log_path 482 self.log.info('Writing to %s' % csv_file_name) 483 with open(csv_file_name, 'a') as csv_file: 484 csv_file.write('%s,%s\n' % (test_name, time_to_reconnect)) 485 486 def log_and_continue(self, run, time_to_reconnect=None, error=None): 487 """Writes the time to reconnect to the csv file before continuing, used 488 in stress tests runs. 489 490 Args: 491 time_to_reconnect: the time from when the rebooted device came back 492 ip to when reassociation occurred. 493 run: the run number in a looped stress tested., 494 error: string, error message to log before continuing with the test 495 """ 496 if error: 497 self.log.info( 498 'Device failed to reconnect to network %s on run %s. Error: %s' 499 % (self.ssid, run, error)) 500 self.write_csv_time_to_reconnect( 501 '%s_run_%s' % (self.test_name, run), 'FAIL') 502 503 else: 504 self.log.info( 505 'Device successfully reconnected to network %s after %s seconds' 506 ' on run %s.' % (self.ssid, time_to_reconnect, run)) 507 self.write_csv_time_to_reconnect( 508 '%s_run_%s' % (self.test_name, run), time_to_reconnect) 509 510 def run_reboot_test(self, settings): 511 """Runs a reboot test based on a given config. 512 1. Setups up a network, associates the dut, and saves the network. 513 2. Verifies the dut receives ip address(es). 514 3. Verifies traffic between DUT and AP (IPerf client and server). 515 4. Reboots (hard or soft) the device (dut or ap). 516 - If the ap was rebooted, setup the same network again. 517 5. Wait for reassociation or timeout. 518 6. If reassocation occurs: 519 - Verifies the dut receives ip address(es). 520 - Verifies traffic between DUT and AP (IPerf client and server). 521 7. Logs time to reconnect (or failure to reconnect) 522 8. If stress testing, repeats steps 4 - 7 for N iterations. 523 524 Args: 525 settings: dictionary containing the following values: 526 reboot_device: string ('dut' or 'ap') of the device to reboot. 527 reboot_type: string ('soft' or 'hard') of how to reboot the 528 reboot_device. 529 band: string ('2g' or '5g') of band to setup. 530 ipv4: True if using ipv4 (dhcp), else False. 531 ipv6: True if using ipv6 (radvd), else False. 532 533 Optional: 534 interrupt: if True, the DUT will be pinging the AP in a 535 parallel process when the reboot occurs. This is used to 536 compare reconnect times when idle to active. 537 test_name: name of the test, used when stress testing. 538 iterations: number of times to perform test, used when stress 539 testing. 540 541 Raises: 542 ValueError, if ipv4 and ipv6 are both False 543 ValueError, if band is not '2g' or '5g' 544 ValueError, if reboot_device is not 'dut' or 'ap' 545 ValueError, if reboot_type is not 'soft' or 'hard' 546 547 """ 548 iterations = settings.get('iterations', 1) 549 passed_count = 0 550 ipv4 = settings.get('ipv4', None) 551 ipv6 = settings.get('ipv6', None) 552 reboot_device = settings['reboot_device'] 553 reboot_type = settings['reboot_type'] 554 band = settings['band'] 555 security_mode = settings.get('security_mode', None) 556 password = settings.get('password', None) 557 if security_mode: 558 if security_mode.lower() == 'open': 559 security_mode = None 560 elif not password: 561 password = generate_random_password( 562 security_mode=security_mode) 563 interrupt = settings.get('interrupt', None) 564 # Skip hard reboots if no PDU present 565 asserts.skip_if( 566 reboot_type == HARD 567 and len(self.user_params.get('PduDevice', [])) < 1, 568 'Hard reboots require a PDU device.') 569 # Skip DUT reboot w/ interrupt tests, since they are not more helpful 570 # and may cause threading issues. 571 asserts.skip_if( 572 (reboot_device == DUT) and interrupt, 573 'Stream interrupts for DUT reboots are prone to threading issues ' 574 'and are not supported.') 575 576 # Validate test settings. 577 if not ipv4 and not ipv6: 578 raise ValueError('Either ipv4, ipv6, or both must be True.') 579 if reboot_device != DUT and reboot_device != AP: 580 raise ValueError('Invalid reboot device: %s' % reboot_device) 581 if reboot_type != SOFT and reboot_type != HARD: 582 raise ValueError('Invalid reboot type: %s' % reboot_type) 583 if band != BAND_2G and band != BAND_5G: 584 raise ValueError('Invalid band: %s' % band) 585 586 self.setup_ap(self.ssid, band, ipv4, ipv6, security_mode, password) 587 if not self.dut.associate( 588 self.ssid, 589 target_security=hostapd_constants. 590 SECURITY_STRING_TO_DEFAULT_TARGET_SECURITY.get(security_mode), 591 target_pwd=password): 592 raise EnvironmentError('Initial network connection failed.') 593 594 if not self.skip_iperf: 595 dut_test_interface = self.iperf_client_on_dut.test_interface 596 if ipv4: 597 self.wait_until_dut_gets_ipv4_addr(dut_test_interface) 598 if ipv6: 599 self.wait_until_dut_gets_ipv6_addr(dut_test_interface) 600 601 self.iperf_server_on_ap = self.setup_iperf_server_on_ap(band) 602 self.iperf_server_on_ap.start() 603 604 if ipv4: 605 self.verify_traffic_between_dut_and_ap( 606 self.iperf_server_on_ap, self.iperf_client_on_dut) 607 if ipv6: 608 self.verify_traffic_between_dut_and_ap( 609 self.iperf_server_on_ap, 610 self.iperf_client_on_dut, 611 ip_version=IPV6) 612 613 # Looping reboots for stress testing 614 for run in range(iterations): 615 run += 1 616 self.log.info('Starting run %s of %s.' % (run, iterations)) 617 618 # Ping from DUT to AP during AP reboot 619 if interrupt: 620 if ipv4: 621 self.start_dut_ping_process(self.iperf_server_on_ap) 622 if ipv6: 623 self.start_dut_ping_process(self.iperf_server_on_ap, 624 ip_version=IPV6) 625 626 # DUT reboots 627 if reboot_device == DUT: 628 if not self.skip_iperf and type( 629 self.iperf_client_on_dut 630 ) == iperf_client.IPerfClientOverSsh: 631 self.iperf_client_on_dut.close_ssh() 632 if reboot_type == SOFT: 633 self.dut.device.reboot() 634 elif reboot_type == HARD: 635 self.dut.hard_power_cycle(self.pdu_devices) 636 637 # AP reboots 638 elif reboot_device == AP: 639 if reboot_type == SOFT: 640 self.log.info('Cleanly stopping ap.') 641 self.access_point.stop_all_aps() 642 elif reboot_type == HARD: 643 if not self.skip_iperf: 644 self.iperf_server_on_ap.close_ssh() 645 self.access_point.hard_power_cycle(self.pdu_devices) 646 self.setup_ap(self.ssid, band, ipv4, ipv6, security_mode, 647 password) 648 649 self.prepare_dut_for_reconnection() 650 uptime = time.time() 651 try: 652 self.wait_for_dut_network_connection(self.ssid) 653 time_to_reconnect = time.time() - uptime 654 655 if not self.skip_iperf: 656 if ipv4: 657 self.wait_until_dut_gets_ipv4_addr(dut_test_interface) 658 if ipv6: 659 self.wait_until_dut_gets_ipv6_addr(dut_test_interface) 660 661 self.iperf_server_on_ap.start() 662 663 if ipv4: 664 self.verify_traffic_between_dut_and_ap( 665 self.iperf_server_on_ap, self.iperf_client_on_dut) 666 if ipv6: 667 self.verify_traffic_between_dut_and_ap( 668 self.iperf_server_on_ap, 669 self.iperf_client_on_dut, 670 ip_version=IPV6) 671 672 except ConnectionError as err: 673 self.log_and_continue(run, error=err) 674 else: 675 passed_count += 1 676 self.log_and_continue(run, time_to_reconnect=time_to_reconnect) 677 678 if passed_count == iterations: 679 asserts.explicit_pass( 680 'Test Summary: device successfully reconnected to network %s ' 681 '%s/%s times.' % (self.ssid, passed_count, iterations)) 682 683 else: 684 asserts.fail( 685 'Test Summary: device failed reconnection test. Reconnected to ' 686 'network %s %s/%s times.' % 687 (self.ssid, passed_count, iterations)) 688 689# Open Network DUT Soft Reboots (requires a DUT and Whirlwind) 690 691 def test_soft_reboot_dut_ipv4_2g(self): 692 settings = { 693 'reboot_device': DUT, 694 'reboot_type': SOFT, 695 'ipv4': True, 696 'band': BAND_2G, 697 } 698 self.run_reboot_test(settings) 699 700 def test_soft_reboot_dut_ipv4_5g(self): 701 settings = { 702 'reboot_device': DUT, 703 'reboot_type': SOFT, 704 'ipv4': True, 705 'band': BAND_5G, 706 } 707 self.run_reboot_test(settings) 708 709 def test_soft_reboot_dut_ipv6_2g(self): 710 settings = { 711 'reboot_device': DUT, 712 'reboot_type': SOFT, 713 'ipv6': True, 714 'band': BAND_2G, 715 } 716 self.run_reboot_test(settings) 717 718 def test_soft_reboot_dut_ipv6_5g(self): 719 settings = { 720 'reboot_device': DUT, 721 'reboot_type': SOFT, 722 'ipv6': True, 723 'band': BAND_5G, 724 } 725 self.run_reboot_test(settings) 726 727 def test_soft_reboot_dut_ipv4_ipv6_2g(self): 728 settings = { 729 'reboot_device': DUT, 730 'reboot_type': SOFT, 731 'ipv4': True, 732 'ipv6': True, 733 'band': BAND_2G, 734 } 735 self.run_reboot_test(settings) 736 737 def test_soft_reboot_dut_ipv4_ipv6_5g(self): 738 settings = { 739 'reboot_device': DUT, 740 'reboot_type': SOFT, 741 'ipv4': True, 742 'ipv6': True, 743 'band': BAND_5G, 744 } 745 self.run_reboot_test(settings) 746 747# Open Network DUT Hard Reboots (requires a DUT, Whirlwind, and PDU) 748 749 def test_hard_reboot_dut_ipv4_2g(self): 750 settings = { 751 'reboot_device': DUT, 752 'reboot_type': HARD, 753 'ipv4': True, 754 'band': BAND_2G, 755 } 756 self.run_reboot_test(settings) 757 758 def test_hard_reboot_dut_ipv4_5g(self): 759 settings = { 760 'reboot_device': DUT, 761 'reboot_type': HARD, 762 'ipv4': True, 763 'band': BAND_5G, 764 } 765 self.run_reboot_test(settings) 766 767 def test_hard_reboot_dut_ipv6_2g(self): 768 settings = { 769 'reboot_device': DUT, 770 'reboot_type': HARD, 771 'ipv6': True, 772 'band': BAND_2G, 773 } 774 self.run_reboot_test(settings) 775 776 def test_hard_reboot_dut_ipv6_5g(self): 777 settings = { 778 'reboot_device': DUT, 779 'reboot_type': HARD, 780 'ipv6': True, 781 'band': BAND_5G, 782 } 783 self.run_reboot_test(settings) 784 785 def test_hard_reboot_dut_ipv4_ipv6_2g(self): 786 settings = { 787 'reboot_device': DUT, 788 'reboot_type': HARD, 789 'ipv4': True, 790 'ipv6': True, 791 'band': BAND_2G, 792 } 793 self.run_reboot_test(settings) 794 795 def test_hard_reboot_dut_ipv4_ipv6_5g(self): 796 settings = { 797 'reboot_device': DUT, 798 'reboot_type': HARD, 799 'ipv4': True, 800 'ipv6': True, 801 'band': BAND_5G, 802 } 803 self.run_reboot_test(settings) 804 805# Open Network AP Soft Reboots (requires a DUT and Whirlwind) 806 807 def test_soft_reboot_ap_ipv4_2g(self): 808 settings = { 809 'reboot_device': AP, 810 'reboot_type': SOFT, 811 'ipv4': True, 812 'band': BAND_2G, 813 } 814 self.run_reboot_test(settings) 815 816 def test_soft_reboot_ap_ipv4_5g(self): 817 settings = { 818 'reboot_device': AP, 819 'reboot_type': SOFT, 820 'ipv4': True, 821 'band': BAND_5G, 822 } 823 self.run_reboot_test(settings) 824 825 def test_soft_reboot_ap_ipv6_2g(self): 826 settings = { 827 'reboot_device': AP, 828 'reboot_type': SOFT, 829 'ipv6': True, 830 'band': BAND_2G, 831 } 832 self.run_reboot_test(settings) 833 834 def test_soft_reboot_ap_ipv6_5g(self): 835 settings = { 836 'reboot_device': AP, 837 'reboot_type': SOFT, 838 'ipv6': True, 839 'band': BAND_5G, 840 } 841 self.run_reboot_test(settings) 842 843 def test_soft_reboot_ap_ipv4_ipv6_2g(self): 844 settings = { 845 'reboot_device': AP, 846 'reboot_type': SOFT, 847 'ipv4': True, 848 'ipv6': True, 849 'band': BAND_2G, 850 } 851 self.run_reboot_test(settings) 852 853 def test_soft_reboot_ap_ipv4_ipv6_5g(self): 854 settings = { 855 'reboot_device': AP, 856 'reboot_type': SOFT, 857 'ipv4': True, 858 'ipv6': True, 859 'band': BAND_5G, 860 } 861 self.run_reboot_test(settings) 862 863# Open Network AP Soft Reboots (requires a DUT and Whirlwind) with traffic 864# interruption. 865 866 def test_soft_reboot_ap_ipv4_2g_interrupt(self): 867 settings = { 868 'reboot_device': AP, 869 'reboot_type': SOFT, 870 'ipv4': True, 871 'band': BAND_2G, 872 'interrupt': True 873 } 874 self.run_reboot_test(settings) 875 876 def test_soft_reboot_ap_ipv4_5g_interrupt(self): 877 settings = { 878 'reboot_device': AP, 879 'reboot_type': SOFT, 880 'ipv4': True, 881 'band': BAND_5G, 882 'interrupt': True 883 } 884 self.run_reboot_test(settings) 885 886 def test_soft_reboot_ap_ipv6_2g_interrupt(self): 887 settings = { 888 'reboot_device': AP, 889 'reboot_type': SOFT, 890 'ipv6': True, 891 'band': BAND_2G, 892 'interrupt': True 893 } 894 self.run_reboot_test(settings) 895 896 def test_soft_reboot_ap_ipv6_5g_interrupt(self): 897 settings = { 898 'reboot_device': AP, 899 'reboot_type': SOFT, 900 'ipv6': True, 901 'band': BAND_5G, 902 'interrupt': True 903 } 904 self.run_reboot_test(settings) 905 906 def test_soft_reboot_ap_ipv4_ipv6_2g_interrupt(self): 907 settings = { 908 'reboot_device': AP, 909 'reboot_type': SOFT, 910 'ipv4': True, 911 'ipv6': True, 912 'band': BAND_2G, 913 'interrupt': True 914 } 915 self.run_reboot_test(settings) 916 917 def test_soft_reboot_ap_ipv4_ipv6_5g_interrupt(self): 918 settings = { 919 'reboot_device': AP, 920 'reboot_type': SOFT, 921 'ipv4': True, 922 'ipv6': True, 923 'band': BAND_5G, 924 'interrupt': True 925 } 926 self.run_reboot_test(settings) 927 928# Open Network AP Hard Reboot (requires a DUT, Whirlwind, and PDU) 929 930 def test_hard_reboot_ap_ipv4_2g(self): 931 settings = { 932 'reboot_device': AP, 933 'reboot_type': HARD, 934 'ipv4': True, 935 'band': BAND_2G, 936 } 937 self.run_reboot_test(settings) 938 939 def test_hard_reboot_ap_ipv4_5g(self): 940 settings = { 941 'reboot_device': AP, 942 'reboot_type': HARD, 943 'ipv4': True, 944 'band': BAND_5G, 945 } 946 self.run_reboot_test(settings) 947 948 def test_hard_reboot_ap_ipv6_2g(self): 949 settings = { 950 'reboot_device': AP, 951 'reboot_type': HARD, 952 'ipv6': True, 953 'band': BAND_2G, 954 } 955 self.run_reboot_test(settings) 956 957 def test_hard_reboot_ap_ipv6_5g(self): 958 settings = { 959 'reboot_device': AP, 960 'reboot_type': HARD, 961 'ipv6': True, 962 'band': BAND_5G, 963 } 964 self.run_reboot_test(settings) 965 966 def test_hard_reboot_ap_ipv4_ipv6_2g(self): 967 settings = { 968 'reboot_device': AP, 969 'reboot_type': HARD, 970 'ipv4': True, 971 'ipv6': True, 972 'band': BAND_2G, 973 } 974 self.run_reboot_test(settings) 975 976 def test_hard_reboot_ap_ipv4_ipv6_5g(self): 977 settings = { 978 'reboot_device': AP, 979 'reboot_type': HARD, 980 'ipv4': True, 981 'ipv6': True, 982 'band': BAND_5G, 983 } 984 self.run_reboot_test(settings) 985 986# Open Network AP Hard Reboot (requires a DUT, Whirlwind, and PDU) with traffic 987# interruptions. 988 989 def test_hard_reboot_ap_ipv4_2g_interrupt(self): 990 settings = { 991 'reboot_device': AP, 992 'reboot_type': HARD, 993 'ipv4': True, 994 'band': BAND_2G, 995 'interrupt': True 996 } 997 self.run_reboot_test(settings) 998 999 def test_hard_reboot_ap_ipv4_5g_interrupt(self): 1000 settings = { 1001 'reboot_device': AP, 1002 'reboot_type': HARD, 1003 'ipv4': True, 1004 'band': BAND_5G, 1005 'interrupt': True 1006 } 1007 self.run_reboot_test(settings) 1008 1009 def test_hard_reboot_ap_ipv6_2g_interrupt(self): 1010 settings = { 1011 'reboot_device': AP, 1012 'reboot_type': HARD, 1013 'ipv6': True, 1014 'band': BAND_2G, 1015 'interrupt': True 1016 } 1017 self.run_reboot_test(settings) 1018 1019 def test_hard_reboot_ap_ipv6_5g_interrupt(self): 1020 settings = { 1021 'reboot_device': AP, 1022 'reboot_type': HARD, 1023 'ipv6': True, 1024 'band': BAND_5G, 1025 'interrupt': True 1026 } 1027 self.run_reboot_test(settings) 1028 1029 def test_hard_reboot_ap_ipv4_ipv6_2g_interrupt(self): 1030 settings = { 1031 'reboot_device': AP, 1032 'reboot_type': HARD, 1033 'ipv4': True, 1034 'ipv6': True, 1035 'band': BAND_2G, 1036 'interrupt': True 1037 } 1038 self.run_reboot_test(settings) 1039 1040 def test_hard_reboot_ap_ipv4_ipv6_5g_interrupt(self): 1041 settings = { 1042 'reboot_device': AP, 1043 'reboot_type': HARD, 1044 'ipv4': True, 1045 'ipv6': True, 1046 'band': BAND_5G, 1047 'interrupt': True 1048 } 1049 self.run_reboot_test(settings) 1050 1051# WPA2 DUT Soft Reboots (requires a DUT and Whirlwind) 1052 1053 def test_soft_reboot_dut_ipv4_2g_wpa2(self): 1054 settings = { 1055 'reboot_device': DUT, 1056 'reboot_type': SOFT, 1057 'ipv4': True, 1058 'band': BAND_2G, 1059 'security_mode': hostapd_constants.WPA2_STRING 1060 } 1061 self.run_reboot_test(settings) 1062 1063 def test_soft_reboot_dut_ipv4_5g_wpa2(self): 1064 settings = { 1065 'reboot_device': DUT, 1066 'reboot_type': SOFT, 1067 'ipv4': True, 1068 'band': BAND_5G, 1069 'security_mode': hostapd_constants.WPA2_STRING 1070 } 1071 self.run_reboot_test(settings) 1072 1073 def test_soft_reboot_dut_ipv6_2g_wpa2(self): 1074 settings = { 1075 'reboot_device': DUT, 1076 'reboot_type': SOFT, 1077 'ipv6': True, 1078 'band': BAND_2G, 1079 'security_mode': hostapd_constants.WPA2_STRING 1080 } 1081 self.run_reboot_test(settings) 1082 1083 def test_soft_reboot_dut_ipv6_5g_wpa2(self): 1084 settings = { 1085 'reboot_device': DUT, 1086 'reboot_type': SOFT, 1087 'ipv6': True, 1088 'band': BAND_5G, 1089 'security_mode': hostapd_constants.WPA2_STRING 1090 } 1091 self.run_reboot_test(settings) 1092 1093 def test_soft_reboot_dut_ipv4_ipv6_2g_wpa2(self): 1094 settings = { 1095 'reboot_device': DUT, 1096 'reboot_type': SOFT, 1097 'ipv4': True, 1098 'ipv6': True, 1099 'band': BAND_2G, 1100 'security_mode': hostapd_constants.WPA2_STRING 1101 } 1102 self.run_reboot_test(settings) 1103 1104 def test_soft_reboot_dut_ipv4_ipv6_5g_wpa2(self): 1105 settings = { 1106 'reboot_device': DUT, 1107 'reboot_type': SOFT, 1108 'ipv4': True, 1109 'ipv6': True, 1110 'band': BAND_5G, 1111 'security_mode': hostapd_constants.WPA2_STRING 1112 } 1113 self.run_reboot_test(settings) 1114 1115# WPA2 Network DUT Hard Reboots (requires a DUT, Whirlwind, and PDU) 1116 1117 def test_hard_reboot_dut_ipv4_2g_wpa2(self): 1118 settings = { 1119 'reboot_device': DUT, 1120 'reboot_type': HARD, 1121 'ipv4': True, 1122 'band': BAND_2G, 1123 'security_mode': hostapd_constants.WPA2_STRING 1124 } 1125 self.run_reboot_test(settings) 1126 1127 def test_hard_reboot_dut_ipv4_5g_wpa2(self): 1128 settings = { 1129 'reboot_device': DUT, 1130 'reboot_type': HARD, 1131 'ipv4': True, 1132 'band': BAND_5G, 1133 'security_mode': hostapd_constants.WPA2_STRING 1134 } 1135 self.run_reboot_test(settings) 1136 1137 def test_hard_reboot_dut_ipv6_2g_wpa2(self): 1138 settings = { 1139 'reboot_device': DUT, 1140 'reboot_type': HARD, 1141 'ipv6': True, 1142 'band': BAND_2G, 1143 'security_mode': hostapd_constants.WPA2_STRING 1144 } 1145 self.run_reboot_test(settings) 1146 1147 def test_hard_reboot_dut_ipv6_5g_wpa2(self): 1148 settings = { 1149 'reboot_device': DUT, 1150 'reboot_type': HARD, 1151 'ipv6': True, 1152 'band': BAND_5G, 1153 'security_mode': hostapd_constants.WPA2_STRING 1154 } 1155 self.run_reboot_test(settings) 1156 1157 def test_hard_reboot_dut_ipv4_ipv6_2g_wpa2(self): 1158 settings = { 1159 'reboot_device': DUT, 1160 'reboot_type': HARD, 1161 'ipv4': True, 1162 'ipv6': True, 1163 'band': BAND_2G, 1164 'security_mode': hostapd_constants.WPA2_STRING 1165 } 1166 self.run_reboot_test(settings) 1167 1168 def test_hard_reboot_dut_ipv4_ipv6_5g_wpa2(self): 1169 settings = { 1170 'reboot_device': DUT, 1171 'reboot_type': HARD, 1172 'ipv4': True, 1173 'ipv6': True, 1174 'band': BAND_5G, 1175 'security_mode': hostapd_constants.WPA2_STRING 1176 } 1177 self.run_reboot_test(settings) 1178 1179# WPA2 Network AP Soft Reboots (requires a DUT and Whirlwind) 1180 1181 def test_soft_reboot_ap_ipv4_2g_wpa2(self): 1182 settings = { 1183 'reboot_device': AP, 1184 'reboot_type': SOFT, 1185 'ipv4': True, 1186 'band': BAND_2G, 1187 'security_mode': hostapd_constants.WPA2_STRING 1188 } 1189 self.run_reboot_test(settings) 1190 1191 def test_soft_reboot_ap_ipv4_5g_wpa2(self): 1192 settings = { 1193 'reboot_device': AP, 1194 'reboot_type': SOFT, 1195 'ipv4': True, 1196 'band': BAND_5G, 1197 'security_mode': hostapd_constants.WPA2_STRING 1198 } 1199 self.run_reboot_test(settings) 1200 1201 def test_soft_reboot_ap_ipv6_2g_wpa2(self): 1202 settings = { 1203 'reboot_device': AP, 1204 'reboot_type': SOFT, 1205 'ipv6': True, 1206 'band': BAND_2G, 1207 'security_mode': hostapd_constants.WPA2_STRING 1208 } 1209 self.run_reboot_test(settings) 1210 1211 def test_soft_reboot_ap_ipv6_5g_wpa2(self): 1212 settings = { 1213 'reboot_device': AP, 1214 'reboot_type': SOFT, 1215 'ipv6': True, 1216 'band': BAND_5G, 1217 'security_mode': hostapd_constants.WPA2_STRING 1218 } 1219 self.run_reboot_test(settings) 1220 1221 def test_soft_reboot_ap_ipv4_ipv6_2g_wpa2(self): 1222 settings = { 1223 'reboot_device': AP, 1224 'reboot_type': SOFT, 1225 'ipv4': True, 1226 'ipv6': True, 1227 'band': BAND_2G, 1228 'security_mode': hostapd_constants.WPA2_STRING 1229 } 1230 self.run_reboot_test(settings) 1231 1232 def test_soft_reboot_ap_ipv4_ipv6_5g_wpa2(self): 1233 settings = { 1234 'reboot_device': AP, 1235 'reboot_type': SOFT, 1236 'ipv4': True, 1237 'ipv6': True, 1238 'band': BAND_5G, 1239 'security_mode': hostapd_constants.WPA2_STRING 1240 } 1241 self.run_reboot_test(settings) 1242 1243# WPA2 Network AP Hard Reboot (requires a DUT, Whirlwind, and PDU) 1244 1245 def test_hard_reboot_ap_ipv4_2g_wpa2(self): 1246 settings = { 1247 'reboot_device': AP, 1248 'reboot_type': HARD, 1249 'ipv4': True, 1250 'band': BAND_2G, 1251 'security_mode': hostapd_constants.WPA2_STRING 1252 } 1253 self.run_reboot_test(settings) 1254 1255 def test_hard_reboot_ap_ipv4_5g_wpa2(self): 1256 settings = { 1257 'reboot_device': AP, 1258 'reboot_type': HARD, 1259 'ipv4': True, 1260 'band': BAND_5G, 1261 'security_mode': hostapd_constants.WPA2_STRING 1262 } 1263 self.run_reboot_test(settings) 1264 1265 def test_hard_reboot_ap_ipv6_2g_wpa2(self): 1266 settings = { 1267 'reboot_device': AP, 1268 'reboot_type': HARD, 1269 'ipv6': True, 1270 'band': BAND_2G, 1271 'security_mode': hostapd_constants.WPA2_STRING 1272 } 1273 self.run_reboot_test(settings) 1274 1275 def test_hard_reboot_ap_ipv6_5g_wpa2(self): 1276 settings = { 1277 'reboot_device': AP, 1278 'reboot_type': HARD, 1279 'ipv6': True, 1280 'band': BAND_5G, 1281 'security_mode': hostapd_constants.WPA2_STRING 1282 } 1283 self.run_reboot_test(settings) 1284 1285 def test_hard_reboot_ap_ipv4_ipv6_2g_wpa2(self): 1286 settings = { 1287 'reboot_device': AP, 1288 'reboot_type': HARD, 1289 'ipv4': True, 1290 'ipv6': True, 1291 'band': BAND_2G, 1292 'security_mode': hostapd_constants.WPA2_STRING 1293 } 1294 self.run_reboot_test(settings) 1295 1296 def test_hard_reboot_ap_ipv4_ipv6_5g_wpa2(self): 1297 settings = { 1298 'reboot_device': AP, 1299 'reboot_type': HARD, 1300 'ipv4': True, 1301 'ipv6': True, 1302 'band': BAND_5G, 1303 'security_mode': hostapd_constants.WPA2_STRING 1304 } 1305 self.run_reboot_test(settings) 1306 1307# WPA3 DUT Soft Reboots (requires a DUT and Whirlwind) 1308 1309 def test_soft_reboot_dut_ipv4_2g_wpa3(self): 1310 settings = { 1311 'reboot_device': DUT, 1312 'reboot_type': SOFT, 1313 'ipv4': True, 1314 'band': BAND_2G, 1315 'security_mode': hostapd_constants.WPA3_STRING 1316 } 1317 self.run_reboot_test(settings) 1318 1319 def test_soft_reboot_dut_ipv4_5g_wpa3(self): 1320 settings = { 1321 'reboot_device': DUT, 1322 'reboot_type': SOFT, 1323 'ipv4': True, 1324 'band': BAND_5G, 1325 'security_mode': hostapd_constants.WPA3_STRING 1326 } 1327 self.run_reboot_test(settings) 1328 1329 def test_soft_reboot_dut_ipv6_2g_wpa3(self): 1330 settings = { 1331 'reboot_device': DUT, 1332 'reboot_type': SOFT, 1333 'ipv6': True, 1334 'band': BAND_2G, 1335 'security_mode': hostapd_constants.WPA3_STRING 1336 } 1337 self.run_reboot_test(settings) 1338 1339 def test_soft_reboot_dut_ipv6_5g_wpa3(self): 1340 settings = { 1341 'reboot_device': DUT, 1342 'reboot_type': SOFT, 1343 'ipv6': True, 1344 'band': BAND_5G, 1345 'security_mode': hostapd_constants.WPA3_STRING 1346 } 1347 self.run_reboot_test(settings) 1348 1349 def test_soft_reboot_dut_ipv4_ipv6_2g_wpa3(self): 1350 settings = { 1351 'reboot_device': DUT, 1352 'reboot_type': SOFT, 1353 'ipv4': True, 1354 'ipv6': True, 1355 'band': BAND_2G, 1356 'security_mode': hostapd_constants.WPA3_STRING 1357 } 1358 self.run_reboot_test(settings) 1359 1360 def test_soft_reboot_dut_ipv4_ipv6_5g_wpa3(self): 1361 settings = { 1362 'reboot_device': DUT, 1363 'reboot_type': SOFT, 1364 'ipv4': True, 1365 'ipv6': True, 1366 'band': BAND_5G, 1367 'security_mode': hostapd_constants.WPA3_STRING 1368 } 1369 self.run_reboot_test(settings) 1370 1371# WPA3 Network DUT Hard Reboots (requires a DUT, Whirlwind, and PDU) 1372 1373 def test_hard_reboot_dut_ipv4_2g_wpa3(self): 1374 settings = { 1375 'reboot_device': DUT, 1376 'reboot_type': HARD, 1377 'ipv4': True, 1378 'band': BAND_2G, 1379 'security_mode': hostapd_constants.WPA3_STRING 1380 } 1381 self.run_reboot_test(settings) 1382 1383 def test_hard_reboot_dut_ipv4_5g_wpa3(self): 1384 settings = { 1385 'reboot_device': DUT, 1386 'reboot_type': HARD, 1387 'ipv4': True, 1388 'band': BAND_5G, 1389 'security_mode': hostapd_constants.WPA3_STRING 1390 } 1391 self.run_reboot_test(settings) 1392 1393 def test_hard_reboot_dut_ipv6_2g_wpa3(self): 1394 settings = { 1395 'reboot_device': DUT, 1396 'reboot_type': HARD, 1397 'ipv6': True, 1398 'band': BAND_2G, 1399 'security_mode': hostapd_constants.WPA3_STRING 1400 } 1401 self.run_reboot_test(settings) 1402 1403 def test_hard_reboot_dut_ipv6_5g_wpa3(self): 1404 settings = { 1405 'reboot_device': DUT, 1406 'reboot_type': HARD, 1407 'ipv6': True, 1408 'band': BAND_5G, 1409 'security_mode': hostapd_constants.WPA3_STRING 1410 } 1411 self.run_reboot_test(settings) 1412 1413 def test_hard_reboot_dut_ipv4_ipv6_2g_wpa3(self): 1414 settings = { 1415 'reboot_device': DUT, 1416 'reboot_type': HARD, 1417 'ipv4': True, 1418 'ipv6': True, 1419 'band': BAND_2G, 1420 'security_mode': hostapd_constants.WPA3_STRING 1421 } 1422 self.run_reboot_test(settings) 1423 1424 def test_hard_reboot_dut_ipv4_ipv6_5g_wpa3(self): 1425 settings = { 1426 'reboot_device': DUT, 1427 'reboot_type': HARD, 1428 'ipv4': True, 1429 'ipv6': True, 1430 'band': BAND_5G, 1431 'security_mode': hostapd_constants.WPA3_STRING 1432 } 1433 self.run_reboot_test(settings) 1434 1435# WPA3 Network AP Soft Reboots (requires a DUT and Whirlwind) 1436 1437 def test_soft_reboot_ap_ipv4_2g_wpa3(self): 1438 settings = { 1439 'reboot_device': AP, 1440 'reboot_type': SOFT, 1441 'ipv4': True, 1442 'band': BAND_2G, 1443 'security_mode': hostapd_constants.WPA3_STRING 1444 } 1445 self.run_reboot_test(settings) 1446 1447 def test_soft_reboot_ap_ipv4_5g_wpa3(self): 1448 settings = { 1449 'reboot_device': AP, 1450 'reboot_type': SOFT, 1451 'ipv4': True, 1452 'band': BAND_5G, 1453 'security_mode': hostapd_constants.WPA3_STRING 1454 } 1455 self.run_reboot_test(settings) 1456 1457 def test_soft_reboot_ap_ipv6_2g_wpa3(self): 1458 settings = { 1459 'reboot_device': AP, 1460 'reboot_type': SOFT, 1461 'ipv6': True, 1462 'band': BAND_2G, 1463 'security_mode': hostapd_constants.WPA3_STRING 1464 } 1465 self.run_reboot_test(settings) 1466 1467 def test_soft_reboot_ap_ipv6_5g_wpa3(self): 1468 settings = { 1469 'reboot_device': AP, 1470 'reboot_type': SOFT, 1471 'ipv6': True, 1472 'band': BAND_5G, 1473 'security_mode': hostapd_constants.WPA3_STRING 1474 } 1475 self.run_reboot_test(settings) 1476 1477 def test_soft_reboot_ap_ipv4_ipv6_2g_wpa3(self): 1478 settings = { 1479 'reboot_device': AP, 1480 'reboot_type': SOFT, 1481 'ipv4': True, 1482 'ipv6': True, 1483 'band': BAND_2G, 1484 'security_mode': hostapd_constants.WPA3_STRING 1485 } 1486 self.run_reboot_test(settings) 1487 1488 def test_soft_reboot_ap_ipv4_ipv6_5g_wpa3(self): 1489 settings = { 1490 'reboot_device': AP, 1491 'reboot_type': SOFT, 1492 'ipv4': True, 1493 'ipv6': True, 1494 'band': BAND_5G, 1495 'security_mode': hostapd_constants.WPA3_STRING 1496 } 1497 self.run_reboot_test(settings) 1498 1499 1500# WPA3 Network AP Hard Reboot (requires a DUT, Whirlwind, and PDU) 1501 1502 def test_hard_reboot_ap_ipv4_2g_wpa3(self): 1503 settings = { 1504 'reboot_device': AP, 1505 'reboot_type': HARD, 1506 'ipv4': True, 1507 'band': BAND_2G, 1508 'security_mode': hostapd_constants.WPA3_STRING 1509 } 1510 self.run_reboot_test(settings) 1511 1512 def test_hard_reboot_ap_ipv4_5g_wpa3(self): 1513 settings = { 1514 'reboot_device': AP, 1515 'reboot_type': HARD, 1516 'ipv4': True, 1517 'band': BAND_5G, 1518 'security_mode': hostapd_constants.WPA3_STRING 1519 } 1520 self.run_reboot_test(settings) 1521 1522 def test_hard_reboot_ap_ipv6_2g_wpa3(self): 1523 settings = { 1524 'reboot_device': AP, 1525 'reboot_type': HARD, 1526 'ipv6': True, 1527 'band': BAND_2G, 1528 'security_mode': hostapd_constants.WPA3_STRING 1529 } 1530 self.run_reboot_test(settings) 1531 1532 def test_hard_reboot_ap_ipv6_5g_wpa3(self): 1533 settings = { 1534 'reboot_device': AP, 1535 'reboot_type': HARD, 1536 'ipv6': True, 1537 'band': BAND_5G, 1538 'security_mode': hostapd_constants.WPA3_STRING 1539 } 1540 self.run_reboot_test(settings) 1541 1542 def test_hard_reboot_ap_ipv4_ipv6_2g_wpa3(self): 1543 settings = { 1544 'reboot_device': AP, 1545 'reboot_type': HARD, 1546 'ipv4': True, 1547 'ipv6': True, 1548 'band': BAND_2G, 1549 'security_mode': hostapd_constants.WPA3_STRING 1550 } 1551 self.run_reboot_test(settings) 1552 1553 def test_hard_reboot_ap_ipv4_ipv6_5g_wpa3(self): 1554 settings = { 1555 'reboot_device': AP, 1556 'reboot_type': HARD, 1557 'ipv4': True, 1558 'ipv6': True, 1559 'band': BAND_5G, 1560 'security_mode': hostapd_constants.WPA3_STRING 1561 } 1562 self.run_reboot_test(settings) 1563 1564 def test_custom_reboots(self): 1565 """Used to create custom reboot tests from ACTS config. Can be 1566 individual tests or permutation sets (i.e. setting "all" for a 1567 test param will run a test with every permutation). 1568 1569 Parameters: 1570 reboot_device: string - "ap", "dut", or "all" 1571 reboot_type: string - "soft", "hard", or "all" 1572 band: string, "2g" - "5g", "all" 1573 ip_version: string - "ipv4", "ipv6", "both", or "all" 1574 interrupt: bool - whether to have traffic flowing at reboot 1575 security_modes: optional, string or list - "open", "wep", "wpa", 1576 "wpa2", "wpa/wpa2", "wpa3", "wpa2/wpa3" 1577 iterations: int - number of iterations for each test 1578 test_name: string (optional, one will be generated) 1579 1580 Example: 1581 "wlan_reboot_test_params": { 1582 "test_custom_reboots": [ 1583 { 1584 "test_name": "test_custom_soft_reboot_dut_2g_dual_ip_open", 1585 "reboot_device": "dut", 1586 "reboot_type": "soft", 1587 "band": "2g", 1588 "ip_version": "both" 1589 }, 1590 { 1591 "reboot_device": "all", 1592 "reboot_type": "hard", 1593 "band": "all", 1594 "ip_version": ipv4", 1595 "security_modes": "wpa2", 1596 "iterations": 10 1597 }, 1598 { 1599 "test_name": "test_custom_hard_reboot_dut_open_and_wpa3", 1600 "reboot_device": "dut", 1601 "reboot_type": "hard", 1602 "band": "5g", 1603 "ip_version": "ipv4", 1604 "security_modes": ["open", "wpa3"] 1605 } 1606 ] 1607 } 1608 1609 The first example runs a single DUT soft reboot test with a 2.4GHz 1610 network and dual ipv4/ipv6. 1611 1612 The second example runs 4 tests, each with 10 iterations. It runs hard 1613 reboots with ipv4 for the permutations of DUT/AP and 2.4GHz/5GHz. 1614 1615 The third example runs two tests, both hard reboots of the DUT with 5g 1616 and ipv4 only, one with open security and one with WPA3. 1617 """ 1618 asserts.skip_if( 1619 'test_custom_reboots' not in self.wlan_reboot_test_params, 1620 'No custom reboots provided in ACTS config.') 1621 test_list = [] 1622 for test in self.wlan_reboot_test_params['test_custom_reboots']: 1623 # Ensure required params are present 1624 try: 1625 reboot_device = test['reboot_device'].lower() 1626 reboot_type = test['reboot_type'].lower() 1627 band = test['band'].lower() 1628 ip_version = test['ip_version'].lower() 1629 except KeyError as err: 1630 raise AttributeError( 1631 'Must provide reboot_type, reboot_device, ip_version, and ' 1632 'band (optionally interrupt and iterations) in custom test ' 1633 'config. See test_custom_reboots docstring for details. ' 1634 'Err: %s' % err) 1635 security_modes = test.get('security_modes', 'open') 1636 interrupt = str(test.get('interrupt', False)).lower() 1637 iterations = test.get('iterations', 1) 1638 1639 # Validate parameters and convert to lists (for permutations) 1640 try: 1641 reboot_devices = CUSTOM_TEST_REBOOT_DEVICES[reboot_device] 1642 reboot_types = CUSTOM_TEST_REBOOT_TYPES[reboot_type] 1643 bands = CUSTOM_TEST_BANDS[band] 1644 ip_versions = CUSTOM_TEST_IP_VERSIONS[ip_version] 1645 interrupts = CUSTOM_TEST_INTERRUPTS[interrupt] 1646 if isinstance(security_modes, str): 1647 security_modes = [security_modes] 1648 1649 except KeyError as err: 1650 raise AttributeError( 1651 'Invalid custom test parameter provided. Err: %s' % err) 1652 1653 # Generate base test name if one is not present 1654 if 'test_name' in test: 1655 test_name = test['test_name'] 1656 else: 1657 test_name = create_custom_test_name(reboot_device, reboot_type, 1658 band, ip_version, 1659 interrupt, iterations) 1660 1661 test_settings = { 1662 'test_name': test_name, 1663 'reboot_devices': reboot_devices, 1664 'reboot_types': reboot_types, 1665 'bands': bands, 1666 'ip_versions': ip_versions, 1667 'security_modes': security_modes, 1668 'interrupts': interrupts, 1669 'iterations': iterations 1670 } 1671 test_list.append(test_settings) 1672 1673 # Run all permutations of the test settings 1674 self.run_generated_testcases(self.run_custom_test_permutations, 1675 test_list, 1676 name_func=get_test_name) 1677 1678 def run_custom_test_permutations(self, settings): 1679 """Runs a custom reboot subtest for each permutation of the provided 1680 test parameters.""" 1681 test_list = [] 1682 for combination in itertools.product( 1683 settings['reboot_devices'], 1684 settings['reboot_types'], 1685 settings['bands'], 1686 settings['ip_versions'], 1687 settings['security_modes'], 1688 settings['interrupts'], 1689 ): 1690 test_settings = { 1691 'reboot_device': combination[0], 1692 'reboot_type': combination[1], 1693 'band': combination[2], 1694 'ipv4': combination[3][IPV4], 1695 'ipv6': combination[3][IPV6], 1696 'security_mode': combination[4], 1697 'interrupt': combination[5], 1698 'iterations': settings['iterations'] 1699 } 1700 test_list.append(test_settings) 1701 self.run_generated_testcases(self.run_reboot_test, 1702 test_list, 1703 name_func=create_custom_subtest_name) 1704