def test_rtt_mixed_80211mc_supporting_aps_wo_privilege(self): """Scan for APs and perform RTT on one supporting and one non-supporting IEEE 802.11mc APs with the device not having privilege access (expect failures).""" dut = self.android_devices[0] rutils.config_privilege_override(dut, True) rtt_aps = rutils.scan_with_rtt_support_constraint(dut, True) non_rtt_aps = rutils.scan_with_rtt_support_constraint(dut, False) mix_list = [rtt_aps[0], non_rtt_aps[0]] dut.log.debug("Visible non-IEEE 802.11mc APs=%s", mix_list) events = rutils.run_ranging(dut, mix_list, self.NUM_ITER, self.TIME_BETWEEN_ITERATIONS) stats = rutils.analyze_results(events, self.rtt_reference_distance_mm, self.rtt_reference_distance_margin_mm, self.rtt_min_expected_rssi_dbm, self.lci_reference, self.lcr_reference) dut.log.debug("Stats=%s", stats) for bssid, stat in stats.items(): asserts.assert_true(stat['num_no_results'] == 0, "Missing (timed-out) results", extras=stats) if bssid == rtt_aps[0][wutils.WifiEnums.BSSID_KEY]: asserts.assert_false(stat['any_lci_mismatch'], "LCI mismatch", extras=stats) asserts.assert_false(stat['any_lcr_mismatch'], "LCR mismatch", extras=stats) asserts.assert_equal(stat['num_invalid_rssi'], 0, "Invalid RSSI", extras=stats) asserts.assert_true( stat['num_failures'] <= self.rtt_max_failure_rate_two_sided_rtt_percentage * stat['num_results'] / 100, "Failure rate is too high", extras=stats) asserts.assert_true( stat['num_range_out_of_margin'] <= self.rtt_max_margin_exceeded_rate_two_sided_rtt_percentage * stat['num_success_results'] / 100, "Results exceeding error margin rate is too high", extras=stats) else: asserts.assert_true( stat['num_failures'] == self.NUM_ITER, "All one-sided RTT requests must fail when executed without privilege", extras=stats) for code in stat['status_codes']: asserts.assert_true( code == rconsts. EVENT_CB_RANGING_STATUS_RESPONDER_DOES_NOT_SUPPORT_IEEE80211MC, "Expected non-support error code", extras=stats) asserts.explicit_pass("RTT test done", extras=stats)
def test_rtt_non_80211mc_supporting_ap_faked_as_supporting(self): """Scan for APs which do not support IEEE 802.11mc, maliciously modify the Responder config to indicate support and pass-through to service. Verify that get an error result. """ dut = self.android_devices[0] non_rtt_aps = rutils.select_best_scan_results( rutils.scan_with_rtt_support_constraint(dut, False), select_count=1) dut.log.debug("Visible non-IEEE 802.11mc APs=%s", non_rtt_aps) asserts.assert_true(len(non_rtt_aps) > 0, "Need at least one AP!") non_rtt_aps = non_rtt_aps[0:1] # pick first non_rtt_aps[0][rconsts.SCAN_RESULT_KEY_RTT_RESPONDER] = True # falsify dut.log.debug("Visible non-IEEE 802.11mc APs=%s", non_rtt_aps) events = rutils.run_ranging(dut, non_rtt_aps, self.NUM_ITER, self.TIME_BETWEEN_ITERATIONS) stats = rutils.analyze_results(events, self.rtt_reference_distance_mm, self.rtt_reference_distance_margin_mm, self.rtt_min_expected_rssi_dbm, self.lci_reference, self.lcr_reference) dut.log.debug("Stats=%s", stats) for bssid, stat in stats.items(): asserts.assert_true(stat['num_no_results'] == 0, "Missing (timed-out) results", extras=stats) asserts.assert_true( stat['num_failures'] == self.NUM_ITER, "Failures expected for falsified responder config", extras=stats) asserts.explicit_pass("RTT test done", extras=stats)
def test_rtt_non_80211mc_supporting_aps_wo_privilege(self): """Scan for APs and perform RTT on non-IEEE 802.11mc supporting APs with the device not having privilege access (expect failures). """ dut = self.android_devices[0] rutils.config_privilege_override(dut, True) non_rtt_aps = rutils.select_best_scan_results( rutils.scan_with_rtt_support_constraint(dut, False), select_count=1) dut.log.debug("Visible non-IEEE 802.11mc APs=%s", non_rtt_aps) asserts.assert_true(len(non_rtt_aps) > 0, "Need at least one AP!") events = rutils.run_ranging(dut, non_rtt_aps, self.NUM_ITER, self.TIME_BETWEEN_ITERATIONS) stats = rutils.analyze_results(events, self.rtt_reference_distance_mm, self.rtt_reference_distance_margin_mm, self.rtt_min_expected_rssi_dbm, self.lci_reference, self.lcr_reference) dut.log.debug("Stats=%s", stats) for bssid, stat in stats.items(): asserts.assert_true(stat['num_no_results'] == 0, "Missing (timed-out) results", extras=stats) asserts.assert_true( stat['num_failures'] == self.NUM_ITER, "All one-sided RTT requests must fail when executed without privilege", extras=stats) for code in stat['status_codes']: asserts.assert_true( code == rconsts. EVENT_CB_RANGING_STATUS_RESPONDER_DOES_NOT_SUPPORT_IEEE80211MC, "Expected non-support error code", extras=stats) asserts.explicit_pass("RTT test done", extras=stats)
def test_rtt_supporting_ap_only(self): """Scan for APs and perform RTT only to those which support 802.11mc. Stress test: repeat ranging to the same AP. Verify rate of success and stability of results. """ dut = self.android_devices[0] rtt_supporting_aps = rutils.scan_with_rtt_support_constraint(dut, True, repeat=10) dut.log.debug("RTT Supporting APs=%s", rtt_supporting_aps) num_iter = self.stress_test_min_iteration_count max_peers = dut.droid.wifiRttMaxPeersInRequest() asserts.assert_true( len(rtt_supporting_aps) > 0, "Need at least one AP which supports 802.11mc!") if len(rtt_supporting_aps) > max_peers: rtt_supporting_aps = rtt_supporting_aps[0:max_peers] events = rutils.run_ranging(dut, rtt_supporting_aps, num_iter, 0, self.stress_test_target_run_time_sec) stats = rutils.analyze_results(events, self.rtt_reference_distance_mm, self.rtt_reference_distance_margin_mm, self.rtt_min_expected_rssi_dbm, self.lci_reference, self.lcr_reference, summary_only=True) dut.log.debug("Stats=%s", stats) for bssid, stat in stats.items(): asserts.assert_true(stat['num_no_results'] == 0, "Missing (timed-out) results", extras=stats) asserts.assert_false(stat['any_lci_mismatch'], "LCI mismatch", extras=stats) asserts.assert_false(stat['any_lcr_mismatch'], "LCR mismatch", extras=stats) asserts.assert_equal(stat['num_invalid_rssi'], 0, "Invalid RSSI", extras=stats) asserts.assert_true( stat['num_failures'] <= self.rtt_max_failure_rate_two_sided_rtt_percentage * stat['num_results'] / 100, "Failure rate is too high", extras=stats) asserts.assert_true( stat['num_range_out_of_margin'] <= self.rtt_max_margin_exceeded_rate_two_sided_rtt_percentage * stat['num_success_results'] / 100, "Results exceeding error margin rate is too high", extras=stats) asserts.explicit_pass("RTT test done", extras=stats)
def run_test_rtt_80211mc_supporting_aps(self, dut, accuracy_evaluation=False): """Scan for APs and perform RTT only to those which support 802.11mc Args: dut: test device accuracy_evaluation: False - only evaluate success rate. True - evaluate both success rate and accuracy default is False. """ rtt_supporting_aps = rutils.select_best_scan_results( rutils.scan_with_rtt_support_constraint(dut, True, repeat=10), select_count=2) dut.log.debug("RTT Supporting APs=%s", rtt_supporting_aps) events = rutils.run_ranging(dut, rtt_supporting_aps, self.NUM_ITER, self.TIME_BETWEEN_ITERATIONS) stats = rutils.analyze_results(events, self.rtt_reference_distance_mm, self.rtt_reference_distance_margin_mm, self.rtt_min_expected_rssi_dbm, self.lci_reference, self.lcr_reference) dut.log.debug("Stats=%s", stats) for bssid, stat in stats.items(): asserts.assert_true(stat['num_no_results'] == 0, "Missing (timed-out) results", extras=stats) asserts.assert_false(stat['any_lci_mismatch'], "LCI mismatch", extras=stats) asserts.assert_false(stat['any_lcr_mismatch'], "LCR mismatch", extras=stats) asserts.assert_false(stat['invalid_num_attempted'], "Invalid (0) number of attempts", extras=stats) asserts.assert_false(stat['invalid_num_successful'], "Invalid (0) number of successes", extras=stats) asserts.assert_equal(stat['num_invalid_rssi'], 0, "Invalid RSSI", extras=stats) asserts.assert_true( stat['num_failures'] <= self.rtt_max_failure_rate_two_sided_rtt_percentage * stat['num_results'] / 100, "Failure rate is too high", extras=stats) if accuracy_evaluation: asserts.assert_true( stat['num_range_out_of_margin'] <= self.rtt_max_margin_exceeded_rate_two_sided_rtt_percentage * stat['num_success_results'] / 100, "Results exceeding error margin rate is too high", extras=stats) asserts.explicit_pass("RTT test done", extras=stats)
def run_test_rtt_non_80211mc_supporting_aps(self, dut, accuracy_evaluation=False): """Scan for APs and perform RTT on non-IEEE 802.11mc supporting APs Args: dut: test device accuracy_evaluation: False - only evaluate success rate. True - evaluate both success rate and accuracy default is False. """ asserts.skip_if( not dut.rtt_capabilities[rconsts.CAP_RTT_ONE_SIDED_SUPPORTED], "Device does not support one-sided RTT") non_rtt_aps = rutils.select_best_scan_results( rutils.scan_with_rtt_support_constraint(dut, False), select_count=1) dut.log.debug("Visible non-IEEE 802.11mc APs=%s", non_rtt_aps) asserts.assert_true(len(non_rtt_aps) > 0, "Need at least one AP!") events = rutils.run_ranging(dut, non_rtt_aps, self.NUM_ITER, self.TIME_BETWEEN_ITERATIONS) stats = rutils.analyze_results(events, self.rtt_reference_distance_mm, self.rtt_reference_distance_margin_mm, self.rtt_min_expected_rssi_dbm, [], []) dut.log.debug("Stats=%s", stats) for bssid, stat in stats.items(): asserts.assert_true(stat['num_no_results'] == 0, "Missing (timed-out) results", extras=stats) asserts.assert_false(stat['any_lci_mismatch'], "LCI mismatch", extras=stats) asserts.assert_false(stat['any_lcr_mismatch'], "LCR mismatch", extras=stats) asserts.assert_equal(stat['num_invalid_rssi'], 0, "Invalid RSSI", extras=stats) asserts.assert_true( stat['num_failures'] <= self.rtt_max_failure_rate_one_sided_rtt_percentage * stat['num_results'] / 100, "Failure rate is too high", extras=stats) if accuracy_evaluation: asserts.assert_true( stat['num_range_out_of_margin'] <= self.rtt_max_margin_exceeded_rate_one_sided_rtt_percentage * stat['num_success_results'] / 100, "Results exceeding error margin rate is too high", extras=stats) asserts.explicit_pass("RTT test done", extras=stats)
def test_throttling(self): """Request sequential range operations using a bogus UID (which will translate as a throttled process) and similarly using the ACTS/sl4a as the source (a foreground/unthrottled process).""" dut = self.android_devices[0] max_peers = dut.droid.wifiRttMaxPeersInRequest() # Need to use a random number since the system keeps states and so the # background uid will be throttled on the next run of this script fake_uid = [random.randint(10, 9999)] aps = rutils.select_best_scan_results( rutils.scan_with_rtt_support_constraint(dut, True, repeat=10), select_count=1) dut.log.info("RTT Supporting APs=%s", aps) asserts.assert_true( len(aps) > 0, "Need at least one AP which supports 802.11mc!") if len(aps) > max_peers: aps = aps[0:max_peers] id1 = dut.droid.wifiRttStartRangingToAccessPoints(aps) # as ACTS/sl4a id2 = dut.droid.wifiRttStartRangingToAccessPoints(aps, fake_uid) id3 = dut.droid.wifiRttStartRangingToAccessPoints(aps, fake_uid) id4 = dut.droid.wifiRttStartRangingToAccessPoints(aps) # as ACTS/sl4a rutils.wait_for_event( dut, rutils.decorate_event(rconsts.EVENT_CB_RANGING_ON_RESULT, id1)) rutils.wait_for_event( dut, rutils.decorate_event(rconsts.EVENT_CB_RANGING_ON_RESULT, id2)) rutils.wait_for_event( dut, rutils.decorate_event(rconsts.EVENT_CB_RANGING_ON_FAIL, id3)) rutils.wait_for_event( dut, rutils.decorate_event(rconsts.EVENT_CB_RANGING_ON_RESULT, id4))
def test_cancel_ranging(self): """Request a 'large' number of range operations with various UIDs (using the work-source API), then cancel some of them. We can't guarantee a reaction time - it is possible that a cancelled test was already finished and it's results dispatched back. The test therefore stacks the request queue. The sequence is: - Request: - 50 tests @ UIDs = {uid1, uid2, uid3} - 2 tests @ UIDs = {uid2, uid3} - 1 test2 @ UIDs = {uid1, uid2, uid3} - Cancel UIDs = {uid2, uid3} Expect to receive only 51 results. """ dut = self.android_devices[0] max_peers = dut.droid.wifiRttMaxPeersInRequest() all_uids = [1000, 20, 30] # 1000 = System Server (makes requests foreground) some_uids = [20, 30] aps = rutils.select_best_scan_results( rutils.scan_with_rtt_support_constraint(dut, True, repeat=10), select_count=1) dut.log.info("RTT Supporting APs=%s", aps) asserts.assert_true( len(aps) > 0, "Need at least one AP which supports 802.11mc!") if len(aps) > max_peers: aps = aps[0:max_peers] group1_ids = [] group2_ids = [] group3_ids = [] # step 1: request <spam_limit> ranging operations on [uid1, uid2, uid3] for i in range(self.SPAMMING_LIMIT): group1_ids.append( dut.droid.wifiRttStartRangingToAccessPoints(aps, all_uids)) # step 2: request 2 ranging operations on [uid2, uid3] for i in range(2): group2_ids.append( dut.droid.wifiRttStartRangingToAccessPoints(aps, some_uids)) # step 3: request 1 ranging operation on [uid1, uid2, uid3] for i in range(1): group3_ids.append( dut.droid.wifiRttStartRangingToAccessPoints(aps, all_uids)) # step 4: cancel ranging requests on [uid2, uid3] dut.droid.wifiRttCancelRanging(some_uids) # collect results for i in range(len(group1_ids)): rutils.wait_for_event( dut, rutils.decorate_event(rconsts.EVENT_CB_RANGING_ON_RESULT, group1_ids[i])) time.sleep( rutils.EVENT_TIMEOUT) # optimize time-outs below to single one for i in range(len(group2_ids)): rutils.fail_on_event( dut, rutils.decorate_event(rconsts.EVENT_CB_RANGING_ON_RESULT, group2_ids[i]), 0) for i in range(len(group3_ids)): rutils.wait_for_event( dut, rutils.decorate_event(rconsts.EVENT_CB_RANGING_ON_RESULT, group3_ids[i]))
def test_legacy_rtt_80211mc_supporting_aps(self): """Scan for APs and perform RTT only to those which support 802.11mc - using the LEGACY API! """ dut = self.android_devices[0] rtt_supporting_aps = rutils.select_best_scan_results( rutils.scan_with_rtt_support_constraint(dut, True, repeat=10), select_count=2) dut.log.debug("RTT Supporting APs=%s", rtt_supporting_aps) rtt_configs = [] for ap in rtt_supporting_aps: rtt_configs.append(self.rtt_config_from_scan_result(ap)) dut.log.debug("RTT configs=%s", rtt_configs) results = [] num_missing = 0 num_failed_aborted = 0 for i in range(self.NUM_ITER): idx = dut.droid.wifiRttStartRanging(rtt_configs) event = None try: events = dut.ed.pop_events("WifiRttRanging%d" % idx, 30) dut.log.debug("Event=%s", events) for event in events: if rconsts.EVENT_CB_RANGING_KEY_RESULTS in event["data"]: results.append(event["data"][ rconsts.EVENT_CB_RANGING_KEY_RESULTS]) else: self.log.info("RTT failed/aborted - %s", event) results.append([]) num_failed_aborted = num_failed_aborted + 1 except queue.Empty: self.log.debug("Waiting for RTT event timed out.") results.append([]) num_missing = num_missing + 1 # basic error checking: # 1. no missing # 2. no full failed/aborted (i.e. operation not even tried) # 3. overall (all BSSIDs) success rate > threshold asserts.assert_equal(num_missing, 0, "Missing results (timeout waiting for event)", extras={"data": results}) asserts.assert_equal(num_failed_aborted, 0, "Failed or aborted operations (not tried)", extras={"data": results}) num_results = 0 num_errors = 0 for result_group in results: num_results = num_results + len(result_group) for result in result_group: if result["status"] != 0: num_errors = num_errors + 1 extras = [ results, { "num_results": num_results, "num_errors": num_errors } ] asserts.assert_true( num_errors <= self.rtt_max_failure_rate_two_sided_rtt_percentage * num_results / 100, "Failure rate is too high", extras={"data": extras}) asserts.explicit_pass("RTT test done", extras={"data": extras})
def test_rtt_in_and_after_softap_mode(self): """Verify behavior when a SoftAP is enabled and then disabled on the device: - SAP Enabled: depending on device characteristics RTT may succeed or fail. - SAP Disabled: RTT must now succeed. """ supp_required_params = ("dbs_supported_models", ) self.unpack_userparams(supp_required_params) dut = self.android_devices[0] rtt_supporting_aps = rutils.select_best_scan_results( rutils.scan_with_rtt_support_constraint(dut, True, repeat=10), select_count=1) dut.log.debug("RTT Supporting APs=%s", rtt_supporting_aps) # phase 1 (pre-SAP) events = rutils.run_ranging(dut, rtt_supporting_aps, self.NUM_ITER, self.TIME_BETWEEN_ITERATIONS) stats = rutils.analyze_results(events, self.rtt_reference_distance_mm, self.rtt_reference_distance_margin_mm, self.rtt_min_expected_rssi_dbm, self.lci_reference, self.lcr_reference) dut.log.debug("Stats Phase 1 (pre-SAP)=%s", stats) for bssid, stat in stats.items(): asserts.assert_true( stat['num_no_results'] == 0, "Phase 1 (pre-SAP) missing (timed-out) results", extras=stats) # phase 2 (SAP) wutils.start_wifi_tethering(dut, self.SOFT_AP_SSID, self.SOFT_AP_PASSWORD, band=WIFI_CONFIG_APBAND_5G, hidden=False) time.sleep(self.WAIT_FOR_CONFIG_CHANGES_SEC) if dut.model not in self.dbs_supported_models: rutils.wait_for_event(dut, rconsts.BROADCAST_WIFI_RTT_NOT_AVAILABLE) asserts.assert_false(dut.droid.wifiIsRttAvailable(), "RTT is available") events = rutils.run_ranging(dut, rtt_supporting_aps, self.NUM_ITER, self.TIME_BETWEEN_ITERATIONS) stats = rutils.analyze_results(events, self.rtt_reference_distance_mm, self.rtt_reference_distance_margin_mm, self.rtt_min_expected_rssi_dbm, self.lci_reference, self.lcr_reference) dut.log.debug("Stats Phase 2 (SAP)=%s", stats) for bssid, stat in stats.items(): if dut.model in self.dbs_supported_models: asserts.assert_true( stat['num_no_results'] == 0, "Phase 2 (SAP) missing (timed-out) results", extras=stats) else: asserts.assert_true( stat['num_success_results'] == 0, "Phase 2 (SAP) valid results - but unexpected in SAP!?", extras=stats) # phase 3 (post-SAP) # enabling Wi-Fi first: on some devices this will also disable SAP # (that's the scenario we're primarily testing). Additionally, # explicitly disable SAP (which may be a NOP on some devices). wutils.wifi_toggle_state(dut, True) time.sleep(self.WAIT_FOR_CONFIG_CHANGES_SEC) wutils.stop_wifi_tethering(dut) if dut.model not in self.dbs_supported_models: rutils.wait_for_event(dut, rconsts.BROADCAST_WIFI_RTT_AVAILABLE) asserts.assert_true(dut.droid.wifiIsRttAvailable(), "RTT is not available") events = rutils.run_ranging(dut, rtt_supporting_aps, self.NUM_ITER, self.TIME_BETWEEN_ITERATIONS) stats = rutils.analyze_results(events, self.rtt_reference_distance_mm, self.rtt_reference_distance_margin_mm, self.rtt_min_expected_rssi_dbm, self.lci_reference, self.lcr_reference) dut.log.debug("Stats Phase 3 (post-SAP)=%s", stats) for bssid, stat in stats.items(): asserts.assert_true( stat['num_no_results'] == 0, "Phase 3 (post-SAP) missing (timed-out) results", extras=stats)