1#!/usr/bin/env python3.4 2# 3# Copyright 2018 - 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 pprint 19import queue 20import time 21 22import acts.base_test 23import acts.signals as signals 24import acts_contrib.test_utils.wifi.wifi_test_utils as wutils 25import acts.utils 26 27from acts import asserts 28from acts.test_decorators import test_tracker_info 29from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest 30 31WifiEnums = wutils.WifiEnums 32# Timeout used for crash recovery. 33RECOVERY_TIMEOUT = 15 34WIFICOND_KILL_SHELL_COMMAND = "killall wificond" 35SUPPLICANT_KILL_SHELL_COMMAND = "killall wpa_supplicant" 36WIFI_VENDOR_EXT_HAL_DAEMON = "vendor.google.wifi_ext@1.0-service-vendor" 37WIFI_VENDOR_EXT_HAL_DAEMON_PREFIX = "vendor.google.wifi_ext@" 38WIFI_VENDOR_EXT_HAL_DAEMON_KILL_SHELL_COMMAND = "killall vendor.google.wifi_ext@1.0-service-vendor" 39WIFI_VENDOR_HAL_DAEMON = "android.hardware.wifi@1.0-service" 40WIFI_VENDOR_HAL_DAEMON_KILL_SHELL_COMMAND = "killall android.hardware.wifi@1.0-service" 41 42class WifiCrashTest(WifiBaseTest): 43 """Crash Tests for wifi stack. 44 45 Test Bed Requirement: 46 * One Android device 47 * One Wi-Fi network visible to the device. 48 """ 49 def __init__(self, configs): 50 super().__init__(configs) 51 self.enable_packet_log = True 52 53 def setup_class(self): 54 super().setup_class() 55 56 self.dut = self.android_devices[0] 57 wutils.wifi_test_device_init(self.dut) 58 req_params = [] 59 opt_param = ["reference_networks"] 60 self.unpack_userparams( 61 req_param_names=req_params, opt_param_names=opt_param) 62 63 if "AccessPoint" in self.user_params: 64 self.legacy_configure_ap_and_start() 65 elif "OpenWrtAP" in self.user_params: 66 self.configure_openwrt_ap_and_start(wpa_network=True) 67 68 asserts.assert_true( 69 len(self.reference_networks) > 0, 70 "Need at least one reference network with psk.") 71 self.network = self.reference_networks[0]["2g"] 72 73 def setup_test(self): 74 super().setup_test() 75 self.dut.droid.wakeLockAcquireBright() 76 self.dut.droid.wakeUpNow() 77 wutils.wifi_toggle_state(self.dut, True) 78 79 def teardown_test(self): 80 super().teardown_test() 81 self.dut.droid.wakeLockRelease() 82 self.dut.droid.goToSleepNow() 83 wutils.reset_wifi(self.dut) 84 85 def teardown_class(self): 86 if "AccessPoint" in self.user_params: 87 del self.user_params["reference_networks"] 88 89 """Helper Functions""" 90 91 """Tests""" 92 @test_tracker_info(uuid="b87fd23f-9bfc-406b-a5b2-17ce6be6c780") 93 def test_wifi_framework_crash_reconnect(self): 94 """Connect to a network, crash framework, then ensure 95 we connect back to the previously connected network. 96 97 Steps: 98 1. Connect to a network. 99 2. Restart framework. 100 3. Reconnect to the previous network. 101 102 """ 103 wutils.wifi_connect(self.dut, self.network, num_of_tries=3) 104 # Restart framework 105 self.log.info("Crashing framework") 106 self.dut.restart_runtime() 107 # We won't get the disconnect broadcast because framework crashed. 108 # wutils.wait_for_disconnect(self.dut) 109 time.sleep(RECOVERY_TIMEOUT) 110 wifi_info = self.dut.droid.wifiGetConnectionInfo() 111 if wifi_info[WifiEnums.SSID_KEY] != self.network[WifiEnums.SSID_KEY]: 112 raise signals.TestFailure("Device did not connect to the" 113 " network after crashing framework.") 114 115 @test_tracker_info(uuid="33f9e4f6-29b8-4116-8f9b-5b13d93b4bcb") 116 def test_wifi_cond_crash_reconnect(self): 117 """Connect to a network, crash wificond, then ensure 118 we connect back to the previously connected network. 119 120 Steps: 121 1. Connect to a network. 122 2. Crash wificond. 123 3. Ensure we get a disconnect. 124 4. Ensure we reconnect to the previous network. 125 126 """ 127 wutils.wifi_connect(self.dut, self.network, num_of_tries=3) 128 # Restart wificond 129 self.log.info("Crashing wificond") 130 self.dut.adb.shell(WIFICOND_KILL_SHELL_COMMAND) 131 wutils.wait_for_disconnect(self.dut) 132 time.sleep(RECOVERY_TIMEOUT) 133 wifi_info = self.dut.droid.wifiGetConnectionInfo() 134 if wifi_info[WifiEnums.SSID_KEY] != self.network[WifiEnums.SSID_KEY]: 135 raise signals.TestFailure("Device did not connect to the" 136 " network after crashing wificond.") 137 138 @test_tracker_info(uuid="463e3d7b-b0b7-4843-b83b-5613a71ae2ac") 139 def test_wifi_vendorhal_crash_reconnect(self): 140 """Connect to a network, crash wifi HAL, then ensure 141 we connect back to the previously connected network. 142 143 Steps: 144 1. Connect to a network. 145 2. Crash wifi HAL. 146 3. Ensure we get a disconnect. 147 4. Ensure we reconnect to the previous network. 148 149 """ 150 wutils.wifi_connect(self.dut, self.network, num_of_tries=3) 151 # Restart wificond 152 self.log.info("Crashing wifi HAL") 153 daemon_search_cmd = "ps -ef | grep %s" % WIFI_VENDOR_EXT_HAL_DAEMON_PREFIX 154 result = self.dut.adb.shell(daemon_search_cmd) or "" 155 if WIFI_VENDOR_EXT_HAL_DAEMON in result: 156 self.log.info("Crashing wifi ext HAL") 157 self.dut.adb.shell(WIFI_VENDOR_EXT_HAL_DAEMON_KILL_SHELL_COMMAND) 158 else: 159 self.log.info("Crashing wifi HAL") 160 self.dut.adb.shell(WIFI_VENDOR_HAL_DAEMON_KILL_SHELL_COMMAND) 161 wutils.wait_for_disconnect(self.dut) 162 time.sleep(RECOVERY_TIMEOUT) 163 wifi_info = self.dut.droid.wifiGetConnectionInfo() 164 if wifi_info[WifiEnums.SSID_KEY] != self.network[WifiEnums.SSID_KEY]: 165 raise signals.TestFailure("Device did not connect to the" 166 " network after crashing wifi HAL.") 167 168 @test_tracker_info(uuid="7c5cd1fc-8f8d-494c-beaf-4eb61b48917b") 169 def test_wpa_supplicant_crash_reconnect(self): 170 """Connect to a network, crash wpa_supplicant, then ensure 171 we connect back to the previously connected network. 172 173 Steps: 174 1. Connect to a network. 175 2. Crash wpa_supplicant. 176 3. Ensure we get a disconnect. 177 4. Ensure we reconnect to the previous network. 178 179 """ 180 wutils.wifi_connect(self.dut, self.network, num_of_tries=3) 181 # Restart wificond 182 self.log.info("Crashing wpa_supplicant") 183 self.dut.adb.shell(SUPPLICANT_KILL_SHELL_COMMAND) 184 wutils.wait_for_disconnect(self.dut) 185 time.sleep(RECOVERY_TIMEOUT) 186 wifi_info = self.dut.droid.wifiGetConnectionInfo() 187 if wifi_info[WifiEnums.SSID_KEY] != self.network[WifiEnums.SSID_KEY]: 188 raise signals.TestFailure("Device did not connect to the" 189 " network after crashing wpa_supplicant.") 190