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 logging 18import queue 19import threading 20import time 21 22import acts.base_test 23import acts_contrib.test_utils.wifi.wifi_test_utils as wutils 24import acts_contrib.test_utils.tel.tel_test_utils as tutils 25 26from acts import asserts 27from acts import signals 28from acts import utils 29from acts.controllers.iperf_server import IPerfServer 30from acts.test_decorators import test_tracker_info 31from acts_contrib.test_utils.bt.bt_test_utils import enable_bluetooth 32from acts_contrib.test_utils.bt.bt_test_utils import disable_bluetooth 33from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest 34 35WifiEnums = wutils.WifiEnums 36 37WAIT_FOR_AUTO_CONNECT = 40 38WAIT_WIFI_DISCONNECT_SEC = 60 39WAIT_BEFORE_CONNECTION = 30 40DEFAULT_TIMEOUT = 10 41PING_ADDR = 'www.google.com' 42BAND_2GHZ = 0 43BAND_5GHZ = 1 44MIN_ATTN = 0 45MAX_ATTN = 95 46 47 48class WifiStressTest(WifiBaseTest): 49 """WiFi Stress test class. 50 51 Test Bed Requirement: 52 * Two Android device 53 * Several Wi-Fi networks visible to the device, including an open Wi-Fi 54 network. 55 """ 56 57 def __init__(self, configs): 58 super().__init__(configs) 59 self.enable_packet_log = True 60 61 def setup_class(self): 62 super().setup_class() 63 64 self.dut = self.android_devices[0] 65 # Note that test_stress_softAP_startup_and_stop_5g will always fail 66 # when testing with a single device. 67 if len(self.android_devices) > 1: 68 self.dut_client = self.android_devices[1] 69 else: 70 self.dut_client = None 71 wutils.wifi_test_device_init(self.dut) 72 req_params = [] 73 opt_param = [ 74 "open_network", "reference_networks", 75 "stress_count", "stress_hours", "attn_vals", "pno_interval", 76 ] 77 self.unpack_userparams(req_param_names=req_params, 78 opt_param_names=opt_param) 79 80 if "AccessPoint" in self.user_params: 81 self.legacy_configure_ap_and_start(ap_count=2) 82 elif "OpenWrtAP" in self.user_params: 83 self.configure_openwrt_ap_and_start(open_network=True, 84 wpa_network=True, 85 ap_count=2) 86 asserts.assert_true( 87 len(self.reference_networks) > 0, 88 "Need at least one reference network with psk.") 89 self.wpa_2g = self.reference_networks[0]["2g"] 90 self.wpa_5g = self.reference_networks[0]["5g"] 91 self.open_2g = self.open_network[0]["2g"] 92 self.open_5g = self.open_network[0]["5g"] 93 self.networks = [self.wpa_2g, self.wpa_5g, self.open_2g, self.open_5g] 94 95 self.iperf_server_port = wutils.get_iperf_server_port() 96 try: 97 self.iperf_server = IPerfServer(self.iperf_server_port) 98 self.iperf_server.start() 99 logging.info(f"IPerf server started on {self.iperf_server_port}") 100 except Exception as e: 101 raise signals.TestFailure("Failed to start iperf3 server: %s" % e) 102 103 def setup_test(self): 104 super().setup_test() 105 self.dut.droid.wakeLockAcquireBright() 106 self.dut.droid.wakeUpNow() 107 108 def teardown_test(self): 109 super().teardown_test() 110 if self.dut.droid.wifiIsApEnabled(): 111 wutils.stop_wifi_tethering(self.dut) 112 self.dut.droid.wakeLockRelease() 113 self.dut.droid.goToSleepNow() 114 wutils.reset_wifi(self.dut) 115 self.log.debug("Toggling Airplane mode OFF") 116 asserts.assert_true( 117 acts.utils.force_airplane_mode(self.dut, False), 118 "Can not turn airplane mode off: %s" % self.dut.serial) 119 120 def teardown_class(self): 121 wutils.reset_wifi(self.dut) 122 self.iperf_server.stop() 123 if "AccessPoint" in self.user_params: 124 del self.user_params["reference_networks"] 125 del self.user_params["open_network"] 126 127 """Helper Functions""" 128 129 def scan_and_connect_by_ssid(self, ad, network): 130 """Scan for network and connect using network information. 131 132 Args: 133 network: A dictionary representing the network to connect to. 134 135 """ 136 ssid = network[WifiEnums.SSID_KEY] 137 wutils.start_wifi_connection_scan_and_ensure_network_found(ad, ssid) 138 wutils.wifi_connect(ad, network, num_of_tries=3) 139 140 def scan_and_connect_by_id(self, network, net_id): 141 """Scan for network and connect using network id. 142 143 Args: 144 net_id: Integer specifying the network id of the network. 145 146 """ 147 ssid = network[WifiEnums.SSID_KEY] 148 wutils.start_wifi_connection_scan_and_ensure_network_found( 149 self.dut, ssid) 150 wutils.wifi_connect_by_id(self.dut, net_id) 151 152 def run_ping(self, sec): 153 """Run ping for given number of seconds. 154 155 Args: 156 sec: Time in seconds to run teh ping traffic. 157 158 """ 159 self.log.info("Running ping for %d seconds" % sec) 160 result = self.dut.adb.shell("ping -w %d %s" % (sec, PING_ADDR), 161 timeout=sec + 1) 162 self.log.debug("Ping Result = %s" % result) 163 if "100% packet loss" in result: 164 raise signals.TestFailure("100% packet loss during ping") 165 166 def start_youtube_video(self, url=None, secs=60): 167 """Start a youtube video and check if it's playing. 168 169 Args: 170 url: The URL of the youtube video to play. 171 secs: Time to play video in seconds. 172 173 """ 174 ad = self.dut 175 ad.log.info("Start a youtube video") 176 ad.ensure_screen_on() 177 video_played = False 178 for count in range(2): 179 ad.unlock_screen() 180 ad.adb.shell('am start -a android.intent.action.VIEW -d "%s"' % 181 url) 182 if tutils.wait_for_state(ad.droid.audioIsMusicActive, True, 15, 1): 183 ad.log.info("Started a video in youtube.") 184 # Play video for given seconds. 185 time.sleep(secs) 186 video_played = True 187 break 188 if not video_played: 189 raise signals.TestFailure( 190 "Youtube video did not start. Current WiFi " 191 "state is %d" % self.dut.droid.wifiCheckState()) 192 193 def add_networks(self, ad, networks): 194 """Add Wi-Fi networks to an Android device and verify the networks were 195 added correctly. 196 197 Args: 198 ad: the AndroidDevice object to add networks to. 199 networks: a list of dicts, each dict represents a Wi-Fi network. 200 """ 201 for network in networks: 202 ret = ad.droid.wifiAddNetwork(network) 203 asserts.assert_true(ret != -1, 204 "Failed to add network %s" % network) 205 ad.droid.wifiEnableNetwork(ret, 0) 206 configured_networks = ad.droid.wifiGetConfiguredNetworks() 207 self.log.debug("Configured networks: %s", configured_networks) 208 209 def connect_and_verify_connected_ssid(self, expected_con, is_pno=False): 210 """Start a scan to get the DUT connected to an AP and verify the DUT 211 is connected to the correct SSID. 212 213 Args: 214 expected_con: The expected info of the network to we expect the DUT 215 to roam to. 216 """ 217 if is_pno: 218 self.dut.log.info("Wait %ss for PNO to trigger.", self.pno_interval) 219 self.dut.log.info("Move the DUT in range of %s", self.wpa_2g[WifiEnums.SSID_KEY]) 220 self.attenuators[0].set_atten(MIN_ATTN) 221 time.sleep(self.pno_interval) 222 wutils.wait_for_connect(self.dut, self.wpa_2g[WifiEnums.SSID_KEY]) 223 connection_info = self.dut.droid.wifiGetConnectionInfo() 224 self.log.info("Triggering network selection from %s to %s", 225 connection_info[WifiEnums.SSID_KEY], 226 expected_con[WifiEnums.SSID_KEY]) 227 else: 228 logging.info("Move the DUT in WiFi range.") 229 self.attenuators[0].set_atten(MIN_ATTN) 230 # force start a single scan so we don't have to wait for the scheduled scan. 231 wutils.start_wifi_connection_scan_and_return_status(self.dut) 232 self.log.info("Wait 60s for network selection.") 233 time.sleep(60) 234 try: 235 self.log.info("Connecting to %s network after network selection" % 236 self.dut.droid.wifiGetConnectionInfo()) 237 expected_ssid = expected_con[WifiEnums.SSID_KEY] 238 verify_con = {WifiEnums.SSID_KEY: expected_ssid} 239 wutils.verify_wifi_connection_info(self.dut, verify_con) 240 self.log.info( 241 "Connected to %s successfully after network selection", 242 expected_ssid) 243 finally: 244 pass 245 246 def run_long_traffic(self, sec, args, q): 247 try: 248 # Use local host as iperf server. 249 self.iperf_server_address = wutils.get_host_iperf_ipv4_address(self.dut) 250 asserts.assert_true(self.iperf_server_address, "The host has no " 251 "available IPv4 address for iperf client to " 252 "connect to.") 253 # Start IPerf traffic 254 self.log.info("Running iperf client {}".format(args)) 255 result, data = self.dut.run_iperf_client(self.iperf_server_address, 256 args, 257 timeout=sec + 1) 258 if not result: 259 self.log.debug("Error occurred in iPerf traffic.") 260 self.run_ping(sec) 261 q.put(True) 262 except: 263 q.put(False) 264 265 """Tests""" 266 267 @test_tracker_info(uuid="cd0016c6-58cf-4361-b551-821c0b8d2554") 268 def test_stress_toggle_wifi_state(self): 269 """Toggle WiFi state ON and OFF for N times.""" 270 for count in range(self.stress_count): 271 """Test toggling wifi""" 272 try: 273 self.log.debug("Going from on to off.") 274 wutils.wifi_toggle_state(self.dut, False) 275 self.log.debug("Going from off to on.") 276 startTime = time.time() 277 wutils.wifi_toggle_state(self.dut, True) 278 startup_time = time.time() - startTime 279 self.log.debug("WiFi was enabled on the device in %s s." % 280 startup_time) 281 except: 282 signals.TestFailure(details="", 283 extras={ 284 "Iterations": "%d" % self.stress_count, 285 "Pass": "%d" % count 286 }) 287 raise signals.TestPass(details="", 288 extras={ 289 "Iterations": "%d" % self.stress_count, 290 "Pass": "%d" % (count + 1) 291 }) 292 293 @test_tracker_info(uuid="4e591cec-9251-4d52-bc6e-6621507524dc") 294 def test_stress_toggle_wifi_state_bluetooth_on(self): 295 """Toggle WiFi state ON and OFF for N times when bluetooth ON.""" 296 enable_bluetooth(self.dut.droid, self.dut.ed) 297 for count in range(self.stress_count): 298 """Test toggling wifi""" 299 try: 300 self.log.debug("Going from on to off.") 301 wutils.wifi_toggle_state(self.dut, False) 302 self.log.debug("Going from off to on.") 303 startTime = time.time() 304 wutils.wifi_toggle_state(self.dut, True) 305 startup_time = time.time() - startTime 306 self.log.debug("WiFi was enabled on the device in %s s." % 307 startup_time) 308 except: 309 signals.TestFailure(details="", 310 extras={ 311 "Iterations": "%d" % self.stress_count, 312 "Pass": "%d" % count 313 }) 314 disable_bluetooth(self.dut.droid) 315 raise signals.TestPass(details="", 316 extras={ 317 "Iterations": "%d" % self.stress_count, 318 "Pass": "%d" % (count + 1) 319 }) 320 321 @test_tracker_info(uuid="49e3916a-9580-4bf7-a60d-a0f2545dcdde") 322 def test_stress_connect_traffic_disconnect_5g(self): 323 """Test to connect and disconnect from a network for N times. 324 325 Steps: 326 1. Scan and connect to a network. 327 2. Run IPerf to upload data for few seconds. 328 3. Disconnect. 329 4. Repeat 1-3. 330 331 """ 332 for count in range(self.stress_count): 333 try: 334 net_id = self.dut.droid.wifiAddNetwork(self.wpa_5g) 335 asserts.assert_true(net_id != -1, 336 "Add network %r failed" % self.wpa_5g) 337 self.scan_and_connect_by_id(self.wpa_5g, net_id) 338 # Use local host as iperf server. 339 self.iperf_server_address = wutils.get_host_iperf_ipv4_address(self.dut) 340 asserts.assert_true(self.iperf_server_address, "The host has no " 341 "available IPv4 address for iperf client to " 342 "connect to.") 343 # Start IPerf traffic from phone to server. 344 # Upload data for 10s. 345 args = "-p {} -t {}".format(self.iperf_server_port, 10) 346 self.log.info("Running iperf client {}".format(args)) 347 result, data = self.dut.run_iperf_client( 348 self.iperf_server_address, args) 349 if not result: 350 self.log.debug("Error occurred in iPerf traffic.") 351 self.run_ping(10) 352 wutils.wifi_forget_network(self.dut, 353 self.wpa_5g[WifiEnums.SSID_KEY]) 354 time.sleep(WAIT_BEFORE_CONNECTION) 355 except: 356 raise signals.TestFailure( 357 "Network connect-disconnect failed." 358 "Look at logs", 359 extras={ 360 "Iterations": "%d" % self.stress_count, 361 "Pass": "%d" % count 362 }) 363 raise signals.TestPass(details="", 364 extras={ 365 "Iterations": "%d" % self.stress_count, 366 "Pass": "%d" % (count + 1) 367 }) 368 369 @test_tracker_info(uuid="e9827dff-0755-43ec-8b50-1f9756958460") 370 def test_stress_connect_long_traffic_5g(self): 371 """Test to connect to network and hold connection for few hours. 372 373 Steps: 374 1. Scan and connect to a network. 375 2. Run IPerf to download data for few hours. 376 3. Run IPerf to upload data for few hours. 377 4. Verify no WiFi disconnects/data interruption. 378 379 """ 380 self.scan_and_connect_by_ssid(self.dut, self.wpa_5g) 381 self.scan_and_connect_by_ssid(self.dut_client, self.wpa_5g) 382 383 q = queue.Queue() 384 sec = self.stress_hours * 60 * 60 385 start_time = time.time() 386 387 dl_args = "-p {} -t {} -b1M -R".format(self.iperf_server_port, sec) 388 dl = threading.Thread(target=self.run_long_traffic, 389 args=(sec, dl_args, q)) 390 dl.start() 391 dl.join() 392 393 total_time = time.time() - start_time 394 self.log.debug("WiFi state = %d" % self.dut.droid.wifiCheckState()) 395 while (q.qsize() > 0): 396 if not q.get(): 397 raise signals.TestFailure("Network long-connect failed.", 398 extras={ 399 "Total Hours": 400 "%d" % self.stress_hours, 401 "Seconds Run": "%d" % total_time 402 }) 403 raise signals.TestPass(details="", 404 extras={ 405 "Total Hours": "%d" % self.stress_hours, 406 "Seconds Run": "%d" % total_time 407 }) 408 409 @test_tracker_info(uuid="591d257d-9477-4a89-a220-5715c93a76a7") 410 def test_stress_youtube_5g(self): 411 """Test to connect to network and play various youtube videos. 412 413 Steps: 414 1. Scan and connect to a network. 415 2. Loop through and play a list of youtube videos. 416 3. Verify no WiFi disconnects/data interruption. 417 418 """ 419 # List of Youtube 4K videos. 420 videos = [ 421 "https://www.youtube.com/watch?v=TKmGU77INaM", 422 "https://www.youtube.com/watch?v=WNCl-69POro", 423 "https://www.youtube.com/watch?v=dVkK36KOcqs", 424 "https://www.youtube.com/watch?v=0wCC3aLXdOw", 425 "https://www.youtube.com/watch?v=rN6nlNC9WQA", 426 "https://www.youtube.com/watch?v=RK1K2bCg4J8" 427 ] 428 try: 429 self.scan_and_connect_by_ssid(self.dut, self.wpa_5g) 430 start_time = time.time() 431 for video in videos: 432 self.start_youtube_video(url=video, secs=10 * 60) 433 except: 434 total_time = time.time() - start_time 435 raise signals.TestFailure("The youtube stress test has failed." 436 "WiFi State = %d" % 437 self.dut.droid.wifiCheckState(), 438 extras={ 439 "Total Hours": "1", 440 "Seconds Run": "%d" % total_time 441 }) 442 total_time = time.time() - start_time 443 self.log.debug("WiFi state = %d" % self.dut.droid.wifiCheckState()) 444 raise signals.TestPass(details="", 445 extras={ 446 "Total Hours": "1", 447 "Seconds Run": "%d" % total_time 448 }) 449 450 @test_tracker_info(uuid="d367c83e-5b00-4028-9ed8-f7b875997d13") 451 def test_stress_wifi_failover(self): 452 """This test does aggressive failover to several networks in list. 453 454 Steps: 455 1. Add and enable few networks. 456 2. Let device auto-connect. 457 3. Remove the connected network. 458 4. Repeat 2-3. 459 5. Device should connect to a network until all networks are 460 exhausted. 461 462 """ 463 for count in range(int(self.stress_count / 4)): 464 wutils.reset_wifi(self.dut) 465 ssids = list() 466 for network in self.networks: 467 ssids.append(network[WifiEnums.SSID_KEY]) 468 ret = self.dut.droid.wifiAddNetwork(network) 469 asserts.assert_true(ret != -1, 470 "Add network %r failed" % network) 471 self.dut.droid.wifiEnableNetwork(ret, 0) 472 self.dut.droid.wifiStartScan() 473 time.sleep(WAIT_FOR_AUTO_CONNECT) 474 cur_network = self.dut.droid.wifiGetConnectionInfo() 475 cur_ssid = cur_network[WifiEnums.SSID_KEY] 476 self.log.info("Cur_ssid = %s" % cur_ssid) 477 for i in range(0, len(self.networks)): 478 self.log.debug("Forget network %s" % cur_ssid) 479 wutils.wifi_forget_network(self.dut, cur_ssid) 480 time.sleep(WAIT_FOR_AUTO_CONNECT) 481 cur_network = self.dut.droid.wifiGetConnectionInfo() 482 cur_ssid = cur_network[WifiEnums.SSID_KEY] 483 self.log.info("Cur_ssid = %s" % cur_ssid) 484 if i == len(self.networks) - 1: 485 break 486 if cur_ssid not in ssids: 487 raise signals.TestFailure("Device did not failover to the " 488 "expected network. SSID = %s" % 489 cur_ssid) 490 network_config = self.dut.droid.wifiGetConfiguredNetworks() 491 self.log.info("Network Config = %s" % network_config) 492 if len(network_config): 493 raise signals.TestFailure( 494 "All the network configurations were not " 495 "removed. Configured networks = %s" % network_config, 496 extras={ 497 "Iterations": "%d" % self.stress_count, 498 "Pass": "%d" % (count * 4) 499 }) 500 raise signals.TestPass(details="", 501 extras={ 502 "Iterations": "%d" % self.stress_count, 503 "Pass": "%d" % ((count + 1) * 4) 504 }) 505 506 @test_tracker_info(uuid="2c19e8d1-ac16-4d7e-b309-795144e6b956") 507 def test_stress_softAP_startup_and_stop_5g(self): 508 """Test to bring up softAP and down for N times. 509 510 Steps: 511 1. Bring up softAP on 5G. 512 2. Check for softAP on teh client device. 513 3. Turn ON WiFi. 514 4. Verify softAP is turned down and WiFi is up. 515 516 """ 517 ap_ssid = "softap_" + utils.rand_ascii_str(8) 518 ap_password = utils.rand_ascii_str(8) 519 self.dut.log.info("softap setup: %s %s", ap_ssid, ap_password) 520 config = {wutils.WifiEnums.SSID_KEY: ap_ssid} 521 config[wutils.WifiEnums.PWD_KEY] = ap_password 522 # Set country code explicitly to "US". 523 wutils.set_wifi_country_code(self.dut, wutils.WifiEnums.CountryCode.US) 524 wutils.set_wifi_country_code(self.dut_client, 525 wutils.WifiEnums.CountryCode.US) 526 for count in range(self.stress_count): 527 initial_wifi_state = self.dut.droid.wifiCheckState() 528 wutils.start_wifi_tethering(self.dut, ap_ssid, ap_password, 529 WifiEnums.WIFI_CONFIG_APBAND_5G) 530 wutils.start_wifi_connection_scan_and_ensure_network_found( 531 self.dut_client, ap_ssid) 532 wutils.stop_wifi_tethering(self.dut) 533 asserts.assert_false(self.dut.droid.wifiIsApEnabled(), 534 "SoftAp failed to shutdown!") 535 # Give some time for WiFi to come back to previous state. 536 time.sleep(2) 537 cur_wifi_state = self.dut.droid.wifiCheckState() 538 if initial_wifi_state != cur_wifi_state: 539 raise signals.TestFailure( 540 "Wifi state was %d before softAP and %d now!" % 541 (initial_wifi_state, cur_wifi_state), 542 extras={ 543 "Iterations": "%d" % self.stress_count, 544 "Pass": "%d" % count 545 }) 546 raise signals.TestPass(details="", 547 extras={ 548 "Iterations": "%d" % self.stress_count, 549 "Pass": "%d" % (count + 1) 550 }) 551 552 @test_tracker_info(uuid="eb22e26b-95d1-4580-8c76-85dfe6a42a0f") 553 def test_stress_wifi_roaming(self): 554 AP1_network = self.reference_networks[0]["5g"] 555 AP2_network = self.reference_networks[1]["5g"] 556 wutils.set_attns(self.attenuators, "AP1_on_AP2_off") 557 self.scan_and_connect_by_ssid(self.dut, AP1_network) 558 # Reduce iteration to half because each iteration does two roams. 559 for count in range(int(self.stress_count / 2)): 560 self.log.info("Roaming iteration %d, from %s to %s", count, 561 AP1_network, AP2_network) 562 try: 563 wutils.trigger_roaming_and_validate(self.dut, self.attenuators, 564 "AP1_off_AP2_on", 565 AP2_network) 566 self.log.info("Roaming iteration %d, from %s to %s", count, 567 AP2_network, AP1_network) 568 wutils.trigger_roaming_and_validate(self.dut, self.attenuators, 569 "AP1_on_AP2_off", 570 AP1_network) 571 except: 572 raise signals.TestFailure("Roaming failed. Look at logs", 573 extras={ 574 "Iterations": 575 "%d" % self.stress_count, 576 "Pass": "%d" % (count * 2) 577 }) 578 raise signals.TestPass(details="", 579 extras={ 580 "Iterations": "%d" % self.stress_count, 581 "Pass": "%d" % ((count + 1) * 2) 582 }) 583 584 @test_tracker_info(uuid="e8ae8cd2-c315-4c08-9eb3-83db65b78a58") 585 def test_stress_network_selector_2G_connection(self): 586 """ 587 1. Add one saved 2G network to DUT. 588 2. Move the DUT in range. 589 3. Verify the DUT is connected to the network. 590 4. Move the DUT out of range 591 5. Repeat step 2-4 592 """ 593 for attenuator in self.attenuators: 594 attenuator.set_atten(95) 595 # add a saved network to DUT 596 networks = [self.reference_networks[0]['2g']] 597 self.add_networks(self.dut, networks) 598 for count in range(self.stress_count): 599 self.connect_and_verify_connected_ssid( 600 self.reference_networks[0]['2g']) 601 logging.info("Move the DUT out of WiFi range and wait 10 seconds.") 602 self.attenuators[0].set_atten(95) 603 time.sleep(10) 604 wutils.set_attns(self.attenuators, "default") 605 raise signals.TestPass(details="", 606 extras={ 607 "Iterations": "%d" % self.stress_count, 608 "Pass": "%d" % (count + 1) 609 }) 610 611 @test_tracker_info(uuid="5d5d14cb-3cd1-4b3d-8c04-0d6f4b764b6b") 612 def test_stress_pno_connection_to_2g(self): 613 """Test PNO triggered autoconnect to a network for N times 614 615 Steps: 616 1. DUT Connects to a 2GHz network. 617 2. Screen off DUT. 618 3. Attenuate 2GHz network and wait for triggering PNO. 619 4. Move the DUT in range of 2GHz network. 620 5. Check the device connected to 2GHz network automatically. 621 6. Repeat step 3-5. 622 """ 623 self.scan_and_connect_by_ssid(self.dut, self.wpa_2g) 624 for attenuator in self.attenuators: 625 attenuator.set_atten(MAX_ATTN) 626 self.dut.droid.wakeLockRelease() 627 self.dut.droid.goToSleepNow() 628 self.dut.log.info("DUT screen off") 629 for count in range(self.stress_count): 630 self.connect_and_verify_connected_ssid( 631 self.reference_networks[0]['2g'], is_pno=True) 632 logging.info("Move the DUT out of range by fully attenuate %s", 633 self.wpa_2g[WifiEnums.SSID_KEY]) 634 self.attenuators[0].set_atten(MAX_ATTN) 635 logging.info("Wait for DUT to disconnect from %s", 636 self.wpa_2g[WifiEnums.SSID_KEY]) 637 wutils.wait_for_disconnect(self.dut, 638 timeout=WAIT_WIFI_DISCONNECT_SEC) 639 self.dut.log.info("DUT disconnected from from %s", 640 self.wpa_2g[WifiEnums.SSID_KEY]) 641 wutils.set_attns(self.attenuators, "default") 642 raise signals.TestPass(details="", 643 extras={ 644 "Iterations": "%d" % self.stress_count, 645 "Pass": "%d" % (count + 1) 646 }) 647 648 @test_tracker_info(uuid="c880e742-8d20-4134-b717-5b6d45f6c337") 649 def test_2g_sta_wifi_on_off_under_airplane_mode(self): 650 """Toggle WiFi state ON and OFF for N times when airplane mode ON.""" 651 self.scan_and_connect_by_ssid(self.dut, self.wpa_2g) 652 self.log.debug("Toggling Airplane mode ON") 653 asserts.assert_true( 654 acts.utils.force_airplane_mode(self.dut, True), 655 "Can not turn on airplane mode on: %s" % self.dut.serial) 656 time.sleep(DEFAULT_TIMEOUT) 657 for count in range(self.stress_count): 658 """Test toggling wifi""" 659 try: 660 self.log.debug("Going from on to off.") 661 wutils.wifi_toggle_state(self.dut, False) 662 self.log.debug("Going from off to on.") 663 startTime = time.time() 664 wutils.wifi_toggle_state(self.dut, True) 665 startup_time = time.time() - startTime 666 self.log.debug("WiFi was enabled on the device in %s s." % 667 startup_time) 668 time.sleep(DEFAULT_TIMEOUT) 669 # Use local host as iperf server. 670 self.iperf_server_address = wutils.get_host_iperf_ipv4_address(self.dut) 671 asserts.assert_true(self.iperf_server_address, "The host has no " 672 "available IPv4 address for iperf client to " 673 "connect to.") 674 # Start IPerf traffic from phone to server. 675 # Upload data for 10s. 676 args = "-p {} -t {}".format(self.iperf_server_port, 10) 677 self.log.info("Running iperf client {}".format(args)) 678 result, data = self.dut.run_iperf_client( 679 self.iperf_server_address, args) 680 if not result: 681 self.log.debug("Error occurred in iPerf traffic.") 682 self.run_ping(10) 683 except: 684 signals.TestFailure(details="", 685 extras={ 686 "Iterations": "%d" % self.stress_count, 687 "Pass": "%d" % count 688 }) 689 raise signals.TestPass(details="", 690 extras={ 691 "Iterations": "%d" % self.stress_count, 692 "Pass": "%d" % (count + 1) 693 }) 694