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 from queue import Empty 19 import threading, time, traceback 20 21 from acts import asserts 22 from acts.base_test import BaseTestClass 23 from acts.utils import load_config 24 from acts.test_utils.wifi.wifi_test_utils import get_scan_time_and_channels 25 from acts.test_utils.wifi.wifi_test_utils import check_internet_connection 26 from acts.test_utils.wifi.wifi_test_utils import start_wifi_background_scan 27 from acts.test_utils.wifi.wifi_test_utils import start_wifi_single_scan 28 from acts.test_utils.wifi.wifi_test_utils import track_connection 29 from acts.test_utils.wifi.wifi_test_utils import wifi_test_device_init 30 from acts.test_utils.wifi.wifi_test_utils import WifiEnums 31 from acts.test_utils.wifi.wifi_test_utils import WifiChannelUS 32 from acts.test_utils.wifi.wifi_test_utils import wifi_forget_network 33 from acts.test_utils.wifi.wifi_test_utils import wifi_toggle_state 34 35 SCANTIME = 10000 #framework support only 10s as minimum scan interval 36 NUMBSSIDPERSCAN = 8 37 EVENT_TAG = "WifiScannerScan" 38 SCAN_TIME_PASSIVE = 47 # dwell time plus 2ms 39 SCAN_TIME_ACTIVE = 32 # dwell time plus 2ms 40 SHORT_TIMEOUT = 30 41 NETWORK_ID_ERROR = "Network don't have ID" 42 NETWORK_ERROR = "Device is not connected to reference network" 43 INVALID_RESULT = "Test fail because scan result reported are not valid" 44 EMPTY_RESULT = "Test fail because empty scan result reported" 45 KEY_RET = "ResultElapsedRealtime" 46 47 class WifiScannerScanError(Exception): 48 pass 49 50 class WifiScannerScanTest(BaseTestClass): 51 52 def __init__(self, controllers): 53 BaseTestClass.__init__(self, controllers) 54 asserts.failed_scan_settings = None 55 # A list of all test cases to be executed in this class. 56 self.tests = ( 57 "test_available_channels_generated", 58 "test_wifi_scanner_single_scan_channel_sanity", 59 "test_wifi_scanner_with_wifi_off", 60 "test_single_scan_report_each_scan_for_channels_with_enumerated_params", 61 "test_single_scan_report_each_scan_for_band_with_enumerated_params", 62 "test_wifi_scanner_batch_scan_channel_sanity", 63 "test_wifi_scanner_batch_scan_period_too_short", 64 "test_batch_scan_report_buffer_full_for_channels_with_enumerated_params", 65 "test_batch_scan_report_buffer_full_for_band_with_enumerated_params", 66 "test_batch_scan_report_each_scan_for_channels_with_enumerated_params", 67 "test_batch_scan_report_each_scan_for_band_with_enumerated_params", 68 "test_single_scan_report_full_scan_for_channels_with_enumerated_params", 69 "test_single_scan_report_full_scan_for_band_with_enumerated_params", 70 "test_batch_scan_report_full_scan_for_channels_with_enumerated_params", 71 "test_batch_scan_report_full_scan_for_band_with_enumerated_params", 72 "test_wifi_connection_while_single_scan", 73 "test_single_scan_while_pno", 74 "test_wifi_connection_and_pno_while_batch_scan", 75 "test_wifi_scanner_single_scan_in_isolated", 76 "test_wifi_scanner_with_invalid_numBssidsPerScan" 77 ) 78 self.leeway = 10 79 self.stime_channel = SCAN_TIME_PASSIVE 80 self.default_scan_setting = { 81 "band": WifiEnums.WIFI_BAND_BOTH, 82 "periodInMs": SCANTIME, 83 "reportEvents": WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN 84 } 85 self.default_batch_scan_setting = { 86 "band": WifiEnums.WIFI_BAND_BOTH, 87 "periodInMs": SCANTIME, 88 "reportEvents": WifiEnums.REPORT_EVENT_AFTER_BUFFER_FULL 89 } 90 91 def setup_class(self): 92 self.dut = self.android_devices[0] 93 wifi_test_device_init(self.dut) 94 req_params = ("connect_network", "run_extended_test", "ping_addr", 95 "max_bugreports") 96 self.unpack_userparams(req_params) 97 self.log.debug("Run extended test: {}".format(self.run_extended_test)) 98 self.wifi_chs = WifiChannelUS(self.dut.model) 99 asserts.assert_true(self.dut.droid.wifiIsScannerSupported(), 100 "Device %s doesn't support WifiScanner, abort." % self.dut.model) 101 self.attenuators[0].set_atten(0) 102 self.attenuators[1].set_atten(0) 103 104 def teardown_test(self): 105 BaseTestClass.teardown_test(self) 106 self.log.debug("Shut down all wifi scanner activities.") 107 self.dut.droid.wifiScannerShutdown() 108 109 def on_fail(self, test_name, begin_time): 110 if self.max_bugreports > 0: 111 self.dut.take_bug_report(test_name, begin_time) 112 self.max_bugreports -= 1 113 self.dut.cat_adb_log(test_name, begin_time) 114 115 """ Helper Functions Begin """ 116 117 def wifi_generate_scanner_scan_settings(self, extended, scan_type, report_result): 118 """Generates all the combinations of different scan setting parameters. 119 120 Args: 121 extended: True for extended setting 122 scan_type: key for type of scan 123 report_result: event type of report scan results 124 125 Returns: 126 A list of dictionaries each representing a set of scan settings. 127 """ 128 base_scan_time = [SCANTIME*2] 129 if scan_type == "band": 130 scan_types_setting = [WifiEnums.WIFI_BAND_BOTH] 131 else: 132 scan_types_setting = [self.wifi_chs.MIX_CHANNEL_SCAN] 133 num_of_bssid = [NUMBSSIDPERSCAN*4] 134 max_scan_cache = [0] 135 if extended: 136 base_scan_time.append(SCANTIME) 137 if scan_type == "band": 138 scan_types_setting.extend([WifiEnums.WIFI_BAND_24_GHZ, 139 WifiEnums.WIFI_BAND_5_GHZ_WITH_DFS, 140 WifiEnums.WIFI_BAND_BOTH_WITH_DFS]) 141 else: 142 scan_types_setting.extend([self.wifi_chs.NONE_DFS_5G_FREQUENCIES, 143 self.wifi_chs.ALL_2G_FREQUENCIES, 144 self.wifi_chs.DFS_5G_FREQUENCIES, 145 self.wifi_chs.ALL_5G_FREQUENCIES]) 146 num_of_bssid.append(NUMBSSIDPERSCAN*3) 147 max_scan_cache.append(5) 148 # Generate all the combinations of report types and scan types 149 if report_result == WifiEnums.REPORT_EVENT_FULL_SCAN_RESULT: 150 report_types = {"reportEvents" : report_result} 151 setting_combinations = list(itertools.product(scan_types_setting, 152 base_scan_time)) 153 # Create scan setting strings based on the combinations 154 scan_settings = [] 155 for combo in setting_combinations: 156 s = dict(report_types) 157 s[scan_type] = combo[0] 158 s["periodInMs"] = combo[1] 159 scan_settings.append(s) 160 else: 161 report_types = {"reportEvents" : report_result} 162 setting_combinations = list(itertools.product(scan_types_setting, 163 base_scan_time, num_of_bssid, 164 max_scan_cache)) 165 # Create scan setting strings based on the combinations 166 scan_settings = [] 167 for combo in setting_combinations: 168 s = dict(report_types) 169 s[scan_type] = combo[0] 170 s["periodInMs"] = combo[1] 171 s["numBssidsPerScan"] = combo[2] 172 s["maxScansToCache"] = combo[3] 173 scan_settings.append(s) 174 return scan_settings 175 176 def proces_and_valid_batch_scan_result(self, scan_resutls, scan_rt, 177 result_rt, scan_setting): 178 """This function process scan results and validate against settings used 179 while starting the scan. 180 181 There are two steps for the verification. First it checks that all the 182 wifi networks in results are of the correct frequencies set by scan setting 183 params. Then it checks that the delta between the batch of scan results less 184 than the time required for scanning channel set by scan setting params. 185 186 Args: 187 scan_results: scan results reported. 188 scan_rt: Elapsed real time on start scan. 189 result_rt: Elapsed ral time on results reported. 190 scan_setting: The params for the single scan. 191 192 Returns: 193 bssids: total number of bssids scan result have 194 validity: True if the all scan result are valid. 195 """ 196 bssids = 0 197 validity = True 198 scan_time_mic = 0 199 scan_channels = [] 200 scan_time, scan_channels = get_scan_time_and_channels(self.wifi_chs, 201 scan_setting, 202 self.stime_channel) 203 scan_time_mic = scan_time * 1000 204 for i, batch in enumerate(scan_resutls, start=1): 205 max_scan_interval = batch["ScanResults"][0]["timestamp"] + scan_time_mic 206 self.log.debug("max_scan_interval: {}".format(max_scan_interval) ) 207 for result in batch["ScanResults"]: 208 if (result["frequency"] not in scan_channels 209 or result["timestamp"] > max_scan_interval 210 or result["timestamp"] < scan_rt*1000 211 or result["timestamp"] > result_rt*1000) : 212 self.log.error("Result didn't match requirement: {}". 213 format(result) ) 214 validity = False 215 self.log.info("Number of scan result in batch {} :: {}".format(i, 216 len(batch["ScanResults"]))) 217 bssids += len(batch["ScanResults"]) 218 return bssids, validity 219 220 def pop_scan_result_events(self, event_name): 221 """Function to pop all the scan result events. 222 223 Args: 224 event_name: event name. 225 226 Returns: 227 results: list of scan result reported in events 228 """ 229 results = [] 230 try: 231 events = self.dut.ed.pop_all(event_name) 232 for event in events: 233 results.append(event["data"]["Results"]) 234 except Empty as error: 235 self.log.debug("Number of Full scan results {}".format(len(results))) 236 return results 237 238 def wifi_scanner_single_scan(self, scan_setting): 239 """Common logic for an enumerated wifi scanner single scan test case. 240 241 1. Start WifiScanner single scan for scan_setting. 242 2. Wait for the scan result event, wait time depend on scan settings 243 parameter. 244 3. Verify that scan results match with scan settings parameters. 245 4. Also verify that only one scan result event trigger. 246 247 Args: 248 scan_setting: The params for the single scan. 249 """ 250 data = start_wifi_single_scan(self.dut, scan_setting) 251 idx = data["Index"] 252 scan_rt = data["ScanElapsedRealtime"] 253 self.log.info("Wifi single shot scan started index: {} at real time: {}". 254 format(idx, scan_rt)) 255 results = [] 256 #generating event wait time from scan setting plus leeway 257 scan_time, scan_channels = get_scan_time_and_channels(self.wifi_chs, 258 scan_setting, 259 self.stime_channel) 260 wait_time = int(scan_time/1000) + self.leeway 261 validity = False 262 #track number of result received 263 result_received = 0 264 try: 265 for snumber in range(1,3): 266 event_name = "{}{}onResults".format(EVENT_TAG, idx) 267 self.log.debug("Waiting for event: {} for time {}". 268 format(event_name, wait_time)) 269 event = self.dut.ed.pop_event(event_name, wait_time) 270 self.log.debug("Event received: {}".format(event )) 271 results = event["data"]["Results"] 272 result_received += 1 273 bssids, validity = self.proces_and_valid_batch_scan_result( 274 results, scan_rt, 275 event["data"][KEY_RET], 276 scan_setting) 277 asserts.assert_true(len(results) == 1, 278 "Test fail because number of scan result {}" 279 .format(len(results))) 280 asserts.assert_true(bssids > 0, EMPTY_RESULT) 281 asserts.assert_true(validity, INVALID_RESULT) 282 self.log.info("Scan number Buckets: {}\nTotal BSSID: {}". 283 format(len(results), bssids)) 284 except Empty as error: 285 asserts.assert_true(result_received >= 1, 286 "Event did not triggered for single shot {}". 287 format(error)) 288 finally: 289 self.dut.droid.wifiScannerStopScan(idx) 290 #For single shot number of result received and length of result should be one 291 asserts.assert_true(result_received == 1, 292 "Test fail because received result {}". 293 format(result_received)) 294 295 def wifi_scanner_single_scan_full(self, scan_setting): 296 """Common logic for single scan test case for full scan result. 297 298 1. Start WifiScanner single scan with scan_setting for full scan result. 299 2. Wait for the scan result event, wait time depend on scan settings 300 parameter. 301 3. Pop all full scan result events occurred earlier. 302 4. Verify that full scan results match with normal scan results. 303 304 Args: 305 scan_setting: The parameters for the single scan. 306 """ 307 self.dut.ed.clear_all_events() 308 data = start_wifi_single_scan(self.dut, scan_setting) 309 idx = data["Index"] 310 scan_rt = data["ScanElapsedRealtime"] 311 self.log.info("Wifi single shot scan started with index: {}".format(idx)) 312 #generating event wait time from scan setting plus leeway 313 scan_time, scan_channels = get_scan_time_and_channels(self.wifi_chs, 314 scan_setting, 315 self.stime_channel) 316 wait_time = int(scan_time/1000) + self.leeway 317 results = [] 318 validity = False 319 try: 320 event_name = "{}{}onResults".format(EVENT_TAG, idx) 321 self.log.debug("Waiting for event: {} for time {}". 322 format(event_name, wait_time)) 323 event = self.dut.ed.pop_event(event_name, wait_time) 324 self.log.info("Event received: {}".format(event)) 325 bssids, validity = (self.proces_and_valid_batch_scan_result( 326 event["data"]["Results"], scan_rt, 327 event["data"][KEY_RET], 328 scan_setting)) 329 asserts.assert_true(bssids > 0, EMPTY_RESULT) 330 asserts.assert_true(validity, INVALID_RESULT) 331 event_name = "{}{}onFullResult".format(EVENT_TAG, idx) 332 results = self.pop_scan_result_events(event_name) 333 asserts.assert_true(len(results) >= bssids, 334 "Full single shot result don't match {}". 335 format(len(results))) 336 except Empty as error: 337 raise AssertionError("Event did not triggered for single shot {}". 338 format(error)) 339 finally: 340 self.dut.droid.wifiScannerStopScan(idx) 341 342 def wifi_scanner_batch_scan_full(self, scan_setting): 343 """Common logic for batch scan test case for full scan result. 344 345 1. Start WifiScanner batch scan with scan_setting for full scan result. 346 2. Wait for the scan result event, wait time depend on scan settings 347 parameter. 348 3. Pop all full scan result events occurred earlier. 349 4. Verify that full scan results match with scan results. 350 351 Args: 352 scan_setting: The params for the batch scan. 353 """ 354 self.dut.ed.clear_all_events() 355 data = start_wifi_background_scan(self.dut, scan_setting) 356 idx = data["Index"] 357 scan_rt = data["ScanElapsedRealtime"] 358 self.log.info("Wifi batch shot scan started with index: {}".format(idx)) 359 #generating event wait time from scan setting plus leeway 360 scan_time, scan_channels = get_scan_time_and_channels(self.wifi_chs, 361 scan_setting, 362 self.stime_channel) 363 # multiply scan period by two to account for scheduler changing period 364 scan_time += scan_setting['periodInMs'] * 2 #add scan period delay for next cycle 365 wait_time = scan_time / 1000 + self.leeway 366 validity = False 367 try: 368 for snumber in range(1,3): 369 results = [] 370 event_name = "{}{}onResults".format(EVENT_TAG, idx) 371 self.log.debug("Waiting for event: {} for time {}". 372 format(event_name, wait_time)) 373 event = self.dut.ed.pop_event(event_name, wait_time) 374 self.log.debug("Event received: {}".format(event)) 375 bssids, validity = self.proces_and_valid_batch_scan_result( 376 event["data"]["Results"], 377 scan_rt, 378 event["data"][KEY_RET], 379 scan_setting) 380 event_name = "{}{}onFullResult".format(EVENT_TAG, idx) 381 results = self.pop_scan_result_events(event_name) 382 asserts.assert_true(len(results) >= bssids, 383 "Full single shot result don't match {}". 384 format(len(results))) 385 asserts.assert_true(bssids > 0, EMPTY_RESULT) 386 asserts.assert_true(validity, INVALID_RESULT) 387 except Empty as error: 388 raise AssertionError("Event did not triggered for batch scan {}". 389 format(error)) 390 finally: 391 self.dut.droid.wifiScannerStopBackgroundScan(idx) 392 self.dut.ed.clear_all_events() 393 394 def wifi_scanner_batch_scan(self, scan_setting): 395 """Common logic for an enumerated wifi scanner batch scan test case. 396 397 1. Start WifiScanner batch scan for given scan_setting. 398 2. Wait for the scan result event, wait time depend on scan settings 399 parameter. 400 3. Verify that scan results match with scan settings parameters. 401 4. Also verify that multiple scan result events trigger. 402 403 Args: 404 scan_setting: The parameters for the batch scan. 405 """ 406 data = start_wifi_background_scan(self.dut, scan_setting) 407 idx = data["Index"] 408 scan_rt = data["ScanElapsedRealtime"] 409 self.log.info("Wifi background scan started with index: {} real time {}" 410 .format(idx, scan_rt)) 411 scan_time, scan_channels = get_scan_time_and_channels(self.wifi_chs, 412 scan_setting, 413 self.stime_channel) 414 #generating event wait time from scan setting plus leeway 415 time_cache = 0 416 number_bucket = 1 #bucket for Report result on each scan 417 check_get_result = False 418 if scan_setting['reportEvents'] == WifiEnums.REPORT_EVENT_AFTER_BUFFER_FULL: 419 check_get_result = True 420 if ('maxScansToCache' in scan_setting and 421 scan_setting['maxScansToCache'] != 0) : 422 time_cache = (scan_setting['maxScansToCache'] * 423 scan_setting['periodInMs']) 424 number_bucket = scan_setting['maxScansToCache'] 425 else: 426 time_cache = 10 * scan_setting['periodInMs'] #10 as default max scan cache 427 number_bucket = 10 428 else: 429 time_cache = scan_setting['periodInMs'] #need while waiting for seconds resutls 430 # multiply cache time by two to account for scheduler changing period 431 wait_time = (time_cache * 2 + scan_time) / 1000 + self.leeway 432 validity = False 433 try: 434 for snumber in range(1,3): 435 event_name = "{}{}onResults".format(EVENT_TAG, idx) 436 self.log.info("Waiting for event: {} for time {}". 437 format(event_name,wait_time)) 438 event = self.dut.ed.pop_event(event_name, wait_time) 439 self.log.debug("Event received: {}".format(event )) 440 results = event["data"]["Results"] 441 bssids, validity = (self.proces_and_valid_batch_scan_result( 442 results, scan_rt, 443 event["data"][KEY_RET], 444 scan_setting)) 445 self.log.info("Scan number: {}\n Buckets: {}\n BSSID: {}". 446 format(snumber, len(results), bssids)) 447 asserts.assert_true(len(results) == number_bucket, 448 "Test fail because number_bucket {}". 449 format(len(results))) 450 asserts.assert_true(bssids >= 1, EMPTY_RESULT) 451 asserts.assert_true(validity, INVALID_RESULT) 452 if snumber%2 == 1 and check_get_result : 453 self.log.info("Get Scan result using GetScanResult API") 454 time.sleep(wait_time/number_bucket) 455 if self.dut.droid.wifiScannerGetScanResults(): 456 event = self.dut.ed.pop_event(event_name, 1) 457 self.log.debug("Event onResults: {}".format(event)) 458 results = event["data"]["Results"] 459 bssids, validity = (self.proces_and_valid_batch_scan_result( 460 results, scan_rt, 461 event["data"][KEY_RET], 462 scan_setting)) 463 self.log.info("Got Scan result number: {} BSSID: {}". 464 format(snumber, bssids)) 465 asserts.assert_true(bssids >= 1, EMPTY_RESULT) 466 asserts.assert_true(validity, INVALID_RESULT) 467 else: 468 self.log.error("Error while fetching the scan result") 469 except Empty as error: 470 raise AssertionError("Event did not triggered for batch scan {}". 471 format(error)) 472 finally: 473 self.dut.droid.wifiScannerStopBackgroundScan(idx) 474 self.dut.ed.clear_all_events() 475 476 def start_wifi_scanner_single_scan_expect_failure(self, scan_setting): 477 """Common logic to test wif scanner single scan with invalid settings 478 or environment 479 480 1. Start WifiScanner batch scan for setting parameters. 481 2. Verify that scan is not started. 482 483 Args: 484 scan_setting: The params for the single scan. 485 """ 486 try: 487 idx = self.dut.droid.wifiScannerStartScan(scan_setting) 488 event = self.dut.ed.pop_event("{}{}onFailure".format(EVENT_TAG, idx), 489 SHORT_TIMEOUT) 490 except Empty as error: 491 raise AssertionError("Did not get expected onFailure {}".format(error)) 492 493 def start_wifi_scanner_background_scan_expect_failure(self, scan_setting): 494 """Common logic to test wif scanner batch scan with invalid settings 495 or environment 496 497 1. Start WifiScanner batch scan for setting parameters. 498 2. Verify that scan is not started. 499 500 Args: 501 scan_setting: The params for the single scan. 502 """ 503 try: 504 idx = self.dut.droid.wifiScannerStartBackgroundScan(scan_setting) 505 event = self.dut.ed.pop_event("{}{}onFailure".format(EVENT_TAG, idx), 506 SHORT_TIMEOUT) 507 except Empty as error: 508 raise AssertionError("Did not get expected onFailure {}".format(error)) 509 510 def check_get_available_channels_with_one_band(self, band): 511 """Common logic to check available channels for a band. 512 513 1. Get available channels for band. 514 2. Verify that channels match with supported channels for band. 515 516 Args: 517 band: wifi band.""" 518 519 r = self.dut.droid.wifiScannerGetAvailableChannels(band) 520 self.log.debug(band) 521 self.log.debug(r) 522 expected = self.wifi_chs.band_to_freq(band) 523 asserts.assert_true(set(r) == set(expected), 524 "Band {} failed. Expected {}, got {}". 525 format(band, expected, r)) 526 527 def connect_to_reference_network(self): 528 """Connect to reference network and make sure that connection happen""" 529 self.dut.droid.wakeLockAcquireBright() 530 self.dut.droid.wakeUpNow() 531 try: 532 self.dut.droid.wifiPriorityConnect(self.connect_network) 533 connect_result = self.dut.ed.pop_event("WifiManagerPriorityConnectOnSuccess", 534 SHORT_TIMEOUT) 535 self.log.info(connect_result) 536 return track_connection(self.dut, self.connect_network["ssid"], 1) 537 except Exception as error: 538 self.log.exception(traceback.format_exc()) 539 self.log.error("Connection to network fail because {}".format(error)) 540 return False 541 finally: 542 self.dut.droid.wifiLockRelease() 543 self.dut.droid.goToSleepNow() 544 545 """ Helper Functions End """ 546 547 """ Tests Begin """ 548 def test_available_channels_generated(self): 549 """Test available channels for different bands. 550 551 1. Get available channels for different bands. 552 2. Verify that channels match with supported channels for respective band. 553 """ 554 bands = (1,2,3,4,6,7) 555 name_func = lambda band : "test_get_channel_band_{}".format(band) 556 failed = self.run_generated_testcases( 557 self.check_get_available_channels_with_one_band, 558 bands, name_func = name_func) 559 asserts.assert_true(not failed, 560 "Number of test_get_channel_band failed {}". 561 format(len(failed))) 562 563 def test_single_scan_report_each_scan_for_channels_with_enumerated_params(self): 564 """Test WiFi scanner single scan for channels with enumerated settings. 565 566 1. Start WifiScanner single scan for different channels with enumerated 567 scan settings. 568 2. Verify that scan results match with respective scan settings. 569 """ 570 scan_settings = self.wifi_generate_scanner_scan_settings( 571 self.run_extended_test, "channels", 572 WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN) 573 self.log.debug("Scan settings:{}\n{}".format(len(scan_settings), 574 scan_settings)) 575 name_func = (lambda scan_setting : 576 ("test_single_scan_report_each_scan_for_channels_{}" 577 "_numBssidsPerScan_{}_maxScansToCache_{}_period_{}"). 578 format(scan_setting["channels"], 579 scan_setting["numBssidsPerScan"], 580 scan_setting["maxScansToCache"], 581 scan_setting["periodInMs"])) 582 failed = self.run_generated_testcases(self.wifi_scanner_single_scan, 583 scan_settings, 584 name_func = name_func) 585 asserts.assert_true(not failed, 586 ("Number of test_single_scan_report_each_scan_for_channels" 587 " failed {}").format(len(failed))) 588 589 def test_single_scan_report_each_scan_for_band_with_enumerated_params(self): 590 """Test WiFi scanner single scan for bands with enumerated settings. 591 592 1. Start WifiScanner single scan for different bands with enumerated 593 scan settings. 594 2. Verify that scan results match with respective scan settings. 595 """ 596 scan_settings = self.wifi_generate_scanner_scan_settings( 597 self.run_extended_test,"band", 598 WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN) 599 self.log.debug("Scan settings:{}\n{}".format(len(scan_settings), 600 scan_settings)) 601 name_func = (lambda scan_setting : 602 ("test_single_scan_report_each_scan_for_band_{}" 603 "_numBssidsPerScan_{}_maxScansToCache_{}_period_{}"). 604 format(scan_setting["band"], 605 scan_setting["numBssidsPerScan"], 606 scan_setting["maxScansToCache"], 607 scan_setting["periodInMs"])) 608 failed = self.run_generated_testcases(self.wifi_scanner_single_scan, 609 scan_settings, 610 name_func = name_func) 611 asserts.assert_true(not failed, 612 ("Number of test_single_scan_report_each_scan_for_band" 613 " failed {}").format(len(failed))) 614 615 def test_batch_scan_report_buffer_full_for_channels_with_enumerated_params(self): 616 """Test WiFi scanner batch scan using channels with enumerated settings 617 to report buffer full scan results. 618 619 1. Start WifiScanner batch scan using different channels with enumerated 620 scan settings to report buffer full scan results. 621 2. Verify that scan results match with respective scan settings. 622 """ 623 scan_settings = self.wifi_generate_scanner_scan_settings( 624 self.run_extended_test, "channels", 625 WifiEnums.REPORT_EVENT_AFTER_BUFFER_FULL) 626 self.log.debug("Scan settings:{}\n{}".format(len(scan_settings), 627 scan_settings)) 628 name_func = (lambda scan_setting : 629 ("test_batch_scan_report_buffer_full_for_channels_{}" 630 "_numBssidsPerScan_{}_maxScansToCache_{}_periodInMs_{}"). 631 format(scan_setting["channels"], 632 scan_setting["numBssidsPerScan"], 633 scan_setting["maxScansToCache"], 634 scan_setting["periodInMs"])) 635 failed = self.run_generated_testcases(self.wifi_scanner_batch_scan, 636 scan_settings, 637 name_func = name_func) 638 asserts.assert_true(not failed, 639 ("Number of test_batch_scan_report_buffer_full_for_channels" 640 " failed {}").format(len(failed))) 641 642 def test_batch_scan_report_buffer_full_for_band_with_enumerated_params(self): 643 """Test WiFi scanner batch scan using band with enumerated settings 644 to report buffer full scan results. 645 646 1. Start WifiScanner batch scan using different bands with enumerated 647 scan settings to report buffer full scan results. 648 2. Verify that scan results match with respective scan settings. 649 """ 650 scan_settings = self.wifi_generate_scanner_scan_settings( 651 self.run_extended_test,"band", 652 WifiEnums.REPORT_EVENT_AFTER_BUFFER_FULL) 653 self.log.debug("Scan settings:{}\n{}".format(len(scan_settings), 654 scan_settings)) 655 name_func = (lambda scan_setting : 656 ("test_batch_scan_report_buffer_full_for_band_{}" 657 "_numBssidsPerScan_{}_maxScansToCache_{}_periodInMs_{}"). 658 format(scan_setting["band"], 659 scan_setting["numBssidsPerScan"], 660 scan_setting["maxScansToCache"], 661 scan_setting["periodInMs"])) 662 failed = self.run_generated_testcases(self.wifi_scanner_batch_scan, 663 scan_settings, 664 name_func = name_func) 665 asserts.assert_true(not failed, 666 ("Number of test_batch_scan_report_buffer_full_for_band" 667 " failed {}").format(len(failed))) 668 669 def test_batch_scan_report_each_scan_for_channels_with_enumerated_params(self): 670 """Test WiFi scanner batch scan using channels with enumerated settings 671 to report each scan results. 672 673 1. Start WifiScanner batch scan using different channels with enumerated 674 scan settings to report each scan results. 675 2. Verify that scan results match with respective scan settings. 676 """ 677 scan_settings = self.wifi_generate_scanner_scan_settings( 678 self.run_extended_test, "channels", 679 WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN) 680 self.log.debug("Scan settings:{}\n{}". 681 format(len(scan_settings),scan_settings)) 682 name_func = (lambda scan_setting : 683 ("test_batch_scan_report_each_scan_for_channels_{}" 684 "_numBssidsPerScan_{}_maxScansToCache_{}_periodInMs_{}"). 685 format(scan_setting["channels"], 686 scan_setting["numBssidsPerScan"], 687 scan_setting["maxScansToCache"], 688 scan_setting["periodInMs"])) 689 failed = self.run_generated_testcases(self.wifi_scanner_batch_scan, 690 scan_settings, 691 name_func = name_func) 692 asserts.assert_true(not failed, 693 ("Number of test_batch_scan_report_each_scan_for_channels" 694 " failed {}").format(len(failed))) 695 696 def test_batch_scan_report_each_scan_for_band_with_enumerated_params(self): 697 """Test WiFi scanner batch scan using band with enumerated settings 698 to report each scan results. 699 700 1. Start WifiScanner batch scan using different bands with enumerated 701 scan settings to report each scan results. 702 2. Verify that scan results match with respective scan settings. 703 """ 704 scan_settings = self.wifi_generate_scanner_scan_settings( 705 self.run_extended_test, "band", 706 WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN) 707 self.log.debug("Scan settings:{}\n{}".format(len(scan_settings), 708 scan_settings)) 709 name_func = (lambda scan_setting : 710 ("test_batch_scan_report_each_scan_for_band_{}" 711 "_numBssidsPerScan_{}_maxScansToCache_{}_periodInMs_{}"). 712 format(scan_setting["band"], 713 scan_setting["numBssidsPerScan"], 714 scan_setting["maxScansToCache"], 715 scan_setting["periodInMs"])) 716 failed = self.run_generated_testcases(self.wifi_scanner_batch_scan, 717 scan_settings, 718 name_func = name_func) 719 asserts.assert_true(not failed, 720 ("Number of test_batch_scan_report_each_scan_for_band" 721 " failed {}").format(len(failed))) 722 723 def test_single_scan_report_full_scan_for_channels_with_enumerated_params(self): 724 """Test WiFi scanner single scan using channels with enumerated settings 725 to report full scan results. 726 727 1. Start WifiScanner single scan using different channels with enumerated 728 scan settings to report full scan results. 729 2. Verify that scan results match with respective scan settings. 730 """ 731 scan_settings = self.wifi_generate_scanner_scan_settings( 732 self.run_extended_test, "channels", 733 WifiEnums.REPORT_EVENT_FULL_SCAN_RESULT) 734 self.log.debug("Full Scan settings:{}\n{}".format(len(scan_settings), 735 scan_settings)) 736 name_func = (lambda scan_setting : 737 "test_single_scan_report_full_scan_for_channels_{}_periodInMs_{}". 738 format(scan_setting["channels"],scan_setting["periodInMs"])) 739 failed = self.run_generated_testcases(self.wifi_scanner_single_scan_full, 740 scan_settings, 741 name_func = name_func) 742 asserts.assert_true(not failed, 743 ("Number of test_single_scan_report_full_scan_for_channels" 744 " failed {}").format(len(failed))) 745 746 def test_single_scan_report_full_scan_for_band_with_enumerated_params(self): 747 """Test WiFi scanner single scan using band with enumerated settings 748 to report full scan results. 749 750 1. Start WifiScanner single scan using different bands with enumerated 751 scan settings to report full scan results. 752 2. Verify that scan results match with respective scan settings. 753 """ 754 scan_settings = self.wifi_generate_scanner_scan_settings( 755 self.run_extended_test, "band", 756 WifiEnums.REPORT_EVENT_FULL_SCAN_RESULT) 757 self.log.debug("Full Scan settings:{}\n{}".format(len(scan_settings), 758 scan_settings)) 759 name_func = (lambda scan_setting : 760 "test_single_scan_report_full_scan_for_band_{}_periodInMs_{}". 761 format(scan_setting["band"],scan_setting["periodInMs"])) 762 failed = self.run_generated_testcases(self.wifi_scanner_single_scan_full, 763 scan_settings, 764 name_func = name_func) 765 asserts.assert_true(not failed, 766 ("Number of test_single_scan_report_full_scan_for_band" 767 " failed {}").format(len(failed))) 768 769 def test_batch_scan_report_full_scan_for_channels_with_enumerated_params(self): 770 """Test WiFi scanner batch scan using channels with enumerated settings 771 to report full scan results. 772 773 1. Start WifiScanner batch scan using different channels with enumerated 774 scan settings to report full scan results. 775 2. Verify that scan results match with respective scan settings. 776 """ 777 scan_settings = self.wifi_generate_scanner_scan_settings( 778 self.run_extended_test, "channels", 779 WifiEnums.REPORT_EVENT_FULL_SCAN_RESULT) 780 self.log.debug("Full Scan settings:{}\n{}".format(len(scan_settings), 781 scan_settings)) 782 name_func = (lambda scan_setting : 783 ("test_batch_scan_report_full_scan_for_channels" 784 "_{}_periodInMs_{}").format(scan_setting["channels"], 785 scan_setting["periodInMs"])) 786 failed = self.run_generated_testcases(self.wifi_scanner_batch_scan_full, 787 scan_settings, 788 name_func = name_func) 789 asserts.assert_true(not failed, 790 ("Number of test_batch_scan_report_full_scan_for_channels" 791 " failed {}").format(len(failed))) 792 793 def test_batch_scan_report_full_scan_for_band_with_enumerated_params(self): 794 """Test WiFi scanner batch scan using channels with enumerated settings 795 to report full scan results. 796 797 1. Start WifiScanner batch scan using different channels with enumerated 798 scan settings to report full scan results. 799 2. Verify that scan results match with respective scan settings. 800 """ 801 scan_settings = self.wifi_generate_scanner_scan_settings( 802 self.run_extended_test, "band", 803 WifiEnums.REPORT_EVENT_FULL_SCAN_RESULT) 804 self.log.debug("Full Scan settings:{}\n{}".format(len(scan_settings), 805 scan_settings)) 806 name_func = (lambda scan_setting : 807 ("test_batch_scan_report_full_scan_for_band" 808 "_{}_periodInMs_{}").format(scan_setting["band"], 809 scan_setting["periodInMs"])) 810 failed = self.run_generated_testcases(self.wifi_scanner_batch_scan_full, 811 scan_settings, 812 name_func = name_func) 813 asserts.assert_true(not failed, 814 ("Number of test_batch_scan_report_full_scan_for_band" 815 " failed {}").format(len(failed))) 816 817 def test_wifi_connection_while_single_scan(self): 818 """Test configuring a connection parallel to wifi scanner single scan. 819 820 1. Start WifiScanner single scan for both band with default scan settings. 821 2. Configure a connection to reference network. 822 3. Verify that connection to reference network occurred. 823 2. Verify that scanner report single scan results. 824 """ 825 self.attenuators[self.connect_network["attenuator"]].set_atten(0) 826 data = start_wifi_single_scan(self.dut, self.default_scan_setting) 827 idx = data["Index"] 828 scan_rt = data["ScanElapsedRealtime"] 829 self.log.info("Wifi single shot scan started with index: {}".format(idx)) 830 asserts.assert_true(self.connect_to_reference_network(), NETWORK_ERROR) 831 time.sleep(10) #wait for connection to be active 832 asserts.assert_true(check_internet_connection(self.dut, self.ping_addr), 833 "Error, No internet connection for current network") 834 #generating event wait time from scan setting plus leeway 835 scan_time, scan_channels = get_scan_time_and_channels(self.wifi_chs, 836 self.default_scan_setting, 837 self.stime_channel) 838 wait_time = int(scan_time/1000) + self.leeway 839 validity = False 840 try: 841 event_name = "{}{}onResults".format(EVENT_TAG, idx) 842 self.log.debug("Waiting for event: {} for time {}". 843 format(event_name, wait_time)) 844 event = self.dut.ed.pop_event(event_name, wait_time) 845 self.log.debug("Event received: {}".format(event )) 846 results = event["data"]["Results"] 847 bssids, validity = self.proces_and_valid_batch_scan_result( 848 results, scan_rt, 849 event["data"][KEY_RET], 850 self.default_scan_setting) 851 self.log.info("Scan number Buckets: {}\nTotal BSSID: {}". 852 format(len(results), bssids)) 853 asserts.assert_true(len(results) == 1 and bssids >= 1, EMPTY_RESULT) 854 except Empty as error: 855 raise AssertionError("Event did not triggered for single scan {}". 856 format(error)) 857 858 def test_single_scan_while_pno(self): 859 """Test wifi scanner single scan parallel to PNO connection. 860 861 1. Check device have a saved network. 862 2. Trigger PNO by attenuate the signal to move out of range. 863 3. Start WifiScanner single scan for both band with default scan settings. 864 4. Verify that scanner report single scan results. 865 5. Attenuate the signal to move in range. 866 6. Verify connection occurred through PNO. 867 """ 868 self.log.info("Check connection through PNO for reference network") 869 current_network = self.dut.droid.wifiGetConnectionInfo() 870 self.log.info("Current network: {}".format(current_network)) 871 asserts.assert_true('network_id' in current_network, NETWORK_ID_ERROR) 872 asserts.assert_true(current_network['network_id'] >= 0, NETWORK_ERROR) 873 self.log.info("Kicking PNO for reference network") 874 self.attenuators[self.connect_network["attenuator"]].set_atten(90) 875 time.sleep(10) #wait for PNO to be kicked 876 self.log.info("Starting single scan while PNO") 877 self.wifi_scanner_single_scan(self.default_scan_setting) 878 self.attenuators[self.connect_network["attenuator"]].set_atten(0) 879 self.log.info("Check connection through PNO for reference network") 880 time.sleep(30) #wait for connection through PNO 881 current_network = self.dut.droid.wifiGetConnectionInfo() 882 self.log.info("Current network: {}".format(current_network)) 883 asserts.assert_true('network_id' in current_network, NETWORK_ID_ERROR) 884 asserts.assert_true(current_network['network_id'] >= 0, NETWORK_ERROR) 885 time.sleep(10) #wait for IP to be assigned 886 asserts.assert_true(check_internet_connection(self.dut, self.ping_addr), 887 "Error, No internet connection for current network") 888 wifi_forget_network(self.dut, self.connect_network["ssid"]) 889 890 def test_wifi_connection_and_pno_while_batch_scan(self): 891 """Test configuring a connection and PNO connection parallel to wifi 892 scanner batch scan. 893 894 1. Start WifiScanner batch scan with default batch scan settings. 895 2. Wait for scan result event for a time depend on scan settings. 896 3. Verify reported batch scan results. 897 4. Configure a connection to reference network. 898 5. Verify that connection to reference network occurred. 899 6. Wait for scan result event for a time depend on scan settings. 900 7. Verify reported batch scan results. 901 8. Trigger PNO by attenuate the signal to move out of range. 902 9. Wait for scan result event for a time depend on scan settings. 903 10. Verify reported batch scan results. 904 11. Attenuate the signal to move in range. 905 12. Verify connection occurred through PNO. 906 """ 907 self.attenuators[self.connect_network["attenuator"]].set_atten(0) 908 data = start_wifi_background_scan(self.dut, self.default_batch_scan_setting) 909 idx = data["Index"] 910 scan_rt = data["ScanElapsedRealtime"] 911 self.log.info("Wifi background scan started with index: {} rt {}". 912 format(idx, scan_rt)) 913 #generating event wait time from scan setting plus leeway 914 scan_time, scan_channels = get_scan_time_and_channels( 915 self.wifi_chs, 916 self.default_batch_scan_setting, 917 self.stime_channel) 918 #default number buckets 919 number_bucket = 10 920 time_cache = self.default_batch_scan_setting['periodInMs'] * number_bucket #default cache 921 #add 2 seconds extra time for switch between the channel for connection scan 922 #multiply cache time by two to account for scheduler changing period 923 wait_time = (time_cache * 2 + scan_time) / 1000 + self.leeway + 2 924 result_flag = 0 925 try: 926 for snumber in range(1,7): 927 event_name = "{}{}onResults".format(EVENT_TAG, idx) 928 self.log.info("Waiting for event: {}".format(event_name )) 929 event = self.dut.ed.pop_event(event_name, wait_time) 930 self.log.debug("Event onResults: {}".format(event )) 931 results = event["data"]["Results"] 932 bssids, validity = self.proces_and_valid_batch_scan_result( 933 results, scan_rt, 934 event["data"][KEY_RET], 935 self.default_batch_scan_setting) 936 self.log.info("Scan number: {}\n Buckets: {}\n BSSID: {}". 937 format(snumber, len(results), bssids)) 938 asserts.assert_true(bssids >= 1, "Not able to fetch scan result") 939 if snumber == 1: 940 self.log.info("Try to connect AP while waiting for event: {}". 941 format(event_name )) 942 asserts.assert_true(self.connect_to_reference_network(), NETWORK_ERROR) 943 time.sleep(10) #wait for connection to be active 944 asserts.assert_true(check_internet_connection(self.dut, self.ping_addr), 945 "Error, No internet connection for current network") 946 elif snumber == 3: 947 self.log.info("Kicking PNO for reference network") 948 self.attenuators[self.connect_network["attenuator"]].set_atten(90) 949 elif snumber == 4: 950 self.log.info("Bring back device for PNO connection") 951 current_network = self.dut.droid.wifiGetConnectionInfo() 952 self.log.info("Current network: {}".format(current_network)) 953 asserts.assert_true('network_id' in current_network, NETWORK_ID_ERROR) 954 asserts.assert_true(current_network['network_id'] == -1, 955 "Device is still connected to network {}". 956 format(current_network[WifiEnums.SSID_KEY])) 957 self.attenuators[self.connect_network["attenuator"]].set_atten(0) 958 time.sleep(10) #wait for connection to take place before waiting for scan result 959 elif snumber == 6: 960 self.log.info("Check connection through PNO for reference network") 961 current_network = self.dut.droid.wifiGetConnectionInfo() 962 self.log.info("Current network: {}".format(current_network)) 963 asserts.assert_true('network_id' in current_network, NETWORK_ID_ERROR) 964 asserts.assert_true(current_network['network_id'] >= 0, NETWORK_ERROR) 965 time.sleep(10) #wait for connection to be active 966 asserts.assert_true(check_internet_connection(self.dut, self.ping_addr), 967 "Error, No internet connection for current network") 968 wifi_forget_network(self.dut, self.connect_network["ssid"]) 969 except Empty as error: 970 raise AssertionError("Event did not triggered for batch scan {}". 971 format(error)) 972 finally: 973 self.dut.droid.wifiScannerStopBackgroundScan(idx) 974 self.dut.ed.clear_all_events() 975 976 def test_wifi_scanner_single_scan_channel_sanity(self): 977 """Test WiFi scanner single scan for mix channel with default setting 978 parameters. 979 980 1. Start WifiScanner single scan for mix channels with default setting 981 parameters. 982 2. Verify that scan results match with respective scan settings. 983 """ 984 scan_setting = { "channels": self.wifi_chs.MIX_CHANNEL_SCAN, 985 "periodInMs": SCANTIME, 986 "reportEvents": WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN } 987 self.wifi_scanner_single_scan(scan_setting) 988 989 def test_wifi_scanner_batch_scan_channel_sanity(self): 990 """Test WiFi scanner batch scan for mix channel with default setting 991 parameters to report the result on buffer full. 992 993 1. Start WifiScanner batch scan for mix channels with default setting 994 parameters. 995 2. Verify that scan results match with respective scan settings. 996 """ 997 scan_setting = { "channels": self.wifi_chs.MIX_CHANNEL_SCAN, 998 "periodInMs": SCANTIME, 999 "reportEvents": WifiEnums.REPORT_EVENT_AFTER_BUFFER_FULL} 1000 self.wifi_scanner_batch_scan(scan_setting) 1001 1002 def test_wifi_scanner_batch_scan_period_too_short(self): 1003 """Test WiFi scanner batch scan for band with too short period time. 1004 1005 1. Start WifiScanner batch scan for both band with interval period as 5s. 1006 2. Verify that scan is not started.""" 1007 scan_setting = { "band": WifiEnums.WIFI_BAND_BOTH_WITH_DFS, 1008 "periodInMs": 5000, 1009 "reportEvents": WifiEnums.REPORT_EVENT_AFTER_BUFFER_FULL} 1010 self.start_wifi_scanner_background_scan_expect_failure(scan_setting); 1011 1012 def test_wifi_scanner_single_scan_in_isolated(self): 1013 """Test WiFi scanner in isolated environment with default scan settings. 1014 1015 1. Created isolated environment by attenuating the single by 90db 1016 2. Start WifiScanner single scan for mix channels with default setting 1017 parameters. 1018 3. Verify that empty scan results reported. 1019 """ 1020 self.attenuators[0].set_atten(90) 1021 self.attenuators[1].set_atten(90) 1022 data = start_wifi_single_scan(self.dut, self.default_scan_setting) 1023 idx = data["Index"] 1024 scan_rt = data["ScanElapsedRealtime"] 1025 self.log.info("Wifi single shot scan started with index: {}".format(idx)) 1026 results = [] 1027 #generating event wait time from scan setting plus leeway 1028 scan_time, scan_channels = get_scan_time_and_channels(self.wifi_chs, 1029 self.default_scan_setting, 1030 self.stime_channel) 1031 wait_time = int(scan_time/1000) + self.leeway 1032 try: 1033 event_name = "{}{}onResults".format(EVENT_TAG, idx) 1034 self.log.debug("Waiting for event: {} for time {}".format(event_name, 1035 wait_time)) 1036 event = self.dut.ed.pop_event(event_name, wait_time) 1037 self.log.debug("Event received: {}".format(event)) 1038 results = event["data"]["Results"] 1039 bssids, validity = (self.proces_and_valid_batch_scan_result( 1040 results, scan_rt, 1041 event["data"][KEY_RET], 1042 self.default_scan_setting)) 1043 self.log.info("Scan number Buckets: {}\nTotal BSSID: {}". 1044 format(len(results), bssids)) 1045 asserts.assert_true(bssids == 0, ("Test fail because report scan " 1046 "results reported are not empty")) 1047 except Empty as error: 1048 raise AssertionError("Event did not triggered for in isolated environment {}". 1049 format(error)) 1050 finally: 1051 self.dut.ed.clear_all_events() 1052 self.attenuators[0].set_atten(0) 1053 self.attenuators[1].set_atten(0) 1054 1055 def test_wifi_scanner_with_wifi_off(self): 1056 """Test WiFi scanner single scan when wifi is off. 1057 1058 1. Toggle wifi state to off. 1059 2. Start WifiScanner single scan for both band with default scan settings. 1060 3. Verify that scan is not started. 1061 """ 1062 self.log.debug("Make sure wifi is off.") 1063 wifi_toggle_state(self.dut, False) 1064 self.start_wifi_scanner_single_scan_expect_failure(self.default_scan_setting) 1065 self.log.debug("Turning wifi back on.") 1066 wifi_toggle_state(self.dut, True) 1067 1068 def test_wifi_scanner_with_invalid_numBssidsPerScan(self): 1069 """Test WiFi scanner single scan with invalid number of bssids reported 1070 per scan. 1071 1072 1. Start WifiScanner single scan with invalid number of bssids reported 1073 per scan. 1074 2. Verify that scan results triggered for default supported number of 1075 bssids per scan. 1076 """ 1077 scan_setting = { 1078 "band": WifiEnums.WIFI_BAND_BOTH_WITH_DFS, 1079 "periodInMs": SCANTIME, 1080 "reportEvents": WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, 1081 'numBssidsPerScan': 33 1082 } 1083 self.wifi_scanner_single_scan(scan_setting) 1084 """ Tests End """ 1085