1 #!/usr/bin/env python3.4 2 # 3 # Copyright 2016 - 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 17 import itertools 18 import pprint 19 import queue 20 import time 21 22 import acts.base_test 23 import acts.signals 24 import acts.test_utils.wifi.wifi_test_utils as wutils 25 26 from acts import asserts 27 28 WifiEnums = wutils.WifiEnums 29 WifiEventNames = wutils.WifiEventNames 30 31 class WifiManagerTest(acts.base_test.BaseTestClass): 32 33 def setup_class(self): 34 self.dut = self.android_devices[0] 35 wutils.wifi_test_device_init(self.dut) 36 req_params = ( 37 "iot_networks", 38 "open_network", 39 "iperf_server_address", 40 "tdls_models", 41 "energy_info_models" 42 ) 43 self.unpack_userparams(req_params) 44 asserts.assert_true(len(self.iot_networks) > 0, 45 "Need at least one iot network with psk.") 46 asserts.assert_true(wutils.wifi_toggle_state(self.dut, True), 47 "Failed to turn on wifi before tests.") 48 self.iot_networks = self.iot_networks + [self.open_network] 49 self.iperf_server = self.iperf_servers[0] 50 51 def setup_test(self): 52 self.dut.droid.wakeLockAcquireBright() 53 self.dut.droid.wakeUpNow() 54 self.iperf_server.start() 55 56 def teardown_test(self): 57 self.dut.droid.wakeLockRelease() 58 self.dut.droid.goToSleepNow() 59 wutils.reset_wifi(self.dut) 60 self.iperf_server.stop() 61 62 def on_fail(self, test_name, begin_time): 63 self.dut.cat_adb_log(test_name, begin_time) 64 65 """Helper Functions""" 66 def connect_to_wifi_network_with_password(self, params): 67 """Connection logic for open and psk wifi networks. 68 69 Logic steps are 70 1. Connect to the network. 71 2. Run iperf traffic. 72 73 Args: 74 params: A tuple of network info and AndroidDevice object. 75 76 Returns: 77 True if successful, False otherwise. 78 """ 79 result = False 80 wait_time = 5 81 network, ad = params 82 droid = ad.droid 83 ed = ad.ed 84 SSID = network[WifiEnums.SSID_KEY] 85 try: 86 ed.clear_all_events() 87 wutils.start_wifi_connection_scan(ad) 88 droid.wifiStartTrackingStateChange() 89 asserts.assert_true(droid.wifiConnect(network), 90 "wifi connect returned false.") 91 connect_result = ed.pop_event(WifiEventNames.WIFI_CONNECTED) 92 self.log.debug(connect_result) 93 result = connect_result['data'][WifiEnums.SSID_KEY] == SSID 94 if result: 95 self.log.info("Starting iperf traffic through {}".format(SSID)) 96 time.sleep(wait_time) 97 port_arg = "-p {}".format(self.iperf_server.port) 98 result, data = ad.run_iperf_client(self.iperf_server_address, 99 port_arg) 100 self.log.debug(pprint.pformat(data)) 101 except queue.Empty: 102 self.log.exception("Failed to connect to {}".format(SSID)) 103 finally: 104 droid.wifiStopTrackingStateChange() 105 return result 106 107 def run_iperf(self, iperf_args): 108 if "iperf_server_address" not in self.user_params: 109 self.log.error(("Missing iperf_server_address. " 110 "Provide one in config.")) 111 else: 112 iperf_addr = self.user_params["iperf_server_address"] 113 self.log.info("Running iperf client.") 114 result, data = self.dut.run_iperf_client(iperf_addr, 115 iperf_args) 116 self.log.debug(data) 117 118 def run_iperf_rx_tx(self, time, omit=10): 119 args = "-p {} -t {} -O 10".format(self.iperf_server.port, time, omit) 120 self.log.info("Running iperf client {}".format(args)) 121 self.run_iperf(args) 122 args = "-p {} -t {} -O 10 -R".format(self.iperf_server.port, time, omit) 123 self.log.info("Running iperf client {}".format(args)) 124 self.run_iperf(args) 125 126 """Tests""" 127 def test_toggle_state(self): 128 """Test toggling wifi""" 129 self.log.debug("Going from on to off.") 130 asserts.assert_true(wutils.wifi_toggle_state(self.dut, False), 131 "Failed to turn wifi off.") 132 self.log.debug("Going from off to on.") 133 asserts.assert_true(wutils.wifi_toggle_state(self.dut, True), 134 "Failed to turn wifi on.") 135 136 def test_toggle_with_screen(self): 137 """Test toggling wifi with screen on/off""" 138 wait_time = 5 139 self.log.debug("Screen from off to on.") 140 self.dut.droid.wakeLockAcquireBright() 141 self.dut.droid.wakeUpNow() 142 time.sleep(wait_time) 143 self.log.debug("Going from on to off.") 144 try: 145 asserts.assert_true(wutils.wifi_toggle_state(self.dut, False), 146 "Failed to turn wifi off.") 147 time.sleep(wait_time) 148 self.log.debug("Going from off to on.") 149 asserts.assert_true(wutils.wifi_toggle_state(self.dut, True), 150 "Failed to turn wifi on.") 151 finally: 152 self.dut.droid.wakeLockRelease() 153 time.sleep(wait_time) 154 self.dut.droid.goToSleepNow() 155 156 def test_scan(self): 157 """Test wifi connection scan can start and find expected networks.""" 158 wutils.wifi_toggle_state(self.dut, True) 159 self.log.debug("Start regular wifi scan.") 160 wutils.start_wifi_connection_scan(self.dut) 161 wifi_results = self.dut.droid.wifiGetScanResults() 162 self.log.debug("Scan results: %s" % wifi_results) 163 ssid = self.open_network[WifiEnums.SSID_KEY] 164 condition = {WifiEnums.SSID_KEY: ssid} 165 asserts.assert_true(wutils.match_networks(condition, wifi_results), 166 "Can not find expected network %s" % ssid) 167 168 def test_add_network(self): 169 """Test wifi connection scan.""" 170 ssid = self.open_network[WifiEnums.SSID_KEY] 171 nId = self.dut.droid.wifiAddNetwork(self.open_network) 172 asserts.assert_true(nId > -1, "Failed to add network.") 173 configured_networks = self.dut.droid.wifiGetConfiguredNetworks() 174 self.log.debug(("Configured networks after adding: %s" % 175 configured_networks)) 176 condition = {WifiEnums.SSID_KEY: ssid} 177 asserts.assert_true(wutils.match_networks(condition, configured_networks), 178 ("Could not find expected network %s in configured " 179 "networks.") % ssid) 180 181 def test_forget_network(self): 182 self.test_add_network() 183 ssid = self.open_network[WifiEnums.SSID_KEY] 184 wutils.wifi_forget_network(self.dut, ssid) 185 configured_networks = self.dut.droid.wifiGetConfiguredNetworks() 186 for nw in configured_networks: 187 asserts.assert_true(nw[WifiEnums.BSSID_KEY] != ssid, 188 "Found forgotten network %s in configured networks." % ssid) 189 190 @acts.signals.generated_test 191 def test_iot_with_password(self): 192 params = list(itertools.product(self.iot_networks, self.android_devices)) 193 name_gen = lambda p : "test_connection_to-%s" % p[0][WifiEnums.SSID_KEY] 194 failed = self.run_generated_testcases( 195 self.connect_to_wifi_network_with_password, 196 params, 197 name_func=name_gen) 198 asserts.assert_true(not failed, "Failed ones: {}".format(failed)) 199 200 def test_tdls_supported(self): 201 model = acts.utils.trim_model_name(self.dut.model) 202 self.log.debug("Model is %s" % model) 203 if model in self.tdls_models: 204 asserts.assert_true(self.dut.droid.wifiIsTdlsSupported(), 205 ("TDLS should be supported on %s, but device is " 206 "reporting not supported.") % model) 207 else: 208 asserts.assert_true(not self.dut.droid.wifiIsTdlsSupported(), 209 ("TDLS should not be supported on %s, but device " 210 "is reporting supported.") % model) 211 212 def test_energy_info(self): 213 """Verify the WiFi energy info reporting feature. 214 215 Steps: 216 1. Check that the WiFi energy info reporting support on this device 217 is as expected (support or not). 218 2. If the device does not support energy info reporting as 219 expected, skip the test. 220 3. Call API to get WiFi energy info. 221 4. Verify the values of "ControllerEnergyUsed" and 222 "ControllerIdleTimeMillis" in energy info don't decrease. 223 5. Repeat from Step 3 for 10 times. 224 """ 225 # Check if dut supports energy info reporting. 226 actual_support = self.dut.droid.wifiIsEnhancedPowerReportingSupported() 227 model = self.dut.model 228 expected_support = model in self.energy_info_models 229 msg = "Expect energy info support to be %s on %s, got %s." % ( 230 expected_support, model, actual_support) 231 asserts.assert_true(actual_support == expected_support, msg) 232 if not actual_support: 233 asserts.skip(("Device %s does not support energy info reporting as " 234 "expected.") % model) 235 # Verify reported values don't decrease. 236 self.log.info(("Device %s supports energy info reporting, verify that " 237 "the reported values don't decrease.") % model) 238 energy = 0 239 idle_time = 0 240 for i in range(10): 241 info = self.dut.droid.wifiGetControllerActivityEnergyInfo() 242 self.log.debug("Iteration %d, got energy info: %s" % (i, info)) 243 new_energy = info["ControllerEnergyUsed"] 244 new_idle_time = info["ControllerIdleTimeMillis"] 245 asserts.assert_true(new_energy >= energy, 246 "Energy value decreased: previous %d, now %d" % (energy, 247 new_energy)) 248 energy = new_energy 249 asserts.assert_true(new_idle_time >= idle_time, 250 "Idle time decreased: previous %d, now %d" % (idle_time, 251 new_idle_time)) 252 idle_time = new_idle_time 253 wutils.start_wifi_connection_scan(self.dut) 254 255 def test_energy_info_connected(self): 256 """Verify the WiFi energy info reporting feature when connected. 257 258 Connect to a wifi network, then the same as test_energy_info. 259 """ 260 wutils.wifi_connect(self.dut, self.open_network) 261 self.test_energy_info() 262