1#!/usr/bin/env python3 2# 3# Copyright (C) 2019 The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); you may not 6# use this file except in compliance with the License. You may obtain a copy of 7# 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, WITHOUT 13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14# License for the specific language governing permissions and limitations under 15# the License. 16""" 17Script for testing WiFi recovery after rebooting the AP. 18 19Override default number of iterations using the following 20parameter in the test config file. 21 22"beacon_loss_test_iterations": "5" 23""" 24 25import time 26 27from acts import asserts 28from acts import signals 29from acts import utils 30from acts.controllers.access_point import setup_ap 31from acts.controllers.ap_lib import hostapd_constants 32 33from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest 34from acts_contrib.test_utils.abstract_devices.wlan_device import create_wlan_device 35from acts.utils import rand_ascii_str 36 37 38class BeaconLossTest(WifiBaseTest): 39 # Default number of test iterations here. 40 # Override using parameter in config file. 41 # Eg: "beacon_loss_test_iterations": "10" 42 num_of_iterations = 5 43 44 # Time to wait for AP to startup 45 wait_ap_startup_s = 15 46 47 # Default wait time in seconds for the AP radio to turn back on 48 wait_to_connect_after_ap_txon_s = 5 49 50 # Time to wait for device to disconnect after AP radio of 51 wait_after_ap_txoff_s = 15 52 53 # Time to wait for device to complete connection setup after 54 # given an associate command 55 wait_client_connection_setup_s = 15 56 57 def setup_class(self): 58 super().setup_class() 59 self.ssid = rand_ascii_str(10) 60 if 'dut' in self.user_params: 61 if self.user_params['dut'] == 'fuchsia_devices': 62 self.dut = create_wlan_device(self.fuchsia_devices[0]) 63 elif self.user_params['dut'] == 'android_devices': 64 self.dut = create_wlan_device(self.android_devices[0]) 65 else: 66 raise ValueError('Invalid DUT specified in config. (%s)' % 67 self.user_params['dut']) 68 else: 69 # Default is an android device, just like the other tests 70 self.dut = create_wlan_device(self.android_devices[0]) 71 self.access_point = self.access_points[0] 72 self.num_of_iterations = int( 73 self.user_params.get("beacon_loss_test_iterations", 74 self.num_of_iterations)) 75 self.in_use_interface = None 76 77 def teardown_test(self): 78 self.dut.disconnect() 79 self.dut.reset_wifi() 80 # ensure radio is on, in case the test failed while the radio was off 81 self.access_point.iwconfig.ap_iwconfig(self.in_use_interface, 82 "txpower on") 83 self.download_ap_logs() 84 self.access_point.stop_all_aps() 85 86 def on_fail(self, test_name, begin_time): 87 super().on_fail(test_name, begin_time) 88 self.access_point.stop_all_aps() 89 90 def beacon_loss(self, channel): 91 setup_ap(access_point=self.access_point, 92 profile_name='whirlwind', 93 channel=channel, 94 ssid=self.ssid) 95 time.sleep(self.wait_ap_startup_s) 96 if channel > 14: 97 self.in_use_interface = self.access_point.wlan_5g 98 else: 99 self.in_use_interface = self.access_point.wlan_2g 100 101 # TODO(b/144505723): [ACTS] update BeaconLossTest.py to handle client 102 # roaming, saved networks, etc. 103 self.log.info("sending associate command for ssid %s", self.ssid) 104 self.dut.associate(target_ssid=self.ssid) 105 106 asserts.assert_true(self.dut.is_connected(), 'Failed to connect.') 107 108 time.sleep(self.wait_client_connection_setup_s) 109 110 for _ in range(0, self.num_of_iterations): 111 # Turn off AP radio 112 self.log.info("turning off radio") 113 self.access_point.iwconfig.ap_iwconfig(self.in_use_interface, 114 "txpower off") 115 time.sleep(self.wait_after_ap_txoff_s) 116 117 # Did we disconnect from AP? 118 asserts.assert_false(self.dut.is_connected(), 119 'Failed to disconnect.') 120 121 # Turn on AP radio 122 self.log.info("turning on radio") 123 self.access_point.iwconfig.ap_iwconfig(self.in_use_interface, 124 "txpower on") 125 time.sleep(self.wait_to_connect_after_ap_txon_s) 126 127 # Tell the client to connect 128 self.log.info("sending associate command for ssid %s" % self.ssid) 129 self.dut.associate(target_ssid=self.ssid) 130 time.sleep(self.wait_client_connection_setup_s) 131 132 # Did we connect back to WiFi? 133 asserts.assert_true(self.dut.is_connected(), 134 'Failed to connect back.') 135 136 return True 137 138 def test_beacon_loss_2g(self): 139 self.beacon_loss(channel=hostapd_constants.AP_DEFAULT_CHANNEL_2G) 140 141 def test_beacon_loss_5g(self): 142 self.beacon_loss(channel=hostapd_constants.AP_DEFAULT_CHANNEL_5G) 143