diff options
49 files changed, 9365 insertions, 8297 deletions
diff --git a/acts/framework/acts/controllers/access_point.py b/acts/framework/acts/controllers/access_point.py index 313fcf999d..ff6eb12648 100755 --- a/acts/framework/acts/controllers/access_point.py +++ b/acts/framework/acts/controllers/access_point.py @@ -17,6 +17,7 @@ import collections import ipaddress import logging +import os import time from acts import logger @@ -38,6 +39,12 @@ ACTS_CONTROLLER_CONFIG_NAME = 'AccessPoint' ACTS_CONTROLLER_REFERENCE_NAME = 'access_points' _BRCTL = 'brctl' +LIFETIME = 180 +PROC_NET_SNMP6 = '/proc/net/snmp6' +SCAPY_INSTALL_COMMAND = 'sudo python setup.py install' +RA_MULTICAST_ADDR = '33:33:00:00:00:01' +RA_SCRIPT = 'sendra.py' + def create(configs): """Creates ap controllers from a json config. @@ -142,6 +149,7 @@ class AccessPoint(object): self.wlan_5g = self.wlan[1] self.lan = self.interfaces.get_lan_interface() self.__initial_ap() + self.scapy_install_path = None def __initial_ap(self): """Initial AP interfaces. @@ -149,40 +157,27 @@ class AccessPoint(object): Bring down hostapd if instance is running, bring down all bridge interfaces. """ + # This is necessary for Gale/Whirlwind flashed with dev channel image + # Unused interfaces such as existing hostapd daemon, guest, mesh + # interfaces need to be brought down as part of the AP initialization + # process, otherwise test would fail. try: - # This is necessary for Gale/Whirlwind flashed with dev channel image - # Unused interfaces such as existing hostapd daemon, guest, mesh - # interfaces need to be brought down as part of the AP initialization - # process, otherwise test would fail. - try: - self.ssh.run('stop hostapd') - except job.Error: - self.log.debug('No hostapd running') - # Bring down all wireless interfaces - for iface in self.wlan: - WLAN_DOWN = 'ifconfig {} down'.format(iface) - self.ssh.run(WLAN_DOWN) - # Bring down all bridge interfaces - bridge_interfaces = self.interfaces.get_bridge_interface() - if bridge_interfaces: - for iface in bridge_interfaces: - BRIDGE_DOWN = 'ifconfig {} down'.format(iface) - BRIDGE_DEL = 'brctl delbr {}'.format(iface) - self.ssh.run(BRIDGE_DOWN) - self.ssh.run(BRIDGE_DEL) - except Exception: - # TODO(b/76101464): APs may not clean up properly from previous - # runs. Rebooting the AP can put them back into the correct state. - self.log.exception('Unable to bring down hostapd. Rebooting.') - # Reboot the AP. - try: - self.ssh.run('reboot') - # This sleep ensures the device had time to go down. - time.sleep(10) - self.ssh.run('echo connected', timeout=300) - except Exception as e: - self.log.exception("Error in rebooting AP: %s", e) - raise + self.ssh.run('stop wpasupplicant') + self.ssh.run('stop hostapd') + except job.Error: + self.log.debug('No hostapd running') + # Bring down all wireless interfaces + for iface in self.wlan: + WLAN_DOWN = 'ifconfig {} down'.format(iface) + self.ssh.run(WLAN_DOWN) + # Bring down all bridge interfaces + bridge_interfaces = self.interfaces.get_bridge_interface() + if bridge_interfaces: + for iface in bridge_interfaces: + BRIDGE_DOWN = 'ifconfig {} down'.format(iface) + BRIDGE_DEL = 'brctl delbr {}'.format(iface) + self.ssh.run(BRIDGE_DOWN) + self.ssh.run(BRIDGE_DEL) def start_ap(self, hostapd_config, additional_parameters=None): """Starts as an ap using a set of configurations. @@ -409,3 +404,60 @@ class AccessPoint(object): configs = (iface_wlan, iface_lan, bridge_ip) return configs + + def install_scapy(self, scapy_path, send_ra_path): + """Install scapy + + Args: + scapy_path: path where scapy tar file is located on server + send_ra_path: path where sendra path is located on server + """ + self.scapy_install_path = self.ssh.run('mktemp -d').stdout.rstrip() + self.log.info("Scapy install path: %s" % self.scapy_install_path) + self.ssh.send_file(scapy_path, self.scapy_install_path) + self.ssh.send_file(send_ra_path, self.scapy_install_path) + + scapy = os.path.join(self.scapy_install_path, scapy_path.split('/')[-1]) + + untar_res = self.ssh.run( + 'tar -xvf %s -C %s' % (scapy, self.scapy_install_path)) + + instl_res = self.ssh.run( + 'cd %s; %s' % (self.scapy_install_path, SCAPY_INSTALL_COMMAND)) + + def cleanup_scapy(self): + """ Cleanup scapy """ + if self.scapy_install_path: + cmd = 'rm -rf %s' % self.scapy_install_path + self.log.info("Cleaning up scapy %s" % cmd) + output = self.ssh.run(cmd) + self.scapy_install_path = None + + def send_ra(self, iface, mac=RA_MULTICAST_ADDR, interval=1, count=None, + lifetime=LIFETIME, rtt=0): + """Invoke scapy and send RA to the device. + + Args: + iface: string of the WiFi interface to use for sending packets. + mac: string HWAddr/MAC address to send the packets to. + interval: int Time to sleep between consecutive packets. + count: int Number of packets to be sent. + lifetime: int original RA's router lifetime in seconds. + rtt: retrans timer of the RA packet + """ + scapy_command = os.path.join(self.scapy_install_path, RA_SCRIPT) + options = ' -m %s -i %d -c %d -l %d -in %s -rtt %s' % ( + mac, interval, count, lifetime, iface, rtt) + self.log.info("Scapy cmd: %s" % scapy_command + options) + res = self.ssh.run(scapy_command + options) + + def get_icmp6intype134(self): + """Read the value of Icmp6InType134 and return integer. + + Returns: + Integer value >0 if grep is successful; 0 otherwise. + """ + ra_count_str = self.ssh.run('grep Icmp6InType134 %s || true' % + PROC_NET_SNMP6).stdout + if ra_count_str: + return int(ra_count_str.split()[1]) diff --git a/acts/framework/acts/test_utils/bt/BluetoothBaseTest.py b/acts/framework/acts/test_utils/bt/BluetoothBaseTest.py index 21d63c7810..e093307422 100644 --- a/acts/framework/acts/test_utils/bt/BluetoothBaseTest.py +++ b/acts/framework/acts/test_utils/bt/BluetoothBaseTest.py @@ -131,8 +131,6 @@ class BluetoothBaseTest(BaseTestClass): return _safe_wrap_test_case def setup_class(self): - self.device_selector = get_device_selector_dictionary( - self.android_devices) if "reboot_between_test_class" in self.user_params: threads = [] for a in self.android_devices: @@ -144,6 +142,8 @@ class BluetoothBaseTest(BaseTestClass): t.join() if not setup_multiple_devices_for_bt_test(self.android_devices): return False + self.device_selector = get_device_selector_dictionary( + self.android_devices) if "bluetooth_proto_path" in self.user_params: from google import protobuf diff --git a/acts/framework/acts/test_utils/tel/tel_data_utils.py b/acts/framework/acts/test_utils/tel/tel_data_utils.py index ddb57ca243..136a1a5eeb 100644 --- a/acts/framework/acts/test_utils/tel/tel_data_utils.py +++ b/acts/framework/acts/test_utils/tel/tel_data_utils.py @@ -341,7 +341,7 @@ def airplane_mode_test(log, ad, retries=3): if not wait_for_cell_data_connection(log, ad, False): ad.log.error("Failed to disable cell data connection") return False - if verify_internet_connection(log, ad): + if not verify_internet_connection(log, ad, expected_result=False): ad.log.error("Data available in airplane mode.") return False @@ -354,19 +354,9 @@ def airplane_mode_test(log, ad, retries=3): ad.log.error("Failed to enable cell data connection") return False - time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING) - - log.info("Step4 verify internet") - for i in range(retries): - if verify_internet_connection(log, ad): - ad.log.info("Data available on cell.") - break - elif i == retries - 1: - ad.log.error("Data not available on cell.") - return False - else: - ad.log.warning("Attempt %d Data not available on cell" % - (i + 1)) + if not verify_internet_connection(log, ad, retries=5): + ad.log.warning("Data not available on cell") + return False return True finally: toggle_airplane_mode(log, ad, False) @@ -411,7 +401,7 @@ def data_connectivity_single_bearer(log, ad, nw_gen): return False log.info("Step2 Verify internet") - if not verify_internet_connection(log, ad): + if not verify_internet_connection(log, ad, retries=3): ad.log.error("Data not available on cell.") return False @@ -421,7 +411,7 @@ def data_connectivity_single_bearer(log, ad, nw_gen): ad.log.error("Step3 Failed to disable data connection.") return False - if verify_internet_connection(log, ad): + if not verify_internet_connection(log, ad, expected_state=False): ad.log.error("Step3 Data still available when disabled.") return False @@ -430,7 +420,7 @@ def data_connectivity_single_bearer(log, ad, nw_gen): if not wait_for_cell_data_connection(log, ad, True): ad.log.error("Step4 failed to re-enable data.") return False - if not verify_internet_connection(log, ad): + if not verify_internet_connection(log, ad, retries=3): ad.log.error("Data not available on cell.") return False diff --git a/acts/framework/acts/test_utils/tel/tel_test_utils.py b/acts/framework/acts/test_utils/tel/tel_test_utils.py index 8378f173c3..111c0aed7d 100644 --- a/acts/framework/acts/test_utils/tel/tel_test_utils.py +++ b/acts/framework/acts/test_utils/tel/tel_test_utils.py @@ -1868,7 +1868,7 @@ def get_internet_connection_type(log, ad): def verify_http_connection(log, ad, - url="www.google.com", + url="https://www.google.com", retry=5, retry_interval=15, expected_state=True): @@ -1882,26 +1882,21 @@ def verify_http_connection(log, """ for i in range(0, retry + 1): - # b/18899134 httpPing will hang - #try: - # http_response = ad.droid.httpPing(url) - #except: - # http_response = None - # If httpPing failed, it may return {} (if phone just turn off APM) or - # None (regular fail) - state = ad.droid.pingHost(url) - ad.log.info("Connection to %s is %s", url, state) - if expected_state == state: - ad.log.info("Verify Internet connection state is %s succeeded", - str(expected_state)) + try: + http_response = ad.droid.httpPing(url) + except: + http_response = None + if (expected_state and http_response) or (not expected_state + and not http_response): + ad.log.info("Verify http connection to %s is %s as expected", url, + expected_state) return True if i < retry: - ad.log.info( - "Verify Internet connection state=%s failed. Try again", - str(expected_state)) + ad.log.info("Verify http connection to %s is %s failed. Try again", + url, expected_state) time.sleep(retry_interval) - ad.log.info("Verify Internet state=%s failed after %s second", - expected_state, i * retry_interval) + ad.log.info("Verify http connection to %s is %s failed after %s second", + url, expected_state, i * retry_interval) return False @@ -1999,7 +1994,8 @@ def active_file_download_test(log, ad, file_name="5MB", method="chrome"): return task[0](*task[1]) -def verify_internet_connection(log, ad, retries=1): +def verify_internet_connection_by_ping(log, ad, retries=1, + expected_state=True): """Verify internet connection by ping test. Args: @@ -2007,14 +2003,45 @@ def verify_internet_connection(log, ad, retries=1): ad: Android Device Object. """ - for i in range(retries): - ad.log.info("Verify internet connection - attempt %d", i + 1) - dest_to_ping = ["www.google.com", "www.amazon.com", "54.230.144.105"] - for dest in dest_to_ping: + ip_addr = "54.230.144.105" + for dest in ("www.google.com", "www.amazon.com", ip_addr): + for i in range(retries): + ad.log.info("Ping %s - attempt %d", dest, i + 1) result = adb_shell_ping( ad, count=5, timeout=60, loss_tolerance=40, dest_ip=dest) - if result: + if result == expected_state: + ad.log.info( + "Internet connection by ping test to %s is %s as expected", + dest, expected_state) + if dest == ip_addr: + ad.log.warning("Suspect dns failure") + ad.log.info("DNS config: %s", + ad.adb.shell("getprop | grep dns")) + return False return True + else: + ad.log.error( + "Internet connection by ping test to %s is not %s as expected", + dest, expected_state) + return False + + +def verify_internet_connection(log, ad, retries=3, expected_state=True): + """Verify internet connection by ping test and http connection. + + Args: + log: log object + ad: Android Device Object. + + """ + if verify_internet_connection_by_ping( + log, ad, retries=retries, expected_state=expected_state): + return True + for url in ("https://www.google.com", "https://www.amazon.com"): + if verify_http_connection( + log, ad, url=url, retry=retries, + expected_state=expected_state): + return True return False diff --git a/acts/framework/acts/test_utils/wifi/aware/AwareBaseTest.py b/acts/framework/acts/test_utils/wifi/aware/AwareBaseTest.py index 5bba0a714c..668fc74220 100644 --- a/acts/framework/acts/test_utils/wifi/aware/AwareBaseTest.py +++ b/acts/framework/acts/test_utils/wifi/aware/AwareBaseTest.py @@ -23,93 +23,94 @@ from acts.test_utils.wifi.aware import aware_test_utils as autils class AwareBaseTest(BaseTestClass): - def __init__(self, controllers): - super(AwareBaseTest, self).__init__(controllers) - - # message ID counter to make sure all uses are unique - msg_id = 0 - - # offset (in seconds) to separate the start-up of multiple devices. - # De-synchronizes the start-up time so that they don't start and stop scanning - # at the same time - which can lead to very long clustering times. - device_startup_offset = 2 - - def setup_test(self): - required_params = ("aware_default_power_mode", ) - self.unpack_userparams(required_params) - - for ad in self.android_devices: - asserts.skip_if( - not ad.droid.doesDeviceSupportWifiAwareFeature(), - "Device under test does not support Wi-Fi Aware - skipping test") - wutils.wifi_toggle_state(ad, True) - ad.droid.wifiP2pClose() - utils.set_location_service(ad, True) - aware_avail = ad.droid.wifiIsAwareAvailable() - if not aware_avail: - self.log.info('Aware not available. Waiting ...') - autils.wait_for_event(ad, aconsts.BROADCAST_WIFI_AWARE_AVAILABLE) - ad.ed.clear_all_events() - ad.aware_capabilities = autils.get_aware_capabilities(ad) - self.reset_device_parameters(ad) - self.reset_device_statistics(ad) - self.set_power_mode_parameters(ad) - ad.droid.wifiSetCountryCode(wutils.WifiEnums.CountryCode.US) - autils.configure_ndp_allow_any_override(ad, True) - # set randomization interval to 0 (disable) to reduce likelihood of - # interference in tests - autils.configure_mac_random_interval(ad, 0) - - def teardown_test(self): - for ad in self.android_devices: - if not ad.droid.doesDeviceSupportWifiAwareFeature(): - return - ad.droid.wifiP2pClose() - ad.droid.wifiAwareDestroyAll() - self.reset_device_parameters(ad) - autils.validate_forbidden_callbacks(ad) - - def reset_device_parameters(self, ad): - """Reset device configurations which may have been set by tests. Should be + def __init__(self, controllers): + super(AwareBaseTest, self).__init__(controllers) + + # message ID counter to make sure all uses are unique + msg_id = 0 + + # offset (in seconds) to separate the start-up of multiple devices. + # De-synchronizes the start-up time so that they don't start and stop scanning + # at the same time - which can lead to very long clustering times. + device_startup_offset = 2 + + def setup_test(self): + required_params = ("aware_default_power_mode", ) + self.unpack_userparams(required_params) + + for ad in self.android_devices: + asserts.skip_if( + not ad.droid.doesDeviceSupportWifiAwareFeature(), + "Device under test does not support Wi-Fi Aware - skipping test" + ) + wutils.wifi_toggle_state(ad, True) + ad.droid.wifiP2pClose() + utils.set_location_service(ad, True) + aware_avail = ad.droid.wifiIsAwareAvailable() + if not aware_avail: + self.log.info('Aware not available. Waiting ...') + autils.wait_for_event(ad, + aconsts.BROADCAST_WIFI_AWARE_AVAILABLE) + ad.ed.clear_all_events() + ad.aware_capabilities = autils.get_aware_capabilities(ad) + self.reset_device_parameters(ad) + self.reset_device_statistics(ad) + self.set_power_mode_parameters(ad) + ad.droid.wifiSetCountryCode(wutils.WifiEnums.CountryCode.US) + autils.configure_ndp_allow_any_override(ad, True) + # set randomization interval to 0 (disable) to reduce likelihood of + # interference in tests + autils.configure_mac_random_interval(ad, 0) + + def teardown_test(self): + for ad in self.android_devices: + if not ad.droid.doesDeviceSupportWifiAwareFeature(): + return + ad.droid.wifiP2pClose() + ad.droid.wifiAwareDestroyAll() + self.reset_device_parameters(ad) + autils.validate_forbidden_callbacks(ad) + + def reset_device_parameters(self, ad): + """Reset device configurations which may have been set by tests. Should be done before tests start (in case previous one was killed without tearing down) and after they end (to leave device in usable state). Args: ad: device to be reset """ - ad.adb.shell("cmd wifiaware reset") + ad.adb.shell("cmd wifiaware reset") - def reset_device_statistics(self, ad): - """Reset device statistics. + def reset_device_statistics(self, ad): + """Reset device statistics. Args: ad: device to be reset """ - ad.adb.shell("cmd wifiaware native_cb get_cb_count --reset") + ad.adb.shell("cmd wifiaware native_cb get_cb_count --reset") - def set_power_mode_parameters(self, ad): - """Set the power configuration DW parameters for the device based on any + def set_power_mode_parameters(self, ad): + """Set the power configuration DW parameters for the device based on any configuration overrides (if provided)""" - if self.aware_default_power_mode == "INTERACTIVE": - autils.config_settings_high_power(ad) - elif self.aware_default_power_mode == "NON_INTERACTIVE": - autils.config_settings_low_power(ad) - else: - asserts.assert_false( - "The 'aware_default_power_mode' configuration must be INTERACTIVE or " - "NON_INTERACTIVE" - ) - - def get_next_msg_id(self): - """Increment the message ID and returns the new value. Guarantees that + if self.aware_default_power_mode == "INTERACTIVE": + autils.config_settings_high_power(ad) + elif self.aware_default_power_mode == "NON_INTERACTIVE": + autils.config_settings_low_power(ad) + else: + asserts.assert_false( + "The 'aware_default_power_mode' configuration must be INTERACTIVE or " + "NON_INTERACTIVE") + + def get_next_msg_id(self): + """Increment the message ID and returns the new value. Guarantees that each call to the method returns a unique value. Returns: a new message id value. """ - self.msg_id = self.msg_id + 1 - return self.msg_id + self.msg_id = self.msg_id + 1 + return self.msg_id - def on_fail(self, test_name, begin_time): - for ad in self.android_devices: - ad.take_bug_report(test_name, begin_time) - ad.cat_adb_log(test_name, begin_time) + def on_fail(self, test_name, begin_time): + for ad in self.android_devices: + ad.take_bug_report(test_name, begin_time) + ad.cat_adb_log(test_name, begin_time) diff --git a/acts/framework/acts/test_utils/wifi/aware/aware_test_utils.py b/acts/framework/acts/test_utils/wifi/aware/aware_test_utils.py index eada0975c0..cbed7dd9b9 100644 --- a/acts/framework/acts/test_utils/wifi/aware/aware_test_utils.py +++ b/acts/framework/acts/test_utils/wifi/aware/aware_test_utils.py @@ -39,11 +39,11 @@ WAIT_FOR_CLUSTER = 5 def decorate_event(event_name, id): - return '%s_%d' % (event_name, id) + return '%s_%d' % (event_name, id) def wait_for_event(ad, event_name, timeout=EVENT_TIMEOUT): - """Wait for the specified event or timeout. + """Wait for the specified event or timeout. Args: ad: The android device @@ -52,19 +52,21 @@ def wait_for_event(ad, event_name, timeout=EVENT_TIMEOUT): Returns: The event (if available) """ - prefix = '' - if hasattr(ad, 'pretty_name'): - prefix = '[%s] ' % ad.pretty_name - try: - event = ad.ed.pop_event(event_name, timeout) - ad.log.info('%s%s: %s', prefix, event_name, event['data']) - return event - except queue.Empty: - ad.log.info('%sTimed out while waiting for %s', prefix, event_name) - asserts.fail(event_name) - -def wait_for_event_with_keys(ad, event_name, timeout=EVENT_TIMEOUT, *keyvalues): - """Wait for the specified event contain the key/value pairs or timeout + prefix = '' + if hasattr(ad, 'pretty_name'): + prefix = '[%s] ' % ad.pretty_name + try: + event = ad.ed.pop_event(event_name, timeout) + ad.log.info('%s%s: %s', prefix, event_name, event['data']) + return event + except queue.Empty: + ad.log.info('%sTimed out while waiting for %s', prefix, event_name) + asserts.fail(event_name) + + +def wait_for_event_with_keys(ad, event_name, timeout=EVENT_TIMEOUT, + *keyvalues): + """Wait for the specified event contain the key/value pairs or timeout Args: ad: The android device @@ -74,47 +76,51 @@ def wait_for_event_with_keys(ad, event_name, timeout=EVENT_TIMEOUT, *keyvalues): Returns: The event (if available) """ - def filter_callbacks(event, keyvalues): - for keyvalue in keyvalues: - key, value = keyvalue - if event['data'][key] != value: - return False - return True - - prefix = '' - if hasattr(ad, 'pretty_name'): - prefix = '[%s] ' % ad.pretty_name - try: - event = ad.ed.wait_for_event(event_name, filter_callbacks, timeout, - keyvalues) - ad.log.info('%s%s: %s', prefix, event_name, event['data']) - return event - except queue.Empty: - ad.log.info('%sTimed out while waiting for %s (%s)', prefix, event_name, - keyvalues) - asserts.fail(event_name) + + def filter_callbacks(event, keyvalues): + for keyvalue in keyvalues: + key, value = keyvalue + if event['data'][key] != value: + return False + return True + + prefix = '' + if hasattr(ad, 'pretty_name'): + prefix = '[%s] ' % ad.pretty_name + try: + event = ad.ed.wait_for_event(event_name, filter_callbacks, timeout, + keyvalues) + ad.log.info('%s%s: %s', prefix, event_name, event['data']) + return event + except queue.Empty: + ad.log.info('%sTimed out while waiting for %s (%s)', prefix, + event_name, keyvalues) + asserts.fail(event_name) + def fail_on_event(ad, event_name, timeout=EVENT_TIMEOUT): - """Wait for a timeout period and looks for the specified event - fails if it + """Wait for a timeout period and looks for the specified event - fails if it is observed. Args: ad: The android device event_name: The event to wait for (and fail on its appearance) """ - prefix = '' - if hasattr(ad, 'pretty_name'): - prefix = '[%s] ' % ad.pretty_name - try: - event = ad.ed.pop_event(event_name, timeout) - ad.log.info('%sReceived unwanted %s: %s', prefix, event_name, event['data']) - asserts.fail(event_name, extras=event) - except queue.Empty: - ad.log.info('%s%s not seen (as expected)', prefix, event_name) - return + prefix = '' + if hasattr(ad, 'pretty_name'): + prefix = '[%s] ' % ad.pretty_name + try: + event = ad.ed.pop_event(event_name, timeout) + ad.log.info('%sReceived unwanted %s: %s', prefix, event_name, + event['data']) + asserts.fail(event_name, extras=event) + except queue.Empty: + ad.log.info('%s%s not seen (as expected)', prefix, event_name) + return + def fail_on_event_with_keys(ad, event_name, timeout=EVENT_TIMEOUT, *keyvalues): - """Wait for a timeout period and looks for the specified event which contains + """Wait for a timeout period and looks for the specified event which contains the key/value pairs - fails if it is observed. Args: @@ -123,47 +129,50 @@ def fail_on_event_with_keys(ad, event_name, timeout=EVENT_TIMEOUT, *keyvalues): timeout: Number of seconds to wait keyvalues: (kay, value) pairs """ - def filter_callbacks(event, keyvalues): - for keyvalue in keyvalues: - key, value = keyvalue - if event['data'][key] != value: - return False - return True - - prefix = '' - if hasattr(ad, 'pretty_name'): - prefix = '[%s] ' % ad.pretty_name - try: - event = ad.ed.wait_for_event(event_name, filter_callbacks, timeout, - keyvalues) - ad.log.info('%sReceived unwanted %s: %s', prefix, event_name, event['data']) - asserts.fail(event_name, extras=event) - except queue.Empty: - ad.log.info('%s%s (%s) not seen (as expected)', prefix, event_name, - keyvalues) - return + + def filter_callbacks(event, keyvalues): + for keyvalue in keyvalues: + key, value = keyvalue + if event['data'][key] != value: + return False + return True + + prefix = '' + if hasattr(ad, 'pretty_name'): + prefix = '[%s] ' % ad.pretty_name + try: + event = ad.ed.wait_for_event(event_name, filter_callbacks, timeout, + keyvalues) + ad.log.info('%sReceived unwanted %s: %s', prefix, event_name, + event['data']) + asserts.fail(event_name, extras=event) + except queue.Empty: + ad.log.info('%s%s (%s) not seen (as expected)', prefix, event_name, + keyvalues) + return + def verify_no_more_events(ad, timeout=EVENT_TIMEOUT): - """Verify that there are no more events in the queue. + """Verify that there are no more events in the queue. """ - prefix = '' - if hasattr(ad, 'pretty_name'): - prefix = '[%s] ' % ad.pretty_name - should_fail = False - try: - while True: - event = ad.ed.pop_events('.*', timeout, freq=0) - ad.log.info('%sQueue contains %s', prefix, event) - should_fail = True - except queue.Empty: - if should_fail: - asserts.fail('%sEvent queue not empty' % prefix) - ad.log.info('%sNo events in the queue (as expected)', prefix) - return + prefix = '' + if hasattr(ad, 'pretty_name'): + prefix = '[%s] ' % ad.pretty_name + should_fail = False + try: + while True: + event = ad.ed.pop_events('.*', timeout, freq=0) + ad.log.info('%sQueue contains %s', prefix, event) + should_fail = True + except queue.Empty: + if should_fail: + asserts.fail('%sEvent queue not empty' % prefix) + ad.log.info('%sNo events in the queue (as expected)', prefix) + return def encode_list(list_of_objects): - """Converts the list of strings or bytearrays to a list of b64 encoded + """Converts the list of strings or bytearrays to a list of b64 encoded bytearrays. A None object is treated as a zero-length bytearray. @@ -172,32 +181,33 @@ def encode_list(list_of_objects): list_of_objects: A list of strings or bytearray objects Returns: A list of the same objects, converted to bytes and b64 encoded. """ - encoded_list = [] - for obj in list_of_objects: - if obj is None: - obj = bytes() - if isinstance(obj, str): - encoded_list.append(base64.b64encode(bytes(obj, 'utf-8')).decode('utf-8')) - else: - encoded_list.append(base64.b64encode(obj).decode('utf-8')) - return encoded_list + encoded_list = [] + for obj in list_of_objects: + if obj is None: + obj = bytes() + if isinstance(obj, str): + encoded_list.append( + base64.b64encode(bytes(obj, 'utf-8')).decode('utf-8')) + else: + encoded_list.append(base64.b64encode(obj).decode('utf-8')) + return encoded_list def decode_list(list_of_b64_strings): - """Converts the list of b64 encoded strings to a list of bytearray. + """Converts the list of b64 encoded strings to a list of bytearray. Args: list_of_b64_strings: list of strings, each of which is b64 encoded array Returns: a list of bytearrays. """ - decoded_list = [] - for str in list_of_b64_strings: - decoded_list.append(base64.b64decode(str)) - return decoded_list + decoded_list = [] + for str in list_of_b64_strings: + decoded_list.append(base64.b64decode(str)) + return decoded_list def construct_max_match_filter(max_size): - """Constructs a maximum size match filter that fits into the 'max_size' bytes. + """Constructs a maximum size match filter that fits into the 'max_size' bytes. Match filters are a set of LVs (Length, Value pairs) where L is 1 byte. The maximum size match filter will contain max_size/2 LVs with all Vs (except @@ -207,19 +217,19 @@ def construct_max_match_filter(max_size): max_size: Maximum size of the match filter. Returns: an array of bytearrays. """ - mf_list = [] - num_lvs = max_size // 2 - for i in range(num_lvs - 1): - mf_list.append(bytes([i])) - if (max_size % 2 == 0): - mf_list.append(bytes([255])) - else: - mf_list.append(bytes([254, 255])) - return mf_list + mf_list = [] + num_lvs = max_size // 2 + for i in range(num_lvs - 1): + mf_list.append(bytes([i])) + if (max_size % 2 == 0): + mf_list.append(bytes([255])) + else: + mf_list.append(bytes([254, 255])) + return mf_list def assert_equal_strings(first, second, msg=None, extras=None): - """Assert equality of the string operands - where None is treated as equal to + """Assert equality of the string operands - where None is treated as equal to an empty string (''), otherwise fail the test. Error message is "first != second" by default. Additional explanation can @@ -231,35 +241,37 @@ def assert_equal_strings(first, second, msg=None, extras=None): extras: An optional field for extra information to be included in test result. """ - if first == None: - first = '' - if second == None: - second = '' - asserts.assert_equal(first, second, msg, extras) + if first == None: + first = '' + if second == None: + second = '' + asserts.assert_equal(first, second, msg, extras) def get_aware_capabilities(ad): - """Get the Wi-Fi Aware capabilities from the specified device. The + """Get the Wi-Fi Aware capabilities from the specified device. The capabilities are a dictionary keyed by aware_const.CAP_* keys. Args: ad: the Android device Returns: the capability dictionary. """ - return json.loads(ad.adb.shell('cmd wifiaware state_mgr get_capabilities')) + return json.loads(ad.adb.shell('cmd wifiaware state_mgr get_capabilities')) + def get_wifi_mac_address(ad): - """Get the Wi-Fi interface MAC address as a upper-case string of hex digits + """Get the Wi-Fi interface MAC address as a upper-case string of hex digits without any separators (e.g. ':'). Args: ad: Device on which to run. """ - return ad.droid.wifiGetConnectionInfo()['mac_address'].upper().replace( - ':', '') + return ad.droid.wifiGetConnectionInfo()['mac_address'].upper().replace( + ':', '') + def validate_forbidden_callbacks(ad, limited_cb=None): - """Validate that the specified callbacks have not been called more then permitted. + """Validate that the specified callbacks have not been called more then permitted. In addition to the input configuration also validates that forbidden callbacks have never been called. @@ -269,26 +281,27 @@ def validate_forbidden_callbacks(ad, limited_cb=None): limited_cb: Dictionary of CB_EV_* ids and maximum permitted calls (0 meaning never). """ - cb_data = json.loads(ad.adb.shell('cmd wifiaware native_cb get_cb_count')) - - if limited_cb is None: - limited_cb = {} - # add callbacks which should never be called - limited_cb[aconsts.CB_EV_MATCH_EXPIRED] = 0 - - fail = False - for cb_event in limited_cb.keys(): - if cb_event in cb_data: - if cb_data[cb_event] > limited_cb[cb_event]: - fail = True - ad.log.info( - 'Callback %s observed %d times: more then permitted %d times', - cb_event, cb_data[cb_event], limited_cb[cb_event]) + cb_data = json.loads(ad.adb.shell('cmd wifiaware native_cb get_cb_count')) + + if limited_cb is None: + limited_cb = {} + # add callbacks which should never be called + limited_cb[aconsts.CB_EV_MATCH_EXPIRED] = 0 + + fail = False + for cb_event in limited_cb.keys(): + if cb_event in cb_data: + if cb_data[cb_event] > limited_cb[cb_event]: + fail = True + ad.log.info( + 'Callback %s observed %d times: more then permitted %d times', + cb_event, cb_data[cb_event], limited_cb[cb_event]) + + asserts.assert_false(fail, 'Forbidden callbacks observed', extras=cb_data) - asserts.assert_false(fail, 'Forbidden callbacks observed', extras=cb_data) def extract_stats(ad, data, results, key_prefix, log_prefix): - """Extract statistics from the data, store in the results dictionary, and + """Extract statistics from the data, store in the results dictionary, and output to the info log. Args: @@ -301,39 +314,41 @@ def extract_stats(ad, data, results, key_prefix, log_prefix): include_data: If True includes the raw data in the dictionary, otherwise just the stats. """ - num_samples = len(data) - results['%snum_samples' % key_prefix] = num_samples - - if not data: - return - - data_min = min(data) - data_max = max(data) - data_mean = statistics.mean(data) - data_cdf = extract_cdf(data) - data_cdf_decile = extract_cdf_decile(data_cdf) - - results['%smin' % key_prefix] = data_min - results['%smax' % key_prefix] = data_max - results['%smean' % key_prefix] = data_mean - results['%scdf' % key_prefix] = data_cdf - results['%scdf_decile' % key_prefix] = data_cdf_decile - results['%sraw_data' % key_prefix] = data - - if num_samples > 1: - data_stdev = statistics.stdev(data) - results['%sstdev' % key_prefix] = data_stdev - ad.log.info( - '%s: num_samples=%d, min=%.2f, max=%.2f, mean=%.2f, stdev=%.2f, cdf_decile=%s', - log_prefix, num_samples, data_min, data_max, data_mean, data_stdev, - data_cdf_decile) - else: - ad.log.info( - '%s: num_samples=%d, min=%.2f, max=%.2f, mean=%.2f, cdf_decile=%s', - log_prefix, num_samples, data_min, data_max, data_mean, data_cdf_decile) + num_samples = len(data) + results['%snum_samples' % key_prefix] = num_samples + + if not data: + return + + data_min = min(data) + data_max = max(data) + data_mean = statistics.mean(data) + data_cdf = extract_cdf(data) + data_cdf_decile = extract_cdf_decile(data_cdf) + + results['%smin' % key_prefix] = data_min + results['%smax' % key_prefix] = data_max + results['%smean' % key_prefix] = data_mean + results['%scdf' % key_prefix] = data_cdf + results['%scdf_decile' % key_prefix] = data_cdf_decile + results['%sraw_data' % key_prefix] = data + + if num_samples > 1: + data_stdev = statistics.stdev(data) + results['%sstdev' % key_prefix] = data_stdev + ad.log.info( + '%s: num_samples=%d, min=%.2f, max=%.2f, mean=%.2f, stdev=%.2f, cdf_decile=%s', + log_prefix, num_samples, data_min, data_max, data_mean, data_stdev, + data_cdf_decile) + else: + ad.log.info( + '%s: num_samples=%d, min=%.2f, max=%.2f, mean=%.2f, cdf_decile=%s', + log_prefix, num_samples, data_min, data_max, data_mean, + data_cdf_decile) + def extract_cdf_decile(cdf): - """Extracts the 10%, 20%, ..., 90% points from the CDF and returns their + """Extracts the 10%, 20%, ..., 90% points from the CDF and returns their value (a list of 9 values). Since CDF may not (will not) have exact x% value picks the value >= x%. @@ -341,66 +356,68 @@ def extract_cdf_decile(cdf): Args: cdf: a list of 2 lists, the X and Y of the CDF. """ - decades = [] - next_decade = 10 - for x, y in zip(cdf[0], cdf[1]): - while 100*y >= next_decade: - decades.append(x) - next_decade = next_decade + 10 - if next_decade == 100: - break - return decades + decades = [] + next_decade = 10 + for x, y in zip(cdf[0], cdf[1]): + while 100 * y >= next_decade: + decades.append(x) + next_decade = next_decade + 10 + if next_decade == 100: + break + return decades + def extract_cdf(data): - """Calculates the Cumulative Distribution Function (CDF) of the data. + """Calculates the Cumulative Distribution Function (CDF) of the data. Args: data: A list containing data (does not have to be sorted). Returns: a list of 2 lists: the X and Y axis of the CDF. """ - x = [] - cdf = [] - if not data: - return (x, cdf) - - all_values = sorted(data) - for val in all_values: - if not x: - x.append(val) - cdf.append(1) - else: - if x[-1] == val: - cdf[-1] += 1 - else: - x.append(val) - cdf.append(cdf[-1] + 1) - - scale = 1.0 / len(all_values) - for i in range(len(cdf)): - cdf[i] = cdf[i] * scale + x = [] + cdf = [] + if not data: + return (x, cdf) + + all_values = sorted(data) + for val in all_values: + if not x: + x.append(val) + cdf.append(1) + else: + if x[-1] == val: + cdf[-1] += 1 + else: + x.append(val) + cdf.append(cdf[-1] + 1) + + scale = 1.0 / len(all_values) + for i in range(len(cdf)): + cdf[i] = cdf[i] * scale - return (x, cdf) + return (x, cdf) def get_mac_addr(device, interface): - """Get the MAC address of the specified interface. Uses ifconfig and parses + """Get the MAC address of the specified interface. Uses ifconfig and parses its output. Normalizes string to remove ':' and upper case. Args: device: Device on which to query the interface MAC address. interface: Name of the interface for which to obtain the MAC address. """ - out = device.adb.shell("ifconfig %s" % interface) - res = re.match(".* HWaddr (\S+).*", out , re.S) - asserts.assert_true( - res, - 'Unable to obtain MAC address for interface %s' % interface, - extras=out) - return res.group(1).upper().replace(':', '') + out = device.adb.shell("ifconfig %s" % interface) + res = re.match(".* HWaddr (\S+).*", out, re.S) + asserts.assert_true( + res, + 'Unable to obtain MAC address for interface %s' % interface, + extras=out) + return res.group(1).upper().replace(':', '') + def get_ipv6_addr(device, interface): - """Get the IPv6 address of the specified interface. Uses ifconfig and parses + """Get the IPv6 address of the specified interface. Uses ifconfig and parses its output. Returns a None if the interface does not have an IPv6 address (indicating it is not UP). @@ -408,29 +425,32 @@ def get_ipv6_addr(device, interface): device: Device on which to query the interface IPv6 address. interface: Name of the interface for which to obtain the IPv6 address. """ - out = device.adb.shell("ifconfig %s" % interface) - res = re.match(".*inet6 addr: (\S+)/.*", out , re.S) - if not res: - return None - return res.group(1) + out = device.adb.shell("ifconfig %s" % interface) + res = re.match(".*inet6 addr: (\S+)/.*", out, re.S) + if not res: + return None + return res.group(1) + ######################################################### # Aware primitives ######################################################### + def request_network(dut, ns): - """Request a Wi-Fi Aware network. + """Request a Wi-Fi Aware network. Args: dut: Device ns: Network specifier Returns: the request key """ - network_req = {"TransportType": 5, "NetworkSpecifier": ns} - return dut.droid.connectivityRequestWifiAwareNetwork(network_req) + network_req = {"TransportType": 5, "NetworkSpecifier": ns} + return dut.droid.connectivityRequestWifiAwareNetwork(network_req) + def get_network_specifier(dut, id, dev_type, peer_mac, sec): - """Create a network specifier for the device based on the security + """Create a network specifier for the device based on the security configuration. Args: @@ -440,17 +460,18 @@ def get_network_specifier(dut, id, dev_type, peer_mac, sec): peer_mac: the discovery MAC address of the peer sec: security configuration """ - if sec is None: - return dut.droid.wifiAwareCreateNetworkSpecifierOob( - id, dev_type, peer_mac) - if isinstance(sec, str): + if sec is None: + return dut.droid.wifiAwareCreateNetworkSpecifierOob( + id, dev_type, peer_mac) + if isinstance(sec, str): + return dut.droid.wifiAwareCreateNetworkSpecifierOob( + id, dev_type, peer_mac, sec) return dut.droid.wifiAwareCreateNetworkSpecifierOob( - id, dev_type, peer_mac, sec) - return dut.droid.wifiAwareCreateNetworkSpecifierOob( - id, dev_type, peer_mac, None, sec) + id, dev_type, peer_mac, None, sec) + def configure_power_setting(device, mode, name, value): - """Use the command-line API to configure the power setting + """Use the command-line API to configure the power setting Args: device: Device on which to perform configuration @@ -458,11 +479,12 @@ def configure_power_setting(device, mode, name, value): name: One of the power settings from 'wifiaware set-power'. value: An integer. """ - device.adb.shell( - "cmd wifiaware native_api set-power %s %s %d" % (mode, name, value)) + device.adb.shell( + "cmd wifiaware native_api set-power %s %s %d" % (mode, name, value)) + def configure_mac_random_interval(device, interval_sec): - """Use the command-line API to configure the MAC address randomization + """Use the command-line API to configure the MAC address randomization interval. Args: @@ -470,11 +492,12 @@ def configure_mac_random_interval(device, interval_sec): interval_sec: The MAC randomization interval in seconds. A value of 0 disables all randomization. """ - device.adb.shell( - "cmd wifiaware native_api set mac_random_interval_sec %d" % interval_sec) + device.adb.shell("cmd wifiaware native_api set mac_random_interval_sec %d" + % interval_sec) + def configure_ndp_allow_any_override(device, override_api_check): - """Use the command-line API to configure whether an NDP Responder may be + """Use the command-line API to configure whether an NDP Responder may be configured to accept an NDP request from ANY peer. By default the target API level of the requesting app determines whether such @@ -486,63 +509,69 @@ def configure_ndp_allow_any_override(device, override_api_check): override_api_check: True to allow a Responder to ANY configuration, False to perform the API level check. """ - device.adb.shell("cmd wifiaware state_mgr allow_ndp_any %s" % ( - "true" if override_api_check else "false")) + device.adb.shell("cmd wifiaware state_mgr allow_ndp_any %s" % + ("true" if override_api_check else "false")) + def config_settings_high_power(device): - """Configure device's power settings values to high power mode - + """Configure device's power settings values to high power mode - whether device is in interactive or non-interactive modes""" - configure_power_setting(device, "default", "dw_24ghz", - aconsts.POWER_DW_24_INTERACTIVE) - configure_power_setting(device, "default", "dw_5ghz", - aconsts.POWER_DW_5_INTERACTIVE) - configure_power_setting(device, "default", "disc_beacon_interval_ms", - aconsts.POWER_DISC_BEACON_INTERVAL_INTERACTIVE) - configure_power_setting(device, "default", "num_ss_in_discovery", - aconsts.POWER_NUM_SS_IN_DISC_INTERACTIVE) - configure_power_setting(device, "default", "enable_dw_early_term", - aconsts.POWER_ENABLE_DW_EARLY_TERM_INTERACTIVE) - - configure_power_setting(device, "inactive", "dw_24ghz", - aconsts.POWER_DW_24_INTERACTIVE) - configure_power_setting(device, "inactive", "dw_5ghz", - aconsts.POWER_DW_5_INTERACTIVE) - configure_power_setting(device, "inactive", "disc_beacon_interval_ms", - aconsts.POWER_DISC_BEACON_INTERVAL_INTERACTIVE) - configure_power_setting(device, "inactive", "num_ss_in_discovery", - aconsts.POWER_NUM_SS_IN_DISC_INTERACTIVE) - configure_power_setting(device, "inactive", "enable_dw_early_term", - aconsts.POWER_ENABLE_DW_EARLY_TERM_INTERACTIVE) + configure_power_setting(device, "default", "dw_24ghz", + aconsts.POWER_DW_24_INTERACTIVE) + configure_power_setting(device, "default", "dw_5ghz", + aconsts.POWER_DW_5_INTERACTIVE) + configure_power_setting(device, "default", "disc_beacon_interval_ms", + aconsts.POWER_DISC_BEACON_INTERVAL_INTERACTIVE) + configure_power_setting(device, "default", "num_ss_in_discovery", + aconsts.POWER_NUM_SS_IN_DISC_INTERACTIVE) + configure_power_setting(device, "default", "enable_dw_early_term", + aconsts.POWER_ENABLE_DW_EARLY_TERM_INTERACTIVE) + + configure_power_setting(device, "inactive", "dw_24ghz", + aconsts.POWER_DW_24_INTERACTIVE) + configure_power_setting(device, "inactive", "dw_5ghz", + aconsts.POWER_DW_5_INTERACTIVE) + configure_power_setting(device, "inactive", "disc_beacon_interval_ms", + aconsts.POWER_DISC_BEACON_INTERVAL_INTERACTIVE) + configure_power_setting(device, "inactive", "num_ss_in_discovery", + aconsts.POWER_NUM_SS_IN_DISC_INTERACTIVE) + configure_power_setting(device, "inactive", "enable_dw_early_term", + aconsts.POWER_ENABLE_DW_EARLY_TERM_INTERACTIVE) + def config_settings_low_power(device): - """Configure device's power settings values to low power mode - whether + """Configure device's power settings values to low power mode - whether device is in interactive or non-interactive modes""" - configure_power_setting(device, "default", "dw_24ghz", - aconsts.POWER_DW_24_NON_INTERACTIVE) - configure_power_setting(device, "default", "dw_5ghz", - aconsts.POWER_DW_5_NON_INTERACTIVE) - configure_power_setting(device, "default", "disc_beacon_interval_ms", - aconsts.POWER_DISC_BEACON_INTERVAL_NON_INTERACTIVE) - configure_power_setting(device, "default", "num_ss_in_discovery", - aconsts.POWER_NUM_SS_IN_DISC_NON_INTERACTIVE) - configure_power_setting(device, "default", "enable_dw_early_term", - aconsts.POWER_ENABLE_DW_EARLY_TERM_NON_INTERACTIVE) - - configure_power_setting(device, "inactive", "dw_24ghz", - aconsts.POWER_DW_24_NON_INTERACTIVE) - configure_power_setting(device, "inactive", "dw_5ghz", - aconsts.POWER_DW_5_NON_INTERACTIVE) - configure_power_setting(device, "inactive", "disc_beacon_interval_ms", - aconsts.POWER_DISC_BEACON_INTERVAL_NON_INTERACTIVE) - configure_power_setting(device, "inactive", "num_ss_in_discovery", - aconsts.POWER_NUM_SS_IN_DISC_NON_INTERACTIVE) - configure_power_setting(device, "inactive", "enable_dw_early_term", - aconsts.POWER_ENABLE_DW_EARLY_TERM_NON_INTERACTIVE) - - -def config_power_settings(device, dw_24ghz, dw_5ghz, disc_beacon_interval=None, - num_ss_in_disc=None, enable_dw_early_term=None): - """Configure device's discovery window (DW) values to the specified values - + configure_power_setting(device, "default", "dw_24ghz", + aconsts.POWER_DW_24_NON_INTERACTIVE) + configure_power_setting(device, "default", "dw_5ghz", + aconsts.POWER_DW_5_NON_INTERACTIVE) + configure_power_setting(device, "default", "disc_beacon_interval_ms", + aconsts.POWER_DISC_BEACON_INTERVAL_NON_INTERACTIVE) + configure_power_setting(device, "default", "num_ss_in_discovery", + aconsts.POWER_NUM_SS_IN_DISC_NON_INTERACTIVE) + configure_power_setting(device, "default", "enable_dw_early_term", + aconsts.POWER_ENABLE_DW_EARLY_TERM_NON_INTERACTIVE) + + configure_power_setting(device, "inactive", "dw_24ghz", + aconsts.POWER_DW_24_NON_INTERACTIVE) + configure_power_setting(device, "inactive", "dw_5ghz", + aconsts.POWER_DW_5_NON_INTERACTIVE) + configure_power_setting(device, "inactive", "disc_beacon_interval_ms", + aconsts.POWER_DISC_BEACON_INTERVAL_NON_INTERACTIVE) + configure_power_setting(device, "inactive", "num_ss_in_discovery", + aconsts.POWER_NUM_SS_IN_DISC_NON_INTERACTIVE) + configure_power_setting(device, "inactive", "enable_dw_early_term", + aconsts.POWER_ENABLE_DW_EARLY_TERM_NON_INTERACTIVE) + + +def config_power_settings(device, + dw_24ghz, + dw_5ghz, + disc_beacon_interval=None, + num_ss_in_disc=None, + enable_dw_early_term=None): + """Configure device's discovery window (DW) values to the specified values - whether the device is in interactive or non-interactive mode. Args: @@ -555,37 +584,38 @@ def config_power_settings(device, dw_24ghz, dw_5ghz, disc_beacon_interval=None, enable_dw_early_term: If True then enable early termination of the DW. If None then not set. """ - configure_power_setting(device, "default", "dw_24ghz", dw_24ghz) - configure_power_setting(device, "default", "dw_5ghz", dw_5ghz) - configure_power_setting(device, "inactive", "dw_24ghz", dw_24ghz) - configure_power_setting(device, "inactive", "dw_5ghz", dw_5ghz) - - if disc_beacon_interval is not None: - configure_power_setting(device, "default", "disc_beacon_interval_ms", - disc_beacon_interval) - configure_power_setting(device, "inactive", "disc_beacon_interval_ms", - disc_beacon_interval) + configure_power_setting(device, "default", "dw_24ghz", dw_24ghz) + configure_power_setting(device, "default", "dw_5ghz", dw_5ghz) + configure_power_setting(device, "inactive", "dw_24ghz", dw_24ghz) + configure_power_setting(device, "inactive", "dw_5ghz", dw_5ghz) + + if disc_beacon_interval is not None: + configure_power_setting(device, "default", "disc_beacon_interval_ms", + disc_beacon_interval) + configure_power_setting(device, "inactive", "disc_beacon_interval_ms", + disc_beacon_interval) + + if num_ss_in_disc is not None: + configure_power_setting(device, "default", "num_ss_in_discovery", + num_ss_in_disc) + configure_power_setting(device, "inactive", "num_ss_in_discovery", + num_ss_in_disc) + + if enable_dw_early_term is not None: + configure_power_setting(device, "default", "enable_dw_early_term", + enable_dw_early_term) + configure_power_setting(device, "inactive", "enable_dw_early_term", + enable_dw_early_term) - if num_ss_in_disc is not None: - configure_power_setting(device, "default", "num_ss_in_discovery", - num_ss_in_disc) - configure_power_setting(device, "inactive", "num_ss_in_discovery", - num_ss_in_disc) - - if enable_dw_early_term is not None: - configure_power_setting(device, "default", "enable_dw_early_term", - enable_dw_early_term) - configure_power_setting(device, "inactive", "enable_dw_early_term", - enable_dw_early_term) def create_discovery_config(service_name, - d_type, - ssi=None, - match_filter=None, - match_filter_list=None, - ttl=0, - term_cb_enable=True): - """Create a publish discovery configuration based on input parameters. + d_type, + ssi=None, + match_filter=None, + match_filter_list=None, + ttl=0, + term_cb_enable=True): + """Create a publish discovery configuration based on input parameters. Args: service_name: Service name - required @@ -599,21 +629,22 @@ def create_discovery_config(service_name, Returns: publish discovery configuration object. """ - config = {} - config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = service_name - config[aconsts.DISCOVERY_KEY_DISCOVERY_TYPE] = d_type - if ssi is not None: - config[aconsts.DISCOVERY_KEY_SSI] = ssi - if match_filter is not None: - config[aconsts.DISCOVERY_KEY_MATCH_FILTER] = match_filter - if match_filter_list is not None: - config[aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST] = match_filter_list - config[aconsts.DISCOVERY_KEY_TTL] = ttl - config[aconsts.DISCOVERY_KEY_TERM_CB_ENABLED] = term_cb_enable - return config + config = {} + config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = service_name + config[aconsts.DISCOVERY_KEY_DISCOVERY_TYPE] = d_type + if ssi is not None: + config[aconsts.DISCOVERY_KEY_SSI] = ssi + if match_filter is not None: + config[aconsts.DISCOVERY_KEY_MATCH_FILTER] = match_filter + if match_filter_list is not None: + config[aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST] = match_filter_list + config[aconsts.DISCOVERY_KEY_TTL] = ttl + config[aconsts.DISCOVERY_KEY_TERM_CB_ENABLED] = term_cb_enable + return config + def add_ranging_to_pub(p_config, enable_ranging): - """Add ranging enabled configuration to a publish configuration (only relevant + """Add ranging enabled configuration to a publish configuration (only relevant for publish configuration). Args: @@ -622,11 +653,12 @@ def add_ranging_to_pub(p_config, enable_ranging): Returns: The modified publish configuration. """ - p_config[aconsts.DISCOVERY_KEY_RANGING_ENABLED] = enable_ranging - return p_config + p_config[aconsts.DISCOVERY_KEY_RANGING_ENABLED] = enable_ranging + return p_config + def add_ranging_to_sub(s_config, min_distance_mm, max_distance_mm): - """Add ranging distance configuration to a subscribe configuration (only + """Add ranging distance configuration to a subscribe configuration (only relevant to a subscribe configuration). Args: @@ -636,14 +668,15 @@ def add_ranging_to_sub(s_config, min_distance_mm, max_distance_mm): Returns: The modified subscribe configuration. """ - if min_distance_mm is not None: - s_config[aconsts.DISCOVERY_KEY_MIN_DISTANCE_MM] = min_distance_mm - if max_distance_mm is not None: - s_config[aconsts.DISCOVERY_KEY_MAX_DISTANCE_MM] = max_distance_mm - return s_config + if min_distance_mm is not None: + s_config[aconsts.DISCOVERY_KEY_MIN_DISTANCE_MM] = min_distance_mm + if max_distance_mm is not None: + s_config[aconsts.DISCOVERY_KEY_MAX_DISTANCE_MM] = max_distance_mm + return s_config + def attach_with_identity(dut): - """Start an Aware session (attach) and wait for confirmation and identity + """Start an Aware session (attach) and wait for confirmation and identity information (mac address). Args: @@ -652,12 +685,13 @@ def attach_with_identity(dut): id: Aware session ID. mac: Discovery MAC address of this device. """ - id = dut.droid.wifiAwareAttach(True) - wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) - event = wait_for_event(dut, aconsts.EVENT_CB_ON_IDENTITY_CHANGED) - mac = event["data"]["mac"] + id = dut.droid.wifiAwareAttach(True) + wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) + event = wait_for_event(dut, aconsts.EVENT_CB_ON_IDENTITY_CHANGED) + mac = event["data"]["mac"] + + return id, mac - return id, mac def create_discovery_pair(p_dut, s_dut, @@ -665,7 +699,7 @@ def create_discovery_pair(p_dut, s_config, device_startup_offset, msg_id=None): - """Creates a discovery session (publish and subscribe), and waits for + """Creates a discovery session (publish and subscribe), and waits for service discovery - at that point the sessions are connected and ready for further messaging of data-path setup. @@ -688,55 +722,59 @@ def create_discovery_pair(p_dut, peer_id_on_pub: Peer ID of the Subscriber as seen on the Publisher. Only included if |msg_id| is not None. """ - p_dut.pretty_name = 'Publisher' - s_dut.pretty_name = 'Subscriber' - - # Publisher+Subscriber: attach and wait for confirmation - p_id = p_dut.droid.wifiAwareAttach() - wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED) - time.sleep(device_startup_offset) - s_id = s_dut.droid.wifiAwareAttach() - wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED) - - # Publisher: start publish and wait for confirmation - p_disc_id = p_dut.droid.wifiAwarePublish(p_id, p_config) - wait_for_event(p_dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED) - - # Subscriber: start subscribe and wait for confirmation - s_disc_id = s_dut.droid.wifiAwareSubscribe(s_id, s_config) - wait_for_event(s_dut, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED) - - # Subscriber: wait for service discovery - discovery_event = wait_for_event(s_dut, - aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) - peer_id_on_sub = discovery_event['data'][aconsts.SESSION_CB_KEY_PEER_ID] - - # Optionally send a message from Subscriber to Publisher - if msg_id is not None: - ping_msg = 'PING' - - # Subscriber: send message to peer (Publisher) - s_dut.droid.wifiAwareSendMessage(s_disc_id, peer_id_on_sub, msg_id, - ping_msg, aconsts.MAX_TX_RETRIES) - sub_tx_msg_event = wait_for_event(s_dut, aconsts.SESSION_CB_ON_MESSAGE_SENT) - asserts.assert_equal( - msg_id, sub_tx_msg_event['data'][aconsts.SESSION_CB_KEY_MESSAGE_ID], - 'Subscriber -> Publisher message ID corrupted') - - # Publisher: wait for received message - pub_rx_msg_event = wait_for_event(p_dut, - aconsts.SESSION_CB_ON_MESSAGE_RECEIVED) - peer_id_on_pub = pub_rx_msg_event['data'][aconsts.SESSION_CB_KEY_PEER_ID] - asserts.assert_equal( - ping_msg, - pub_rx_msg_event['data'][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING], - 'Subscriber -> Publisher message corrupted') - return p_id, s_id, p_disc_id, s_disc_id, peer_id_on_sub, peer_id_on_pub - - return p_id, s_id, p_disc_id, s_disc_id, peer_id_on_sub + p_dut.pretty_name = 'Publisher' + s_dut.pretty_name = 'Subscriber' + + # Publisher+Subscriber: attach and wait for confirmation + p_id = p_dut.droid.wifiAwareAttach() + wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED) + time.sleep(device_startup_offset) + s_id = s_dut.droid.wifiAwareAttach() + wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED) + + # Publisher: start publish and wait for confirmation + p_disc_id = p_dut.droid.wifiAwarePublish(p_id, p_config) + wait_for_event(p_dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED) + + # Subscriber: start subscribe and wait for confirmation + s_disc_id = s_dut.droid.wifiAwareSubscribe(s_id, s_config) + wait_for_event(s_dut, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED) + + # Subscriber: wait for service discovery + discovery_event = wait_for_event(s_dut, + aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) + peer_id_on_sub = discovery_event['data'][aconsts.SESSION_CB_KEY_PEER_ID] + + # Optionally send a message from Subscriber to Publisher + if msg_id is not None: + ping_msg = 'PING' + + # Subscriber: send message to peer (Publisher) + s_dut.droid.wifiAwareSendMessage(s_disc_id, peer_id_on_sub, msg_id, + ping_msg, aconsts.MAX_TX_RETRIES) + sub_tx_msg_event = wait_for_event(s_dut, + aconsts.SESSION_CB_ON_MESSAGE_SENT) + asserts.assert_equal( + msg_id, + sub_tx_msg_event['data'][aconsts.SESSION_CB_KEY_MESSAGE_ID], + 'Subscriber -> Publisher message ID corrupted') + + # Publisher: wait for received message + pub_rx_msg_event = wait_for_event( + p_dut, aconsts.SESSION_CB_ON_MESSAGE_RECEIVED) + peer_id_on_pub = pub_rx_msg_event['data'][ + aconsts.SESSION_CB_KEY_PEER_ID] + asserts.assert_equal( + ping_msg, + pub_rx_msg_event['data'][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING], + 'Subscriber -> Publisher message corrupted') + return p_id, s_id, p_disc_id, s_disc_id, peer_id_on_sub, peer_id_on_pub + + return p_id, s_id, p_disc_id, s_disc_id, peer_id_on_sub + def create_ib_ndp(p_dut, s_dut, p_config, s_config, device_startup_offset): - """Create an NDP (using in-band discovery) + """Create an NDP (using in-band discovery) Args: p_dut: Device to use as publisher. @@ -746,45 +784,48 @@ def create_ib_ndp(p_dut, s_dut, p_config, s_config, device_startup_offset): device_startup_offset: Number of seconds to offset the enabling of NAN on the two devices. """ - (p_id, s_id, p_disc_id, s_disc_id, peer_id_on_sub, - peer_id_on_pub) = create_discovery_pair( - p_dut, s_dut, p_config, s_config, device_startup_offset, msg_id=9999) - - # Publisher: request network - p_req_key = request_network(p_dut, - p_dut.droid.wifiAwareCreateNetworkSpecifier( - p_disc_id, peer_id_on_pub, None)) - - # Subscriber: request network - s_req_key = request_network(s_dut, - s_dut.droid.wifiAwareCreateNetworkSpecifier( - s_disc_id, peer_id_on_sub, None)) - - # Publisher & Subscriber: wait for network formation - p_net_event = wait_for_event_with_keys( - p_dut, cconsts.EVENT_NETWORK_CALLBACK, EVENT_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), (cconsts.NETWORK_CB_KEY_ID, - p_req_key)) - s_net_event = wait_for_event_with_keys( - s_dut, cconsts.EVENT_NETWORK_CALLBACK, EVENT_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), (cconsts.NETWORK_CB_KEY_ID, - s_req_key)) - - p_aware_if = p_net_event["data"][cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - s_aware_if = s_net_event["data"][cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - - p_ipv6 = p_dut.droid.connectivityGetLinkLocalIpv6Address(p_aware_if).split( - "%")[0] - s_ipv6 = s_dut.droid.connectivityGetLinkLocalIpv6Address(s_aware_if).split( - "%")[0] - - return p_req_key, s_req_key, p_aware_if, s_aware_if, p_ipv6, s_ipv6 + (p_id, s_id, p_disc_id, s_disc_id, peer_id_on_sub, + peer_id_on_pub) = create_discovery_pair( + p_dut, s_dut, p_config, s_config, device_startup_offset, msg_id=9999) + + # Publisher: request network + p_req_key = request_network( + p_dut, + p_dut.droid.wifiAwareCreateNetworkSpecifier(p_disc_id, peer_id_on_pub, + None)) + + # Subscriber: request network + s_req_key = request_network( + s_dut, + s_dut.droid.wifiAwareCreateNetworkSpecifier(s_disc_id, peer_id_on_sub, + None)) + + # Publisher & Subscriber: wait for network formation + p_net_event = wait_for_event_with_keys( + p_dut, cconsts.EVENT_NETWORK_CALLBACK, EVENT_TIMEOUT, + (cconsts.NETWORK_CB_KEY_EVENT, + cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), + (cconsts.NETWORK_CB_KEY_ID, p_req_key)) + s_net_event = wait_for_event_with_keys( + s_dut, cconsts.EVENT_NETWORK_CALLBACK, EVENT_TIMEOUT, + (cconsts.NETWORK_CB_KEY_EVENT, + cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), + (cconsts.NETWORK_CB_KEY_ID, s_req_key)) + + p_aware_if = p_net_event["data"][cconsts.NETWORK_CB_KEY_INTERFACE_NAME] + s_aware_if = s_net_event["data"][cconsts.NETWORK_CB_KEY_INTERFACE_NAME] + + p_ipv6 = p_dut.droid.connectivityGetLinkLocalIpv6Address(p_aware_if).split( + "%")[0] + s_ipv6 = s_dut.droid.connectivityGetLinkLocalIpv6Address(s_aware_if).split( + "%")[0] + + return p_req_key, s_req_key, p_aware_if, s_aware_if, p_ipv6, s_ipv6 + def create_oob_ndp_on_sessions(init_dut, resp_dut, init_id, init_mac, resp_id, resp_mac): - """Create an NDP on top of existing Aware sessions (using OOB discovery) + """Create an NDP on top of existing Aware sessions (using OOB discovery) Args: init_dut: Initiator device @@ -801,71 +842,74 @@ def create_oob_ndp_on_sessions(init_dut, resp_dut, init_id, init_mac, resp_id, init_ipv6: Initiator IPv6 address resp_ipv6: Responder IPv6 address """ - # Responder: request network - resp_req_key = request_network( - resp_dut, - resp_dut.droid.wifiAwareCreateNetworkSpecifierOob( - resp_id, aconsts.DATA_PATH_RESPONDER, init_mac, None)) - - # Initiator: request network - init_req_key = request_network( - init_dut, - init_dut.droid.wifiAwareCreateNetworkSpecifierOob( - init_id, aconsts.DATA_PATH_INITIATOR, resp_mac, None)) - - # Initiator & Responder: wait for network formation - init_net_event = wait_for_event_with_keys( - init_dut, cconsts.EVENT_NETWORK_CALLBACK, EVENT_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), (cconsts.NETWORK_CB_KEY_ID, - init_req_key)) - resp_net_event = wait_for_event_with_keys( - resp_dut, cconsts.EVENT_NETWORK_CALLBACK, EVENT_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), (cconsts.NETWORK_CB_KEY_ID, - resp_req_key)) - - init_aware_if = init_net_event['data'][cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - resp_aware_if = resp_net_event['data'][cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - - init_ipv6 = init_dut.droid.connectivityGetLinkLocalIpv6Address( - init_aware_if).split('%')[0] - resp_ipv6 = resp_dut.droid.connectivityGetLinkLocalIpv6Address( - resp_aware_if).split('%')[0] - - return (init_req_key, resp_req_key, init_aware_if, resp_aware_if, init_ipv6, - resp_ipv6) + # Responder: request network + resp_req_key = request_network( + resp_dut, + resp_dut.droid.wifiAwareCreateNetworkSpecifierOob( + resp_id, aconsts.DATA_PATH_RESPONDER, init_mac, None)) + + # Initiator: request network + init_req_key = request_network( + init_dut, + init_dut.droid.wifiAwareCreateNetworkSpecifierOob( + init_id, aconsts.DATA_PATH_INITIATOR, resp_mac, None)) + + # Initiator & Responder: wait for network formation + init_net_event = wait_for_event_with_keys( + init_dut, cconsts.EVENT_NETWORK_CALLBACK, EVENT_TIMEOUT, + (cconsts.NETWORK_CB_KEY_EVENT, + cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), + (cconsts.NETWORK_CB_KEY_ID, init_req_key)) + resp_net_event = wait_for_event_with_keys( + resp_dut, cconsts.EVENT_NETWORK_CALLBACK, EVENT_TIMEOUT, + (cconsts.NETWORK_CB_KEY_EVENT, + cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), + (cconsts.NETWORK_CB_KEY_ID, resp_req_key)) + + init_aware_if = init_net_event['data'][ + cconsts.NETWORK_CB_KEY_INTERFACE_NAME] + resp_aware_if = resp_net_event['data'][ + cconsts.NETWORK_CB_KEY_INTERFACE_NAME] + + init_ipv6 = init_dut.droid.connectivityGetLinkLocalIpv6Address( + init_aware_if).split('%')[0] + resp_ipv6 = resp_dut.droid.connectivityGetLinkLocalIpv6Address( + resp_aware_if).split('%')[0] + + return (init_req_key, resp_req_key, init_aware_if, resp_aware_if, + init_ipv6, resp_ipv6) + def create_oob_ndp(init_dut, resp_dut): - """Create an NDP (using OOB discovery) + """Create an NDP (using OOB discovery) Args: init_dut: Initiator device resp_dut: Responder device """ - init_dut.pretty_name = 'Initiator' - resp_dut.pretty_name = 'Responder' - - # Initiator+Responder: attach and wait for confirmation & identity - init_id = init_dut.droid.wifiAwareAttach(True) - wait_for_event(init_dut, aconsts.EVENT_CB_ON_ATTACHED) - init_ident_event = wait_for_event(init_dut, - aconsts.EVENT_CB_ON_IDENTITY_CHANGED) - init_mac = init_ident_event['data']['mac'] - resp_id = resp_dut.droid.wifiAwareAttach(True) - wait_for_event(resp_dut, aconsts.EVENT_CB_ON_ATTACHED) - resp_ident_event = wait_for_event(resp_dut, - aconsts.EVENT_CB_ON_IDENTITY_CHANGED) - resp_mac = resp_ident_event['data']['mac'] - - # wait for for devices to synchronize with each other - there are no other - # mechanisms to make sure this happens for OOB discovery (except retrying - # to execute the data-path request) - time.sleep(WAIT_FOR_CLUSTER) - - (init_req_key, resp_req_key, init_aware_if, - resp_aware_if, init_ipv6, resp_ipv6) = create_oob_ndp_on_sessions( - init_dut, resp_dut, init_id, init_mac, resp_id, resp_mac) - - return (init_req_key, resp_req_key, init_aware_if, resp_aware_if, init_ipv6, - resp_ipv6) + init_dut.pretty_name = 'Initiator' + resp_dut.pretty_name = 'Responder' + + # Initiator+Responder: attach and wait for confirmation & identity + init_id = init_dut.droid.wifiAwareAttach(True) + wait_for_event(init_dut, aconsts.EVENT_CB_ON_ATTACHED) + init_ident_event = wait_for_event(init_dut, + aconsts.EVENT_CB_ON_IDENTITY_CHANGED) + init_mac = init_ident_event['data']['mac'] + resp_id = resp_dut.droid.wifiAwareAttach(True) + wait_for_event(resp_dut, aconsts.EVENT_CB_ON_ATTACHED) + resp_ident_event = wait_for_event(resp_dut, + aconsts.EVENT_CB_ON_IDENTITY_CHANGED) + resp_mac = resp_ident_event['data']['mac'] + + # wait for for devices to synchronize with each other - there are no other + # mechanisms to make sure this happens for OOB discovery (except retrying + # to execute the data-path request) + time.sleep(WAIT_FOR_CLUSTER) + + (init_req_key, resp_req_key, init_aware_if, resp_aware_if, + init_ipv6, resp_ipv6) = create_oob_ndp_on_sessions( + init_dut, resp_dut, init_id, init_mac, resp_id, resp_mac) + + return (init_req_key, resp_req_key, init_aware_if, resp_aware_if, + init_ipv6, resp_ipv6) diff --git a/acts/framework/acts/test_utils/wifi/rtt/RttBaseTest.py b/acts/framework/acts/test_utils/wifi/rtt/RttBaseTest.py index 218278001b..fb6db20f68 100644 --- a/acts/framework/acts/test_utils/wifi/rtt/RttBaseTest.py +++ b/acts/framework/acts/test_utils/wifi/rtt/RttBaseTest.py @@ -23,48 +23,47 @@ from acts.test_utils.wifi.rtt import rtt_test_utils as rutils class RttBaseTest(BaseTestClass): + def __init__(self, controllers): + super(RttBaseTest, self).__init__(controllers) - def __init__(self, controllers): - super(RttBaseTest, self).__init__(controllers) + def setup_test(self): + required_params = ("lci_reference", "lcr_reference", + "rtt_reference_distance_mm", + "stress_test_min_iteration_count", + "stress_test_target_run_time_sec") + self.unpack_userparams(required_params) - def setup_test(self): - required_params = ("lci_reference", "lcr_reference", - "rtt_reference_distance_mm", - "stress_test_min_iteration_count", - "stress_test_target_run_time_sec") - self.unpack_userparams(required_params) + # can be moved to JSON config file + self.rtt_reference_distance_margin_mm = 1000 + self.rtt_max_failure_rate_two_sided_rtt_percentage = 10 + self.rtt_max_failure_rate_one_sided_rtt_percentage = 50 + self.rtt_max_margin_exceeded_rate_two_sided_rtt_percentage = 10 + self.rtt_max_margin_exceeded_rate_one_sided_rtt_percentage = 50 + self.rtt_min_expected_rssi_dbm = -100 - # can be moved to JSON config file - self.rtt_reference_distance_margin_mm = 1000 - self.rtt_max_failure_rate_two_sided_rtt_percentage = 10 - self.rtt_max_failure_rate_one_sided_rtt_percentage = 50 - self.rtt_max_margin_exceeded_rate_two_sided_rtt_percentage = 10 - self.rtt_max_margin_exceeded_rate_one_sided_rtt_percentage = 50 - self.rtt_min_expected_rssi_dbm = -100 + for ad in self.android_devices: + utils.set_location_service(ad, True) + asserts.skip_if( + not ad.droid.doesDeviceSupportWifiRttFeature(), + "Device under test does not support Wi-Fi RTT - skipping test") + wutils.wifi_toggle_state(ad, True) + rtt_avail = ad.droid.wifiIsRttAvailable() + if not rtt_avail: + self.log.info('RTT not available. Waiting ...') + rutils.wait_for_event(ad, rconsts.BROADCAST_WIFI_RTT_AVAILABLE) + ad.ed.clear_all_events() + rutils.config_privilege_override(ad, False) + ad.droid.wifiSetCountryCode(wutils.WifiEnums.CountryCode.US) - for ad in self.android_devices: - utils.set_location_service(ad, True) - asserts.skip_if( - not ad.droid.doesDeviceSupportWifiRttFeature(), - "Device under test does not support Wi-Fi RTT - skipping test") - wutils.wifi_toggle_state(ad, True) - rtt_avail = ad.droid.wifiIsRttAvailable() - if not rtt_avail: - self.log.info('RTT not available. Waiting ...') - rutils.wait_for_event(ad, rconsts.BROADCAST_WIFI_RTT_AVAILABLE) - ad.ed.clear_all_events() - rutils.config_privilege_override(ad, False) - ad.droid.wifiSetCountryCode(wutils.WifiEnums.CountryCode.US) + def teardown_test(self): + for ad in self.android_devices: + if not ad.droid.doesDeviceSupportWifiRttFeature(): + return - def teardown_test(self): - for ad in self.android_devices: - if not ad.droid.doesDeviceSupportWifiRttFeature(): - return + # clean-up queue from the System Service UID + ad.droid.wifiRttCancelRanging([1000]) - # clean-up queue from the System Service UID - ad.droid.wifiRttCancelRanging([1000]) - - def on_fail(self, test_name, begin_time): - for ad in self.android_devices: - ad.take_bug_report(test_name, begin_time) - ad.cat_adb_log(test_name, begin_time) + def on_fail(self, test_name, begin_time): + for ad in self.android_devices: + ad.take_bug_report(test_name, begin_time) + ad.cat_adb_log(test_name, begin_time) diff --git a/acts/framework/acts/test_utils/wifi/rtt/rtt_test_utils.py b/acts/framework/acts/test_utils/wifi/rtt/rtt_test_utils.py index c24b406893..627bb75dff 100644 --- a/acts/framework/acts/test_utils/wifi/rtt/rtt_test_utils.py +++ b/acts/framework/acts/test_utils/wifi/rtt/rtt_test_utils.py @@ -27,11 +27,11 @@ EVENT_TIMEOUT = 10 def decorate_event(event_name, id): - return '%s_%d' % (event_name, id) + return '%s_%d' % (event_name, id) def wait_for_event(ad, event_name, timeout=EVENT_TIMEOUT): - """Wait for the specified event or timeout. + """Wait for the specified event or timeout. Args: ad: The android device @@ -40,39 +40,41 @@ def wait_for_event(ad, event_name, timeout=EVENT_TIMEOUT): Returns: The event (if available) """ - prefix = '' - if hasattr(ad, 'pretty_name'): - prefix = '[%s] ' % ad.pretty_name - try: - event = ad.ed.pop_event(event_name, timeout) - ad.log.info('%s%s: %s', prefix, event_name, event['data']) - return event - except queue.Empty: - ad.log.info('%sTimed out while waiting for %s', prefix, event_name) - asserts.fail(event_name) + prefix = '' + if hasattr(ad, 'pretty_name'): + prefix = '[%s] ' % ad.pretty_name + try: + event = ad.ed.pop_event(event_name, timeout) + ad.log.info('%s%s: %s', prefix, event_name, event['data']) + return event + except queue.Empty: + ad.log.info('%sTimed out while waiting for %s', prefix, event_name) + asserts.fail(event_name) + def fail_on_event(ad, event_name, timeout=EVENT_TIMEOUT): - """Wait for a timeout period and looks for the specified event - fails if it + """Wait for a timeout period and looks for the specified event - fails if it is observed. Args: ad: The android device event_name: The event to wait for (and fail on its appearance) """ - prefix = '' - if hasattr(ad, 'pretty_name'): - prefix = '[%s] ' % ad.pretty_name - try: - event = ad.ed.pop_event(event_name, timeout) - ad.log.info('%sReceived unwanted %s: %s', prefix, event_name, event['data']) - asserts.fail(event_name, extras=event) - except queue.Empty: - ad.log.info('%s%s not seen (as expected)', prefix, event_name) - return + prefix = '' + if hasattr(ad, 'pretty_name'): + prefix = '[%s] ' % ad.pretty_name + try: + event = ad.ed.pop_event(event_name, timeout) + ad.log.info('%sReceived unwanted %s: %s', prefix, event_name, + event['data']) + asserts.fail(event_name, extras=event) + except queue.Empty: + ad.log.info('%s%s not seen (as expected)', prefix, event_name) + return def config_privilege_override(dut, override_to_no_privilege): - """Configure the device to override the permission check and to disallow any + """Configure the device to override the permission check and to disallow any privileged RTT operations, e.g. disallow one-sided RTT to Responders (APs) which do not support IEEE 802.11mc. @@ -81,12 +83,12 @@ def config_privilege_override(dut, override_to_no_privilege): override_to_no_privilege: True to indicate no privileged ops, False for default (which will allow privileged ops). """ - dut.adb.shell("cmd wifirtt set override_assume_no_privilege %d" % ( - 1 if override_to_no_privilege else 0)) + dut.adb.shell("cmd wifirtt set override_assume_no_privilege %d" % + (1 if override_to_no_privilege else 0)) def get_rtt_constrained_results(scanned_networks, support_rtt): - """Filter the input list and only return those networks which either support + """Filter the input list and only return those networks which either support or do not support RTT (IEEE 802.11mc.) Args: @@ -96,34 +98,34 @@ def get_rtt_constrained_results(scanned_networks, support_rtt): Returns: a sub-set of the scanned_networks per support_rtt constraint. """ - matching_networks = [] - for network in scanned_networks: - if support_rtt: - if (rconsts.SCAN_RESULT_KEY_RTT_RESPONDER in network and - network[rconsts.SCAN_RESULT_KEY_RTT_RESPONDER]): - matching_networks.append(network) - else: - if (rconsts.SCAN_RESULT_KEY_RTT_RESPONDER not in network or - not network[rconsts.SCAN_RESULT_KEY_RTT_RESPONDER]): - matching_networks.append(network) + matching_networks = [] + for network in scanned_networks: + if support_rtt: + if (rconsts.SCAN_RESULT_KEY_RTT_RESPONDER in network + and network[rconsts.SCAN_RESULT_KEY_RTT_RESPONDER]): + matching_networks.append(network) + else: + if (rconsts.SCAN_RESULT_KEY_RTT_RESPONDER not in network + or not network[rconsts.SCAN_RESULT_KEY_RTT_RESPONDER]): + matching_networks.append(network) - return matching_networks + return matching_networks def scan_networks(dut): - """Perform a scan and return scan results. + """Perform a scan and return scan results. Args: dut: Device under test. Returns: an array of scan results. """ - wutils.start_wifi_connection_scan(dut) - return dut.droid.wifiGetScanResults() + wutils.start_wifi_connection_scan(dut) + return dut.droid.wifiGetScanResults() def scan_with_rtt_support_constraint(dut, support_rtt, repeat=0): - """Perform a scan and return scan results of APs: only those that support or + """Perform a scan and return scan results of APs: only those that support or do not support RTT (IEEE 802.11mc) - per the support_rtt parameter. Args: @@ -134,17 +136,17 @@ def scan_with_rtt_support_constraint(dut, support_rtt, repeat=0): Returns: an array of scan results. """ - for i in range(repeat + 1): - scan_results = scan_networks(dut) - aps = get_rtt_constrained_results(scan_results, support_rtt) - if len(aps) != 0: - return aps + for i in range(repeat + 1): + scan_results = scan_networks(dut) + aps = get_rtt_constrained_results(scan_results, support_rtt) + if len(aps) != 0: + return aps - return [] + return [] def select_best_scan_results(scans, select_count, lowest_rssi=-80): - """Select the strongest 'select_count' scans in the input list based on + """Select the strongest 'select_count' scans in the input list based on highest RSSI. Exclude all very weak signals, even if results in a shorter list. @@ -155,23 +157,24 @@ def select_best_scan_results(scans, select_count, lowest_rssi=-80): Returns: a list of the strongest 'select_count' scan results from the scans list. """ - def takeRssi(element): - return element['level'] - result = [] - scans.sort(key=takeRssi, reverse=True) - for scan in scans: - if len(result) == select_count: - break - if scan['level'] < lowest_rssi: - break # rest are lower since we're sorted - result.append(scan) + def takeRssi(element): + return element['level'] - return result + result = [] + scans.sort(key=takeRssi, reverse=True) + for scan in scans: + if len(result) == select_count: + break + if scan['level'] < lowest_rssi: + break # rest are lower since we're sorted + result.append(scan) + + return result def validate_ap_result(scan_result, range_result): - """Validate the range results: + """Validate the range results: - Successful if AP (per scan result) support 802.11mc (allowed to fail otherwise) - MAC of result matches the BSSID @@ -180,17 +183,20 @@ def validate_ap_result(scan_result, range_result): scan_result: Scan result for the AP range_result: Range result returned by the RTT API """ - asserts.assert_equal(scan_result[wutils.WifiEnums.BSSID_KEY], range_result[ - rconsts.EVENT_CB_RANGING_KEY_MAC_AS_STRING_BSSID], 'MAC/BSSID mismatch') - if (rconsts.SCAN_RESULT_KEY_RTT_RESPONDER in scan_result and - scan_result[rconsts.SCAN_RESULT_KEY_RTT_RESPONDER]): - asserts.assert_true(range_result[rconsts.EVENT_CB_RANGING_KEY_STATUS] == - rconsts.EVENT_CB_RANGING_STATUS_SUCCESS, - 'Ranging failed for an AP which supports 802.11mc!') + asserts.assert_equal( + scan_result[wutils.WifiEnums.BSSID_KEY], + range_result[rconsts.EVENT_CB_RANGING_KEY_MAC_AS_STRING_BSSID], + 'MAC/BSSID mismatch') + if (rconsts.SCAN_RESULT_KEY_RTT_RESPONDER in scan_result + and scan_result[rconsts.SCAN_RESULT_KEY_RTT_RESPONDER]): + asserts.assert_true( + range_result[rconsts.EVENT_CB_RANGING_KEY_STATUS] == + rconsts.EVENT_CB_RANGING_STATUS_SUCCESS, + 'Ranging failed for an AP which supports 802.11mc!') def validate_ap_results(scan_results, range_results): - """Validate an array of ranging results against the scan results used to + """Validate an array of ranging results against the scan results used to trigger the range. The assumption is that the results are returned in the same order as the request (which were the scan results). @@ -198,22 +204,21 @@ def validate_ap_results(scan_results, range_results): scan_results: Scans results used to trigger the range request range_results: Range results returned by the RTT API """ - asserts.assert_equal( - len(scan_results), - len(range_results), - 'Mismatch in length of scan results and range results') + asserts.assert_equal( + len(scan_results), len(range_results), + 'Mismatch in length of scan results and range results') - # sort first based on BSSID/MAC - scan_results.sort(key=lambda x: x[wutils.WifiEnums.BSSID_KEY]) - range_results.sort( - key=lambda x: x[rconsts.EVENT_CB_RANGING_KEY_MAC_AS_STRING_BSSID]) + # sort first based on BSSID/MAC + scan_results.sort(key=lambda x: x[wutils.WifiEnums.BSSID_KEY]) + range_results.sort( + key=lambda x: x[rconsts.EVENT_CB_RANGING_KEY_MAC_AS_STRING_BSSID]) - for i in range(len(scan_results)): - validate_ap_result(scan_results[i], range_results[i]) + for i in range(len(scan_results)): + validate_ap_result(scan_results[i], range_results[i]) def validate_aware_mac_result(range_result, mac, description): - """Validate the range result for an Aware peer specified with a MAC address: + """Validate the range result for an Aware peer specified with a MAC address: - Correct MAC address. The MAC addresses may contain ":" (which are ignored for the comparison) and @@ -224,14 +229,14 @@ def validate_aware_mac_result(range_result, mac, description): mac: MAC address of the peer description: Additional content to print on failure """ - mac1 = mac.replace(':', '').lower() - mac2 = range_result[rconsts.EVENT_CB_RANGING_KEY_MAC_AS_STRING].replace(':', - '').lower() - asserts.assert_equal(mac1, mac2, - '%s: MAC mismatch' % description) + mac1 = mac.replace(':', '').lower() + mac2 = range_result[rconsts.EVENT_CB_RANGING_KEY_MAC_AS_STRING].replace( + ':', '').lower() + asserts.assert_equal(mac1, mac2, '%s: MAC mismatch' % description) + def validate_aware_peer_id_result(range_result, peer_id, description): - """Validate the range result for An Aware peer specified with a Peer ID: + """Validate the range result for An Aware peer specified with a Peer ID: - Correct Peer ID - MAC address information not available @@ -240,16 +245,21 @@ def validate_aware_peer_id_result(range_result, peer_id, description): peer_id: Peer ID of the peer description: Additional content to print on failure """ - asserts.assert_equal(peer_id, - range_result[rconsts.EVENT_CB_RANGING_KEY_PEER_ID], - '%s: Peer Id mismatch' % description) - asserts.assert_false(rconsts.EVENT_CB_RANGING_KEY_MAC in range_result, - '%s: MAC Address not empty!' % description) - - -def extract_stats(results, range_reference_mm, range_margin_mm, min_rssi, - reference_lci=[], reference_lcr=[], summary_only=False): - """Extract statistics from a list of RTT results. Returns a dictionary + asserts.assert_equal(peer_id, + range_result[rconsts.EVENT_CB_RANGING_KEY_PEER_ID], + '%s: Peer Id mismatch' % description) + asserts.assert_false(rconsts.EVENT_CB_RANGING_KEY_MAC in range_result, + '%s: MAC Address not empty!' % description) + + +def extract_stats(results, + range_reference_mm, + range_margin_mm, + min_rssi, + reference_lci=[], + reference_lcr=[], + summary_only=False): + """Extract statistics from a list of RTT results. Returns a dictionary with results: - num_results (success or fails) - num_success_results @@ -290,99 +300,103 @@ def extract_stats(results, range_reference_mm, range_margin_mm, min_rssi, Returns: A dictionary of stats. """ - stats = {} - stats['num_results'] = 0 - stats['num_success_results'] = 0 - stats['num_no_results'] = 0 - stats['num_failures'] = 0 - stats['num_range_out_of_margin'] = 0 - stats['num_invalid_rssi'] = 0 - stats['any_lci_mismatch'] = False - stats['any_lcr_mismatch'] = False - stats['invalid_num_attempted'] = False - stats['invalid_num_successful'] = False - - range_max_mm = range_reference_mm + range_margin_mm - range_min_mm = range_reference_mm - range_margin_mm - - distances = [] - distance_std_devs = [] - rssis = [] - num_attempted_measurements = [] - num_successful_measurements = [] - status_codes = [] - lcis = [] - lcrs = [] - - for i in range(len(results)): - result = results[i] - - if result is None: # None -> timeout waiting for RTT result - stats['num_no_results'] = stats['num_no_results'] + 1 - continue - stats['num_results'] = stats['num_results'] + 1 - - status_codes.append(result[rconsts.EVENT_CB_RANGING_KEY_STATUS]) - if status_codes[-1] != rconsts.EVENT_CB_RANGING_STATUS_SUCCESS: - stats['num_failures'] = stats['num_failures'] + 1 - continue - stats['num_success_results'] = stats['num_success_results'] + 1 - - distance_mm = result[rconsts.EVENT_CB_RANGING_KEY_DISTANCE_MM] - distances.append(distance_mm) - if not range_min_mm <= distance_mm <= range_max_mm: - stats['num_range_out_of_margin'] = stats['num_range_out_of_margin'] + 1 - distance_std_devs.append( - result[rconsts.EVENT_CB_RANGING_KEY_DISTANCE_STD_DEV_MM]) - - rssi = result[rconsts.EVENT_CB_RANGING_KEY_RSSI] - rssis.append(rssi) - if not min_rssi <= rssi <= 0: - stats['num_invalid_rssi'] = stats['num_invalid_rssi'] + 1 - - num_attempted = result[ - rconsts.EVENT_CB_RANGING_KEY_NUM_ATTEMPTED_MEASUREMENTS] - num_attempted_measurements.append(num_attempted) - if num_attempted == 0: - stats['invalid_num_attempted'] = True - - num_successful = result[ - rconsts.EVENT_CB_RANGING_KEY_NUM_SUCCESSFUL_MEASUREMENTS] - num_successful_measurements.append(num_successful) - if num_successful == 0: - stats['invalid_num_successful'] = True - - lcis.append(result[rconsts.EVENT_CB_RANGING_KEY_LCI]) - if (result[rconsts.EVENT_CB_RANGING_KEY_LCI] != reference_lci): - stats['any_lci_mismatch'] = True - lcrs.append(result[rconsts.EVENT_CB_RANGING_KEY_LCR]) - if (result[rconsts.EVENT_CB_RANGING_KEY_LCR] != reference_lcr): - stats['any_lcr_mismatch'] = True - - if len(distances) > 0: - stats['distance_mean'] = statistics.mean(distances) - if len(distances) > 1: - stats['distance_std_dev'] = statistics.stdev(distances) - if len(rssis) > 0: - stats['rssi_mean'] = statistics.mean(rssis) - if len(rssis) > 1: - stats['rssi_std_dev'] = statistics.stdev(rssis) - if not summary_only: - stats['distances'] = distances - stats['distance_std_devs'] = distance_std_devs - stats['rssis'] = rssis - stats['num_attempted_measurements'] = num_attempted_measurements - stats['num_successful_measurements'] = num_successful_measurements - stats['status_codes'] = status_codes - stats['lcis'] = lcis - stats['lcrs'] = lcrs - - return stats - - -def run_ranging(dut, aps, iter_count, time_between_iterations, - target_run_time_sec=0): - """Executing ranging to the set of APs. + stats = {} + stats['num_results'] = 0 + stats['num_success_results'] = 0 + stats['num_no_results'] = 0 + stats['num_failures'] = 0 + stats['num_range_out_of_margin'] = 0 + stats['num_invalid_rssi'] = 0 + stats['any_lci_mismatch'] = False + stats['any_lcr_mismatch'] = False + stats['invalid_num_attempted'] = False + stats['invalid_num_successful'] = False + + range_max_mm = range_reference_mm + range_margin_mm + range_min_mm = range_reference_mm - range_margin_mm + + distances = [] + distance_std_devs = [] + rssis = [] + num_attempted_measurements = [] + num_successful_measurements = [] + status_codes = [] + lcis = [] + lcrs = [] + + for i in range(len(results)): + result = results[i] + + if result is None: # None -> timeout waiting for RTT result + stats['num_no_results'] = stats['num_no_results'] + 1 + continue + stats['num_results'] = stats['num_results'] + 1 + + status_codes.append(result[rconsts.EVENT_CB_RANGING_KEY_STATUS]) + if status_codes[-1] != rconsts.EVENT_CB_RANGING_STATUS_SUCCESS: + stats['num_failures'] = stats['num_failures'] + 1 + continue + stats['num_success_results'] = stats['num_success_results'] + 1 + + distance_mm = result[rconsts.EVENT_CB_RANGING_KEY_DISTANCE_MM] + distances.append(distance_mm) + if not range_min_mm <= distance_mm <= range_max_mm: + stats[ + 'num_range_out_of_margin'] = stats['num_range_out_of_margin'] + 1 + distance_std_devs.append( + result[rconsts.EVENT_CB_RANGING_KEY_DISTANCE_STD_DEV_MM]) + + rssi = result[rconsts.EVENT_CB_RANGING_KEY_RSSI] + rssis.append(rssi) + if not min_rssi <= rssi <= 0: + stats['num_invalid_rssi'] = stats['num_invalid_rssi'] + 1 + + num_attempted = result[ + rconsts.EVENT_CB_RANGING_KEY_NUM_ATTEMPTED_MEASUREMENTS] + num_attempted_measurements.append(num_attempted) + if num_attempted == 0: + stats['invalid_num_attempted'] = True + + num_successful = result[ + rconsts.EVENT_CB_RANGING_KEY_NUM_SUCCESSFUL_MEASUREMENTS] + num_successful_measurements.append(num_successful) + if num_successful == 0: + stats['invalid_num_successful'] = True + + lcis.append(result[rconsts.EVENT_CB_RANGING_KEY_LCI]) + if (result[rconsts.EVENT_CB_RANGING_KEY_LCI] != reference_lci): + stats['any_lci_mismatch'] = True + lcrs.append(result[rconsts.EVENT_CB_RANGING_KEY_LCR]) + if (result[rconsts.EVENT_CB_RANGING_KEY_LCR] != reference_lcr): + stats['any_lcr_mismatch'] = True + + if len(distances) > 0: + stats['distance_mean'] = statistics.mean(distances) + if len(distances) > 1: + stats['distance_std_dev'] = statistics.stdev(distances) + if len(rssis) > 0: + stats['rssi_mean'] = statistics.mean(rssis) + if len(rssis) > 1: + stats['rssi_std_dev'] = statistics.stdev(rssis) + if not summary_only: + stats['distances'] = distances + stats['distance_std_devs'] = distance_std_devs + stats['rssis'] = rssis + stats['num_attempted_measurements'] = num_attempted_measurements + stats['num_successful_measurements'] = num_successful_measurements + stats['status_codes'] = status_codes + stats['lcis'] = lcis + stats['lcrs'] = lcrs + + return stats + + +def run_ranging(dut, + aps, + iter_count, + time_between_iterations, + target_run_time_sec=0): + """Executing ranging to the set of APs. Will execute a minimum of 'iter_count' iterations. Will continue to run until execution time (just) exceeds 'target_run_time_sec'. @@ -397,54 +411,60 @@ def run_ranging(dut, aps, iter_count, time_between_iterations, Returns: a list of the events containing the RTT results (or None for a failed measurement). """ - max_peers = dut.droid.wifiRttMaxPeersInRequest() - - asserts.assert_true(len(aps) > 0, "Need at least one AP!") - if len(aps) > max_peers: - aps = aps[0:max_peers] - - events = {} # need to keep track per BSSID! - for ap in aps: - events[ap["BSSID"]] = [] - - start_clock = time.time() - iterations_done = 0 - run_time = 0 - while iterations_done < iter_count or ( - target_run_time_sec != 0 and run_time < target_run_time_sec): - if iterations_done != 0 and time_between_iterations != 0: - time.sleep(time_between_iterations) - - id = dut.droid.wifiRttStartRangingToAccessPoints(aps) - try: - event = dut.ed.pop_event( - decorate_event(rconsts.EVENT_CB_RANGING_ON_RESULT, id), EVENT_TIMEOUT) - range_results = event["data"][rconsts.EVENT_CB_RANGING_KEY_RESULTS] - asserts.assert_equal( - len(aps), - len(range_results), - 'Mismatch in length of scan results and range results') - for result in range_results: - bssid = result[rconsts.EVENT_CB_RANGING_KEY_MAC_AS_STRING] - asserts.assert_true(bssid in events, - "Result BSSID %s not in requested AP!?" % bssid) - asserts.assert_equal(len(events[bssid]), iterations_done, - "Duplicate results for BSSID %s!?" % bssid) - events[bssid].append(result) - except queue.Empty: - for ap in aps: - events[ap["BSSID"]].append(None) - - iterations_done = iterations_done + 1 - run_time = time.time() - start_clock - - return events - - -def analyze_results(all_aps_events, rtt_reference_distance_mm, - distance_margin_mm, min_expected_rssi, lci_reference, lcr_reference, - summary_only=False): - """Verifies the results of the RTT experiment. + max_peers = dut.droid.wifiRttMaxPeersInRequest() + + asserts.assert_true(len(aps) > 0, "Need at least one AP!") + if len(aps) > max_peers: + aps = aps[0:max_peers] + + events = {} # need to keep track per BSSID! + for ap in aps: + events[ap["BSSID"]] = [] + + start_clock = time.time() + iterations_done = 0 + run_time = 0 + while iterations_done < iter_count or (target_run_time_sec != 0 + and run_time < target_run_time_sec): + if iterations_done != 0 and time_between_iterations != 0: + time.sleep(time_between_iterations) + + id = dut.droid.wifiRttStartRangingToAccessPoints(aps) + try: + event = dut.ed.pop_event( + decorate_event(rconsts.EVENT_CB_RANGING_ON_RESULT, id), + EVENT_TIMEOUT) + range_results = event["data"][rconsts.EVENT_CB_RANGING_KEY_RESULTS] + asserts.assert_equal( + len(aps), len(range_results), + 'Mismatch in length of scan results and range results') + for result in range_results: + bssid = result[rconsts.EVENT_CB_RANGING_KEY_MAC_AS_STRING] + asserts.assert_true( + bssid in events, + "Result BSSID %s not in requested AP!?" % bssid) + asserts.assert_equal( + len(events[bssid]), iterations_done, + "Duplicate results for BSSID %s!?" % bssid) + events[bssid].append(result) + except queue.Empty: + for ap in aps: + events[ap["BSSID"]].append(None) + + iterations_done = iterations_done + 1 + run_time = time.time() - start_clock + + return events + + +def analyze_results(all_aps_events, + rtt_reference_distance_mm, + distance_margin_mm, + min_expected_rssi, + lci_reference, + lcr_reference, + summary_only=False): + """Verifies the results of the RTT experiment. Args: all_aps_events: Dictionary of APs, each a list of RTT result events. @@ -454,10 +474,10 @@ def analyze_results(all_aps_events, rtt_reference_distance_mm, lci_reference, lcr_reference: Expected LCI/LCR values (arrays of bytes). summary_only: Only include summary keys (reduce size). """ - all_stats = {} - for bssid, events in all_aps_events.items(): - stats = extract_stats(events, rtt_reference_distance_mm, - distance_margin_mm, min_expected_rssi, - lci_reference, lcr_reference, summary_only) - all_stats[bssid] = stats - return all_stats + all_stats = {} + for bssid, events in all_aps_events.items(): + stats = extract_stats(events, rtt_reference_distance_mm, + distance_margin_mm, min_expected_rssi, + lci_reference, lcr_reference, summary_only) + all_stats[bssid] = stats + return all_stats diff --git a/acts/framework/acts/test_utils/wifi/wifi_datastore_utils.py b/acts/framework/acts/test_utils/wifi/wifi_datastore_utils.py index 3c045db8b6..44532d7de3 100755 --- a/acts/framework/acts/test_utils/wifi/wifi_datastore_utils.py +++ b/acts/framework/acts/test_utils/wifi/wifi_datastore_utils.py @@ -84,11 +84,12 @@ def remove_device(name): return True return False -def lock_device(name): +def lock_device(name, admin): """Lock a device(AP or Packet Capturer) in datastore. Args: name: string, hostname of the device in datastore. + admin: string, unique admin name for locking. Returns: True if operation was successful; 0 otherwise. """ @@ -96,7 +97,7 @@ def lock_device(name): logging.debug("Request = %s" % request) response = requests.put(request, headers=HTTP_HEADER, - data=json.dumps({"hostname":name, "locked_by":"admin"})) + data=json.dumps({"hostname":name, "locked_by":admin})) if response.json()['result']: logging.info("Locked device %s in datastore" % name) return True @@ -131,7 +132,7 @@ def show_device(name): request = DATASTORE_HOST + '/' + SHOW_DEVICE + name logging.debug("Request = %s" % request) response = requests.get(request) - if 'null' in response.text: + if 'error' in response.text: return None return response.json() diff --git a/acts/framework/acts/test_utils/wifi/wifi_test_utils.py b/acts/framework/acts/test_utils/wifi/wifi_test_utils.py index 0f86c7e611..d4b2536bbd 100755 --- a/acts/framework/acts/test_utils/wifi/wifi_test_utils.py +++ b/acts/framework/acts/test_utils/wifi/wifi_test_utils.py @@ -49,12 +49,12 @@ roaming_attn = { "AP1_on_AP2_off": [ 0, 0, - 95, - 95 + 60, + 60 ], "AP1_off_AP2_on": [ - 95, - 95, + 60, + 60, 0, 0 ], @@ -1664,6 +1664,36 @@ def set_attns(attenuator, attn_val_name): attn_val_name) raise +def set_attns_steps(attenuator, attn_val_name, steps=10, wait_time=12): + """Sets attenuation values on attenuators used in this test. + + Args: + attenuator: The attenuator object. + attn_val_name: Name of the attenuation value pair to use. + steps: Number of attenuator changes to reach the target value. + wait_time: Sleep time for each change of attenuator. + """ + logging.info("Set attenuation values to %s in %d step(s)", roaming_attn[attn_val_name], steps) + current_atten = [ + attenuator[0].get_atten(), attenuator[1].get_atten(), + attenuator[2].get_atten(), attenuator[3].get_atten()] + target_atten = [ + roaming_attn[attn_val_name][0], roaming_attn[attn_val_name][1], + roaming_attn[attn_val_name][2], roaming_attn[attn_val_name][3]] + while steps > 0: + next_atten = list(map( + lambda x, y: round((y + (steps - 1) * x) / steps) , current_atten, target_atten)) + try: + attenuator[0].set_atten(next_atten[0]) + attenuator[1].set_atten(next_atten[1]) + attenuator[2].set_atten(next_atten[2]) + attenuator[3].set_atten(next_atten[3]) + time.sleep(wait_time) + except: + logging.exception("Failed to set attenuation values %s.", attn_val_name) + raise + current_atten = next_atten + steps = steps - 1 def trigger_roaming_and_validate(dut, attenuator, attn_val_name, expected_con): """Sets attenuators to trigger roaming and validate the DUT connected @@ -1678,9 +1708,7 @@ def trigger_roaming_and_validate(dut, attenuator, attn_val_name, expected_con): WifiEnums.SSID_KEY: expected_con[WifiEnums.SSID_KEY], WifiEnums.BSSID_KEY: expected_con["bssid"], } - set_attns(attenuator, attn_val_name) - logging.info("Wait %ss for roaming to finish.", ROAMING_TIMEOUT) - time.sleep(ROAMING_TIMEOUT) + set_attns_steps(attenuator, attn_val_name) verify_wifi_connection_info(dut, expected_con) expected_bssid = expected_con[WifiEnums.BSSID_KEY] diff --git a/acts/framework/acts/utils.py b/acts/framework/acts/utils.py index edc38509cb..a16339fd3f 100755 --- a/acts/framework/acts/utils.py +++ b/acts/framework/acts/utils.py @@ -817,26 +817,23 @@ def parse_ping_ouput(ad, count, out, loss_tolerance=20): False: if packet loss is more than loss_tolerance% True: if all good """ - out = out.split('\n')[-3:] - stats = out[1].split(',') - # For failure case, line of interest becomes the last line - if len(stats) != 4: - stats = out[2].split(',') - packet_loss = float(stats[2].split('%')[0]) - packet_xmit = int(stats[0].split()[0]) - packet_rcvd = int(stats[1].split()[0]) - min_packet_xmit_rcvd = (100 - loss_tolerance) * 0.01 + result = re.search( + r"(\d+) packets transmitted, (\d+) received, (\d+)% packet loss", out) + if not result: + ad.log.info("Ping failed with %s", out) + return False + packet_loss = int(result.group(3)) + packet_xmit = int(result.group(1)) + packet_rcvd = int(result.group(2)) + min_packet_xmit_rcvd = (100 - loss_tolerance) * 0.01 if (packet_loss > loss_tolerance or packet_xmit < count * min_packet_xmit_rcvd or packet_rcvd < count * min_packet_xmit_rcvd): - ad.log.error( - "More than %d %% packet loss seen, Expected Packet_count %d \ - Packet loss %.2f%% Packets_xmitted %d Packets_rcvd %d", - loss_tolerance, count, packet_loss, packet_xmit, packet_rcvd) + ad.log.error("%s, ping failed with loss more than tolerance %s%%", + result.group(0), loss_tolerance) return False - ad.log.info("Pkt_count %d Pkt_loss %.2f%% Pkt_xmit %d Pkt_rcvd %d", count, - packet_loss, packet_xmit, packet_rcvd) + ad.log.info("Ping succeed with %s", result.group(0)) return True @@ -858,19 +855,17 @@ def adb_shell_ping(ad, if count: ping_cmd += " -c %d" % count if dest_ip: - ping_cmd += " %s | tee /data/ping.txt" % dest_ip + ping_cmd += " %s" % dest_ip try: ad.log.info("Starting ping test to %s using adb command %s", dest_ip, ping_cmd) - out = ad.adb.shell(ping_cmd, timeout=timeout) + out = ad.adb.shell(ping_cmd, timeout=timeout, ignore_status=True) if not parse_ping_ouput(ad, count, out, loss_tolerance): return False return True except Exception as e: ad.log.warning("Ping Test to %s failed with exception %s", dest_ip, e) return False - finally: - ad.adb.shell("rm /data/ping.txt", timeout=10, ignore_status=True) def unzip_maintain_permissions(zip_path, extract_location): diff --git a/acts/tests/google/ble/bt5/AdvertisingSetTest.py b/acts/tests/google/ble/bt5/AdvertisingSetTest.py index 0f0c352f0e..e06536d8db 100644 --- a/acts/tests/google/ble/bt5/AdvertisingSetTest.py +++ b/acts/tests/google/ble/bt5/AdvertisingSetTest.py @@ -28,15 +28,15 @@ from acts.asserts import assert_true from acts.test_decorators import test_tracker_info from acts.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest from acts.test_utils.bt.bt_constants import ble_scan_settings_modes -from acts.test_utils.bt.bt_test_utils import advertising_set_started -from acts.test_utils.bt.bt_test_utils import advertising_set_stopped -from acts.test_utils.bt.bt_test_utils import advertising_set_enabled -from acts.test_utils.bt.bt_test_utils import advertising_set_data_set -from acts.test_utils.bt.bt_test_utils import advertising_set_scan_response_set -from acts.test_utils.bt.bt_test_utils import advertising_set_parameters_update -from acts.test_utils.bt.bt_test_utils import advertising_set_periodic_parameters_updated -from acts.test_utils.bt.bt_test_utils import advertising_set_periodic_data_set -from acts.test_utils.bt.bt_test_utils import advertising_set_periodic_enable +from acts.test_utils.bt.bt_constants import advertising_set_started +from acts.test_utils.bt.bt_constants import advertising_set_stopped +from acts.test_utils.bt.bt_constants import advertising_set_enabled +from acts.test_utils.bt.bt_constants import advertising_set_data_set +from acts.test_utils.bt.bt_constants import advertising_set_scan_response_set +from acts.test_utils.bt.bt_constants import advertising_set_parameters_update +from acts.test_utils.bt.bt_constants import advertising_set_periodic_parameters_updated +from acts.test_utils.bt.bt_constants import advertising_set_periodic_data_set +from acts.test_utils.bt.bt_constants import advertising_set_periodic_enable from acts.test_utils.bt.bt_test_utils import reset_bluetooth from acts import signals @@ -67,6 +67,7 @@ class AdvertisingSetTest(BluetoothBaseTest): self.adv_ad = self.android_devices[0] def setup_class(self): + super(AdvertisingSetTest, self).setup_class() if not self.adv_ad.droid.bluetoothIsLeExtendedAdvertisingSupported(): raise signals.TestSkipClass( "Advertiser does not support LE Extended Advertising") diff --git a/acts/tests/google/ble/bt5/Bt5ScanTest.py b/acts/tests/google/ble/bt5/Bt5ScanTest.py index 633489f038..a07769e2e7 100644 --- a/acts/tests/google/ble/bt5/Bt5ScanTest.py +++ b/acts/tests/google/ble/bt5/Bt5ScanTest.py @@ -28,14 +28,14 @@ from acts.test_decorators import test_tracker_info from acts.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest from acts.test_utils.bt.bt_constants import ble_scan_settings_phys from acts.test_utils.bt.bt_constants import ble_scan_settings_modes -from acts.test_utils.bt.bt_test_utils import batch_scan_result +from acts.test_utils.bt.bt_constants import batch_scan_result from acts.test_utils.bt.bt_test_utils import cleanup_scanners_and_advertisers from acts.test_utils.bt.bt_test_utils import generate_ble_advertise_objects from acts.test_utils.bt.bt_test_utils import generate_ble_scan_objects from acts.test_utils.bt.bt_test_utils import reset_bluetooth from acts.test_utils.bt.bt_constants import scan_result -from acts.test_utils.bt.bt_test_utils import advertising_set_on_own_address_read -from acts.test_utils.bt.bt_test_utils import advertising_set_started +from acts.test_utils.bt.bt_constants import advertising_set_on_own_address_read +from acts.test_utils.bt.bt_constants import advertising_set_started from acts import signals @@ -66,6 +66,7 @@ class Bt5ScanTest(BluetoothBaseTest): self.adv_ad = self.android_devices[1] def setup_class(self): + super(Bt5ScanTest, self).setup_class() if not self.scn_ad.droid.bluetoothIsLeExtendedAdvertisingSupported(): raise signals.TestSkipClass( "Scanner does not support LE Extended Advertising") diff --git a/acts/tests/google/ble/bt5/PhyTest.py b/acts/tests/google/ble/bt5/PhyTest.py index 5af778d1d9..b892d26c2b 100644 --- a/acts/tests/google/ble/bt5/PhyTest.py +++ b/acts/tests/google/ble/bt5/PhyTest.py @@ -40,6 +40,7 @@ def lfmt(txPhy, rxPhy): class PhyTest(GattConnectedBaseTest): def setup_class(self): + super(PhyTest, self).setup_class() if not self.cen_ad.droid.bluetoothIsLe2MPhySupported(): raise signals.TestSkipClass( "Central device does not support LE 2M PHY") diff --git a/acts/tests/google/ble/concurrency/ConcurrentBleAdvertisingTest.py b/acts/tests/google/ble/concurrency/ConcurrentBleAdvertisingTest.py index de81bacdc0..65ce278868 100644 --- a/acts/tests/google/ble/concurrency/ConcurrentBleAdvertisingTest.py +++ b/acts/tests/google/ble/concurrency/ConcurrentBleAdvertisingTest.py @@ -482,6 +482,8 @@ class ConcurrentBleAdvertisingTest(BluetoothBaseTest): self.log.error( "Test failed, filtering callback onSuccess never occurred: {}". format(error)) + self.scn_ad.droid.bleSetScanSettingsScanMode( + ble_scan_settings_modes['low_latency']) self.scn_ad.droid.bleSetScanFilterDeviceName( self.adv_ad.droid.bluetoothGetLocalName()) filter_list, scan_settings, scan_callback = generate_ble_scan_objects( diff --git a/acts/tests/google/ble/concurrency/ConcurrentBleScanningTest.py b/acts/tests/google/ble/concurrency/ConcurrentBleScanningTest.py index 83b5ddc60e..c3e71f24a8 100644 --- a/acts/tests/google/ble/concurrency/ConcurrentBleScanningTest.py +++ b/acts/tests/google/ble/concurrency/ConcurrentBleScanningTest.py @@ -1,4 +1,4 @@ -#/usr/bin/env python3.4 +#!/usr/bin/env python3 # # Copyright (C) 2016 The Android Open Source Project # @@ -30,7 +30,7 @@ from acts.test_utils.bt.bt_constants import ble_scan_settings_modes from acts.test_utils.bt.bt_constants import adv_succ from acts.test_utils.bt.bt_test_utils import generate_ble_advertise_objects from acts.test_utils.bt.bt_test_utils import reset_bluetooth -from acts.test_utils.bt.bt_test_utils import scan_failed +from acts.test_utils.bt.bt_constants import scan_failed from acts.test_utils.bt.bt_constants import scan_result from acts.test_utils.bt.bt_test_utils import take_btsnoop_logs @@ -205,13 +205,13 @@ class ConcurrentBleScanningTest(BluetoothBaseTest): for callback in scan_callback_list: try: self.scn_ad.ed.pop_event( - scan_result.format(scan_callback), self.default_timeout) + scan_result.format(callback), self.default_timeout) self.log.info( "Found scan event successfully. Iteration {} successful." .format(i)) except Exception: self.log.info("Failed to find a scan result for callback {}" - .format(scan_callback)) + .format(callback)) return False i += 1 for callback in scan_callback_list: @@ -244,12 +244,7 @@ class ConcurrentBleScanningTest(BluetoothBaseTest): Priority: 1 """ test_result = True - self.scn_ad.droid.bleSetScanSettingsCallbackType( - ble_scan_settings_callback_types['all_matches']) - self.scn_ad.droid.bleSetScanSettingsScanMode(ble_scan_settings_modes[ - 'low_latency']) filter_list = self.scn_ad.droid.bleGenFilterList() - self.scn_ad.droid.bleBuildScanFilter(filter_list) scan_settings = self.scn_ad.droid.bleBuildScanSetting() scan_callback_list = [] for i in range(self.max_concurrent_scans): @@ -264,13 +259,13 @@ class ConcurrentBleScanningTest(BluetoothBaseTest): try: self.scn_ad.ed.pop_event( scan_failed.format(scan_callback), self.default_timeout) - self.log.error( - "Unexpected scan event found. Iteration {} successful." - .format(i)) - test_result = False + self.log.info( + "Found scan event successfully. Iteration {} successful." + .format(self.max_concurrent_scans + 1)) except Exception: - self.log.info("No onScanFailed event for callback {} as expected." - .format(scan_callback)) + self.log.error("Failed to find a onScanFailed event for callback {}" + .format(scan_callback)) + test_result = False for callback in scan_callback_list: self.scn_ad.droid.bleStopBleScan(callback) return test_result diff --git a/acts/tests/google/ble/filtering/UniqueFilteringTest.py b/acts/tests/google/ble/filtering/UniqueFilteringTest.py index e4ad858197..3e89f033b6 100644 --- a/acts/tests/google/ble/filtering/UniqueFilteringTest.py +++ b/acts/tests/google/ble/filtering/UniqueFilteringTest.py @@ -31,7 +31,7 @@ from acts.test_utils.bt.bt_constants import ble_scan_settings_modes from acts.test_utils.bt.bt_test_utils import generate_ble_advertise_objects from acts.test_utils.bt.bt_test_utils import generate_ble_scan_objects from acts.test_utils.bt.bt_constants import adv_succ -from acts.test_utils.bt.bt_test_utils import batch_scan_result +from acts.test_utils.bt.bt_constants import batch_scan_result from acts.test_utils.bt.bt_constants import scan_result @@ -334,14 +334,12 @@ class UniqueFilteringTest(BluetoothBaseTest): test_result = True service_uuid = "00000000-0000-1000-8000-00805F9B34FB" service_mask = "00000000-0000-1000-8000-00805F9B34FA" - self.adv_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True) self.scn_ad.droid.bleSetScanFilterServiceUuid(service_uuid, service_mask) self.adv_ad.droid.bleSetAdvertiseSettingsAdvertiseMode( ble_advertise_settings_modes['low_latency']) filter_list, scan_settings, scan_callback = generate_ble_scan_objects( self.scn_ad.droid) - self.scn_ad.droid.bleBuildScanFilter(filter_list) expected_event_name = scan_result.format(scan_callback) self.adv_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True) self.adv_ad.droid.bleSetAdvertiseDataIncludeTxPowerLevel(True) @@ -361,7 +359,7 @@ class UniqueFilteringTest(BluetoothBaseTest): event_info = self.scn_ad.ed.pop_event(expected_event_name, self.default_timeout) self.log.error( - "Unexpectedly found an advertiser:".format(event_info)) + "Unexpectedly found an advertiser: {}".format(event_info)) test_result = False except Empty as error: self.log.debug("No events were found as expected.") diff --git a/acts/tests/google/power/wifi/PowerWiFiscanTest.py b/acts/tests/google/power/wifi/PowerWiFiscanTest.py index 5b8de6c655..7ff6d82dc8 100644 --- a/acts/tests/google/power/wifi/PowerWiFiscanTest.py +++ b/acts/tests/google/power/wifi/PowerWiFiscanTest.py @@ -32,20 +32,20 @@ class PowerWiFiscanTest(PWBT.PowerWiFiBaseTest): ' -e class com.google.android.platform.powertests.' 'WifiScanTest#testWifiSingleShotScan' ' com.google.android.platform.powertests/' - 'android.test.InstrumentationTestRunner > /dev/null &' % + 'androidx.test.runner.AndroidJUnitRunner > /dev/null &' % (self.mon_duration + self.mon_offset + 10)) BACKGROUND_SCAN = ('am instrument -w -r -e min_scan_count \"1\" -e ' 'WifiScanTest-testWifiBackgroundScan %d -e class ' 'com.google.android.platform.powertests.WifiScan' 'Test#testWifiBackgroundScan com.google.android.' - 'platform.powertests/android.test.Instrumentation' - 'TestRunner > /dev/null &' % + 'platform.powertests/androidx.test.runner.' + 'AndroidJUnitRunner > /dev/null &' % (self.mon_duration + self.mon_offset + 10)) WIFI_SCAN = ('am instrument -w -r -e min_scan_count \"1\" -e ' 'WifiScanTest-testWifiScan %d -e class ' 'com.google.android.platform.powertests.WifiScanTest#' 'testWifiScan com.google.android.platform.powertests/' - 'android.test.InstrumentationTestRunner > /dev/null &' % + 'androidx.test.runner.AndroidJUnitRunner > /dev/null &' % (self.mon_duration + self.mon_offset + 10)) self.APK_SCAN_CMDS = { 'singleshot': SINGLE_SHOT_SCAN, diff --git a/acts/tests/google/tel/live/TelLiveDataTest.py b/acts/tests/google/tel/live/TelLiveDataTest.py index c0034c01f8..72bf2489ca 100644 --- a/acts/tests/google/tel/live/TelLiveDataTest.py +++ b/acts/tests/google/tel/live/TelLiveDataTest.py @@ -2414,8 +2414,7 @@ class TelLiveDataTest(TelephonyBaseTest): self.log.error("Failed wifi connection, aborting!") return False - if not verify_internet_connection( - self.log, ad, 'http://www.google.com', 100, .1): + if not verify_internet_connection(self.log, ad): self.log.error("Failed to get user-plane traffic, aborting!") return False diff --git a/acts/tests/google/wifi/WifiChaosTest.py b/acts/tests/google/wifi/WifiChaosTest.py index 9c7c24f884..4e5d165799 100755 --- a/acts/tests/google/wifi/WifiChaosTest.py +++ b/acts/tests/google/wifi/WifiChaosTest.py @@ -14,7 +14,9 @@ # See the License for the specific language governing permissions and # limitations under the License. +import re import sys +import random import time import acts.controllers.packet_capture as packet_capture @@ -35,7 +37,8 @@ WAIT_BEFORE_CONNECTION = 1 SINGLE_BAND = 1 DUAL_BAND = 2 -TIMEOUT = 1 +TIMEOUT = 60 +TEST = 'test_' PING_ADDR = 'www.google.com' @@ -51,6 +54,35 @@ class WifiChaosTest(WifiBaseTest): BaseTestClass.__init__(self, configs) self.generate_interop_tests() + def randomize_testcases(self): + """Randomize the list of hosts and build a random order of tests, + based on SSIDs, keeping all the relevant bands of an AP together. + + """ + temp_tests = list() + hosts = self.user_params['interop_host'] + + random.shuffle(hosts) + + for host in hosts: + ssid_2g = None + ssid_5g = None + info = dutils.show_device(host) + + # Based on the information in datastore, add to test list if + # AP has 2G band. + if 'ssid_2g' in info: + ssid_2g = info['ssid_2g'] + temp_tests.append(TEST + ssid_2g) + + # Based on the information in datastore, add to test list if + # AP has 5G band. + if 'ssid_5g' in info: + ssid_5g = info['ssid_5g'] + temp_tests.append(TEST + ssid_5g) + + self.tests = temp_tests + def generate_interop_testcase(self, base_test, testcase_name, ssid_dict): """Generates a single test case from the given data. @@ -74,9 +106,11 @@ class WifiChaosTest(WifiBaseTest): testcase_name = list(ssid_dict)[0] self.generate_interop_testcase(self.interop_base_test, testcase_name, ssid_dict) + self.randomize_testcases() def setup_class(self): self.dut = self.android_devices[0] + self.admin = 'admin' + str(random.randint(1000001, 12345678)) wutils.wifi_test_device_init(self.dut) # Set country code explicitly to "US". self.dut.droid.wifiSetCountryCode(wutils.WifiEnums.CountryCode.US) @@ -98,14 +132,15 @@ class WifiChaosTest(WifiBaseTest): device_name = device['hostname'] device_type = device['ap_label'] - if device_type == 'PCAP'and dutils.lock_device(device_name): - host = device['ip_address'] - self.log.info("Locked Packet Capture device: %s" % device_name) - locked_pcap = True - break - - elif device_type == 'PCAP': - self.log.warning("Failed to lock %s PCAP.") + if device_type == 'PCAP' and not device['lock_status']: + if dutils.lock_device(device_name, self.admin): + self.pcap_host = device_name + host = device['ip_address'] + self.log.info("Locked Packet Capture device: %s" % device_name) + locked_pcap = True + break + else: + self.log.warning("Failed to lock %s PCAP." % device_name) if not locked_pcap: return False @@ -120,10 +155,22 @@ class WifiChaosTest(WifiBaseTest): self.dut.droid.wakeLockAcquireBright() self.dut.droid.wakeUpNow() + def on_pass(self, test_name, begin_time): + wutils.stop_pcap(self.pcap, self.pcap_pid, True) + + def on_fail(self, test_name, begin_time): + wutils.stop_pcap(self.pcap, self.pcap_pid, False) + self.dut.take_bug_report(test_name, begin_time) + self.dut.cat_adb_log(test_name, begin_time) + def teardown_test(self): self.dut.droid.wakeLockRelease() self.dut.droid.goToSleepNow() - wutils.reset_wifi(self.dut) + + def teardown_class(self): + # Unlock the PCAP. + if not dutils.unlock_device(self.pcap_host): + self.log.warning("Failed to unlock %s PCAP. Check in datastore.") """Helper Functions""" @@ -154,17 +201,37 @@ class WifiChaosTest(WifiBaseTest): if "100% packet loss" in result: raise signals.TestFailure("100% packet loss during ping") - def run_connect_disconnect(self, network): + def unlock_and_turn_off_ap(self, hostname, rpm_port, rpm_ip): + """UNlock the AP in datastore and turn off the AP. + + Args: + hostname: Hostname of the AP. + rpm_port: Port number on the RPM for the AP. + rpm_ip: RPM's IP address. + + """ + # Un-Lock AP in datastore. + self.log.debug("Un-lock AP in datastore") + if not dutils.unlock_device(hostname): + self.log.warning("Failed to unlock %s AP. Check AP in datastore.") + # Turn OFF AP from the RPM port. + rutils.turn_off_ap(rpm_port, rpm_ip) + + def run_connect_disconnect(self, network, hostname, rpm_port, rpm_ip, + release_ap): """Run connect/disconnect to a given network in loop. Args: - network: dict, network information. + network: Dict, network information. + hostname: Hostanme of the AP to connect to. + rpm_port: Port number on the RPM for the AP. + rpm_ip: Port number on the RPM for the AP. + release_ap: Flag to determine if we should turn off the AP yet. Raises: TestFailure if the network connection fails. """ - for attempt in range(1): - # TODO:(bmahadev) Change it to 5 or more attempts later. + for attempt in range(5): try: begin_time = time.time() ssid = network[WifiEnums.SSID_KEY] @@ -172,7 +239,7 @@ class WifiChaosTest(WifiBaseTest): asserts.assert_true(net_id != -1, "Add network %s failed" % network) self.log.info("Connecting to %s" % ssid) self.scan_and_connect_by_id(network, net_id) - self.run_ping(1) + self.run_ping(10) wutils.wifi_forget_network(self.dut, ssid) time.sleep(WAIT_BEFORE_CONNECTION) except: @@ -181,8 +248,26 @@ class WifiChaosTest(WifiBaseTest): # TODO:(bmahadev) Uncomment after scan issue is fixed. # self.dut.take_bug_report(ssid, begin_time) # self.dut.cat_adb_log(ssid, begin_time) + if release_ap: + self.unlock_and_turn_off_ap(hostname, rpm_port, rpm_ip) raise signals.TestFailure("Failed to connect to %s" % ssid) + def get_band_and_chan(self, ssid): + """Get the band and channel information from SSID. + + Args: + ssid: SSID of the network. + + """ + ssid_info = ssid.split('_') + self.band = ssid_info[-1] + for item in ssid_info: + # Skip over the router model part. + if 'ch' in item and item != ssid_info[0]: + self.chan = re.search(r'(\d+)',item).group(0) + return + raise signals.TestFailure("Channel information not found in SSID.") + def interop_base_test(self, ssid, hostname): """Base test for all the connect-disconnect interop tests. @@ -201,20 +286,29 @@ class WifiChaosTest(WifiBaseTest): network = {} network['password'] = 'password' network['SSID'] = ssid + release_ap = False wutils.reset_wifi(self.dut) # Lock AP in datastore. self.log.info("Lock AP in datastore") - if not dutils.lock_device(hostname): + + ap_info = dutils.show_device(hostname) + + # If AP is locked by a different test admin, then we skip. + if ap_info['lock_status'] and ap_info['locked_by'] != self.admin: + raise signals.TestSkip("AP %s is locked, skipping test" % hostname) + + if not dutils.lock_device(hostname, self.admin): self.log.warning("Failed to lock %s AP. Unlock AP in datastore" " and try again.") raise signals.TestFailure("Failed to lock AP") - ap_info = dutils.show_device(hostname) - band = SINGLE_BAND if ('ssid_2g' in ap_info) and ('ssid_5g' in ap_info): band = DUAL_BAND + if (band == SINGLE_BAND) or ( + band == DUAL_BAND and '5G' in ssid): + release_ap = True # Get AP RPM attributes and Turn ON AP. rpm_ip = ap_info['rpm_ip'] @@ -222,20 +316,16 @@ class WifiChaosTest(WifiBaseTest): rutils.turn_on_ap(self.pcap, ssid, rpm_port, rpm_ip=rpm_ip) self.log.info("Finished turning ON AP.") - # Experimental to check if 2G connects better. - time.sleep(30) + # Experimental. Some APs take upto a min to come online. + time.sleep(60) - self.run_connect_disconnect(network) + self.get_band_and_chan(ssid) + self.pcap.configure_monitor_mode(self.band, self.chan) + self.pcap_pid = wutils.start_pcap( + self.pcap, self.band.lower(), self.log_path, self.test_name) + self.run_connect_disconnect(network, hostname, rpm_port, rpm_ip, + release_ap) # Un-lock only if it's a single band AP or we are running the last band. - if (band == SINGLE_BAND) or ( - band == DUAL_BAND and hostapd_constants.BAND_5G in \ - sys._getframe().f_code.co_name): - - # Un-Lock AP in datastore. - self.log.debug("Un-lock AP in datastore") - if not dutils.unlock_device(hostname): - self.log.warning("Failed to unlock %s AP. Check AP in datastore.") - - # Turn OFF AP from the RPM port. - rutils.turn_off_ap(rpm_port, rpm_ip) + if release_ap: + self.unlock_and_turn_off_ap(hostname, rpm_port, rpm_ip) diff --git a/acts/tests/google/wifi/WifiCrashStressTest.py b/acts/tests/google/wifi/WifiCrashStressTest.py index 73f6460a52..6668f14059 100755 --- a/acts/tests/google/wifi/WifiCrashStressTest.py +++ b/acts/tests/google/wifi/WifiCrashStressTest.py @@ -21,7 +21,7 @@ from acts import asserts from acts import utils from acts.test_decorators import test_tracker_info from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest -from acts.test_utils.tel.tel_test_utils import disable_qxdm_logger +from acts.test_utils.tel.tel_test_utils import stop_qxdm_logger WifiEnums = wutils.WifiEnums @@ -85,14 +85,14 @@ class WifiCrashStressTest(WifiBaseTest): del self.user_params["reference_networks"] """Helper Functions""" - def trigger_wifi_firmware_crash(self, ad, timeout=30): + def trigger_wifi_firmware_crash(self, ad, timeout=15): pre_timestamp = ad.adb.getprop("vendor.debug.ssrdump.timestamp") ad.adb.shell( "setprop persist.vendor.sys.modem.diag.mdlog false", ignore_status=True) # Legacy pixels use persist.sys.modem.diag.mdlog. ad.adb.shell( "setprop persist.sys.modem.diag.mdlog false", ignore_status=True) - disable_qxdm_logger(ad) + stop_qxdm_logger(ad) cmd = ('am instrument -w -e request "4b 25 03 b0 00" ' '"com.google.mdstest/com.google.mdstest.instrument.' 'ModemCommandInstrumentation"') @@ -105,7 +105,7 @@ class WifiCrashStressTest(WifiBaseTest): "SSR didn't happened %s %s" % (subsystem, timestamp)) """Tests""" - @test_tracker_info(uuid="") + @test_tracker_info(uuid="b5a982ef-10ef-4f36-a1b5-1e5d1fec06a4") def test_firmware_crash_wifi_reconnect_stress(self): """Firmware crash stress test for station mode @@ -124,7 +124,7 @@ class WifiCrashStressTest(WifiBaseTest): self.trigger_wifi_firmware_crash(self.dut) wutils.connect_to_wifi_network(self.dut, self.network) - @test_tracker_info(uuid="") + @test_tracker_info(uuid="204a921b-b0de-47f7-9b70-9384317051c8") def test_firmware_crash_softap_reconnect_stress(self): """Firmware crash stress test for softap mode @@ -153,14 +153,13 @@ class WifiCrashStressTest(WifiBaseTest): asserts.assert_true( utils.adb_shell_ping(self.dut_client, count=10, dest_ip=dut_addr, timeout=20), "%s ping %s failed" % (self.dut_client.serial, dut_addr)) - wutils.reset_wifi(self.dut_client) for count in range(self.stress_count): self.log.info("%s: %d/%d" % (self.current_test_name, count + 1, self.stress_count)) + wutils.reset_wifi(self.dut_client) # Trigger firmware crash self.trigger_wifi_firmware_crash(self.dut) # Connect DUT to Network - wutils.wifi_toggle_state(self.dut_client, True) wutils.connect_to_wifi_network(self.dut_client, config, check_connectivity=False) # Ping the DUT server_addr = self.dut.droid.connectivityGetIPv4Addresses("wlan0")[0] @@ -169,7 +168,7 @@ class WifiCrashStressTest(WifiBaseTest): "%s ping %s failed" % (self.dut_client.serial, dut_addr)) wutils.stop_wifi_tethering(self.dut) - @test_tracker_info(uuid="") + @test_tracker_info(uuid="4b7f2d89-82be-41de-9277-e938cc1c318b") def test_firmware_crash_concurrent_reconnect_stress(self): """Firmware crash stress test for concurrent mode @@ -199,11 +198,11 @@ class WifiCrashStressTest(WifiBaseTest): # Client connects to Softap wutils.wifi_toggle_state(self.dut_client, True) wutils.connect_to_wifi_network(self.dut_client, config) - wutils.reset_wifi(self.dut_client) - wutils.reset_wifi(self.dut) for count in range(self.stress_count): self.log.info("%s: %d/%d" % (self.current_test_name, count + 1, self.stress_count)) + wutils.reset_wifi(self.dut_client) + wutils.reset_wifi(self.dut) # Trigger firmware crash self.trigger_wifi_firmware_crash(self.dut) wutils.connect_to_wifi_network(self.dut, self.network) diff --git a/acts/tests/google/wifi/WifiManagerTest.py b/acts/tests/google/wifi/WifiManagerTest.py index 30996486cf..b63fee2db9 100755 --- a/acts/tests/google/wifi/WifiManagerTest.py +++ b/acts/tests/google/wifi/WifiManagerTest.py @@ -26,6 +26,8 @@ import acts.utils from acts import asserts from acts.test_decorators import test_tracker_info +from acts.test_utils.bt.bt_test_utils import enable_bluetooth +from acts.test_utils.bt.bt_test_utils import disable_bluetooth from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest WifiEnums = wutils.WifiEnums @@ -961,3 +963,19 @@ class WifiManagerTest(WifiBaseTest): "ping DUT %s failed" % dut_address) self.dut.droid.wakeLockAcquireBright() self.dut.droid.wakeUpNow() + + @test_tracker_info(uuid="402cfaa8-297f-4865-9e27-6bab6adca756") + def test_reboot_wifi_and_bluetooth_on(self): + """Toggle WiFi and bluetooth ON then reboot """ + wutils.wifi_toggle_state(self.dut, True) + enable_bluetooth(self.dut.droid, self.dut.ed) + + self.dut.reboot() + time.sleep(DEFAULT_TIMEOUT) + + asserts.assert_true(self.dut.droid.bluetoothCheckState(), + "bluetooth state changed after reboot") + asserts.assert_true(self.dut.droid.wifiCheckState(), + "wifi state changed after reboot") + + disable_bluetooth(self.dut.droid) diff --git a/acts/tests/google/wifi/WifiStressTest.py b/acts/tests/google/wifi/WifiStressTest.py index d4d617fb82..84818e0017 100755 --- a/acts/tests/google/wifi/WifiStressTest.py +++ b/acts/tests/google/wifi/WifiStressTest.py @@ -15,6 +15,9 @@ # limitations under the License. import pprint +import queue +import re +import threading import time import acts.base_test @@ -74,6 +77,8 @@ class WifiStressTest(WifiBaseTest): self.iperf_server = self.iperf_servers[0] if hasattr(self, 'iperf_server'): self.iperf_server.start() + if(len(self.iperf_servers) > 1): + self.iperf_servers[1].start() def setup_test(self): self.dut.droid.wakeLockAcquireBright() @@ -94,13 +99,15 @@ class WifiStressTest(WifiBaseTest): wutils.reset_wifi(self.dut) if hasattr(self, 'iperf_server'): self.iperf_server.stop() + if(len(self.iperf_servers) > 1): + self.iperf_servers[1].stop() if "AccessPoint" in self.user_params: del self.user_params["reference_networks"] del self.user_params["open_network"] """Helper Functions""" - def scan_and_connect_by_ssid(self, network): + def scan_and_connect_by_ssid(self, ad, network): """Scan for network and connect using network information. Args: @@ -108,9 +115,8 @@ class WifiStressTest(WifiBaseTest): """ ssid = network[WifiEnums.SSID_KEY] - wutils.start_wifi_connection_scan_and_ensure_network_found(self.dut, - ssid) - wutils.wifi_connect(self.dut, network, num_of_tries=3) + wutils.start_wifi_connection_scan_and_ensure_network_found(ad, ssid) + wutils.wifi_connect(ad, network, num_of_tries=3) def scan_and_connect_by_id(self, network, net_id): """Scan for network and connect using network id. @@ -179,74 +185,162 @@ class WifiStressTest(WifiBaseTest): configured_networks = ad.droid.wifiGetConfiguredNetworks() self.log.debug("Configured networks: %s", configured_networks) - def connect_and_verify_connected_bssid(self, expected_bssid): + def connect_and_verify_connected_ssid(self, expected_con, is_pno=False): """Start a scan to get the DUT connected to an AP and verify the DUT - is connected to the correct BSSID. - - Args: - expected_bssid: Network bssid to which connection. - - Returns: - True if connection to given network happen, else return False. - """ - #force start a single scan so we don't have to wait for the - #WCM scheduled scan. - wutils.start_wifi_connection_scan(self.dut) - #wait for connection - time.sleep(20) - #verify connection - actual_network = self.dut.droid.wifiGetConnectionInfo() - self.log.info("Actual network: %s", actual_network) - try: - asserts.assert_equal(expected_bssid, - actual_network[WifiEnums.BSSID_KEY]) - except: - msg = "Device did not connect to any network." - raise signals.TestFailure(msg) - - def set_attns(self, attn_val_name): - """Sets attenuation values on attenuators used in this test. + is connected to the correct SSID. Args: - attn_val_name: Name of the attenuation value pair to use. - """ - self.log.info("Set attenuation values to %s", self.attn_vals[attn_val_name]) - try: - self.attenuators[0].set_atten(self.attn_vals[attn_val_name][0]) - self.attenuators[1].set_atten(self.attn_vals[attn_val_name][1]) - self.attenuators[2].set_atten(95) - self.attenuators[3].set_atten(95) - except: - self.log.error("Failed to set attenuation values %s.", attn_val_name) - raise - - def trigger_pno_and_assert_connect(self, attn_val_name, expected_con): - """Sets attenuators to disconnect current connection to trigger PNO. - Validate that the DUT connected to the new SSID as expected after PNO. - - Args: - attn_val_name: Name of the attenuation value pair to use. expected_con: The expected info of the network to we expect the DUT to roam to. """ connection_info = self.dut.droid.wifiGetConnectionInfo() - self.log.info("Triggering PNO connect from %s to %s", + self.log.info("Triggering network selection from %s to %s", connection_info[WifiEnums.SSID_KEY], expected_con[WifiEnums.SSID_KEY]) - self.set_attns(attn_val_name) - self.log.info("Wait %ss for PNO to trigger.", self.pno_interval) - time.sleep(self.pno_interval) + self.attenuators[0].set_atten(0) + if is_pno: + self.log.info("Wait %ss for PNO to trigger.", self.pno_interval) + time.sleep(self.pno_interval) + else: + # force start a single scan so we don't have to wait for the scheduled scan. + wutils.start_wifi_connection_scan(self.dut) + self.log.info("Wait 20s for network selection.") + time.sleep(20) try: - self.log.info("Connected to %s network after PNO interval" + self.log.info("Connected to %s network after network selection" % self.dut.droid.wifiGetConnectionInfo()) expected_ssid = expected_con[WifiEnums.SSID_KEY] verify_con = {WifiEnums.SSID_KEY: expected_ssid} wutils.verify_wifi_connection_info(self.dut, verify_con) - self.log.info("Connected to %s successfully after PNO", + self.log.info("Connected to %s successfully after network selection", expected_ssid) finally: pass + def run_long_traffic(self, sec, args, q): + try: + # Start IPerf traffic + self.log.info("Running iperf client {}".format(args)) + result, data = self.dut.run_iperf_client(self.iperf_server_address, + args, timeout=sec+1) + if not result: + self.log.debug("Error occurred in iPerf traffic.") + self.run_ping(sec) + q.put(True) + except: + q.put(False) + + def _test_stress_connect_long_traffic(self, network): + """Connect to a network and run iperf traffic for stress_hours. + + Args: + network: wifi network to connect to. + """ + self.scan_and_connect_by_ssid(self.dut, network) + self.scan_and_connect_by_ssid(self.dut_client, network) + + q = queue.Queue() + sec = self.stress_hours * 60 * 60 + start_time = time.time() + + dl_args = "-p {} -t {} -R".format(self.iperf_server.port, sec) + dl = threading.Thread(target=self.run_long_traffic, args=(sec, dl_args, q)) + dl.start() + if(len(self.iperf_servers) > 1): + ul_args = "-p {} -t {}".format(self.iperf_servers[1].port, sec) + ul = threading.Thread(target=self.run_long_traffic, args=(sec, ul_args, q)) + ul.start() + + dl.join() + if(len(self.iperf_servers) > 1): + ul.join() + + total_time = time.time() - start_time + self.log.debug("WiFi state = %d" %self.dut.droid.wifiCheckState()) + while(q.qsize() > 0): + if not q.get(): + raise signals.TestFailure("Network long-connect failed.", + extras={"Total Hours":"%d" %self.stress_hours, + "Seconds Run":"%d" %total_time}) + raise signals.TestPass(details="", extras={"Total Hours":"%d" % + self.stress_hours, "Seconds Run":"%d" %total_time}) + + def _test_stress_connect_AP_on_off(self, network): + """Verify that DUT connects back to the wifi network when the AP + is up again. + + Args: + network: wifi network to connect to. + """ + chan = 0 if network == self.wpa_2g else 1 + self.attenuators[chan].set_atten(0) + self.scan_and_connect_by_ssid(self.dut, network) + for _ in range(50): + self.attenuators[chan].set_atten(95) + wutils.wait_for_disconnect(self.dut) + self.attenuators[chan].set_atten(0) + wutils.start_wifi_connection_scan_and_check_for_network( + self.dut, network[WifiEnums.SSID_KEY]) + wutils.wait_for_connect(self.dut, network[WifiEnums.SSID_KEY]) + internet = wutils.validate_connection(self.dut) + if not internet: + raise signals.TestFailure("Failed to connect to internet on %s" + % network) + wutils.wifi_forget_network(self.dut, WifiEnums.SSID_KEY) + + def _test_stress_connect_long_traffic_weak_signal(self, network): + """Connect to a network with weak signal stength and run iperf traffic + for stress_hours. + + Args: + network: wifi network to connect to + """ + chan = 0 if network == self.wpa_2g else 1 + self.scan_and_connect_by_ssid(self.dut, network) + self.attenuators[chan].set_atten(70) + conn_info = self.dut.droid.wifiGetConnectionInfo() + self.log.info("Wifi signal strength is %s" % conn_info['rssi']) + sec = self.stress_hours * 60 * 60 + args = "-p {} -t {} -R".format(self.iperf_server.port, sec) + self.log.info("Running iperf client {}".format(args)) + result, data = self.dut.run_iperf_client(self.iperf_server_address, + args, timeout=sec+1) + if not result: + self.log.debug("Error occurred in iPerf traffic.") + self.run_ping(sec) + else: + self.log.info("Throughput is %s" % + re.search('MBytes(.*)Mbits', data[-3]).group(1)) + + def _test_stress_youtube(self, network): + """Connect to wifi network and run youtube videos. Verify no + WiFi disconnects/data interruption. + + Args: + network: wifi network to connect to + """ + # List of Youtube 4K videos. + videos = ["https://www.youtube.com/watch?v=TKmGU77INaM", + "https://www.youtube.com/watch?v=WNCl-69POro", + "https://www.youtube.com/watch?v=dVkK36KOcqs", + "https://www.youtube.com/watch?v=0wCC3aLXdOw", + "https://www.youtube.com/watch?v=rN6nlNC9WQA", + "https://www.youtube.com/watch?v=U--7hxRNPvk"] + try: + self.scan_and_connect_by_ssid(self.dut, network) + start_time = time.time() + for video in videos: + self.start_youtube_video(url=video, secs=10*60) + except: + total_time = time.time() - start_time + raise signals.TestFailure("The youtube stress test has failed." + "WiFi State = %d" %self.dut.droid.wifiCheckState(), + extras={"Total Hours":"1", "Seconds Run":"%d" %total_time}) + total_time = time.time() - start_time + self.log.debug("WiFi state = %d" %self.dut.droid.wifiCheckState()) + raise signals.TestPass(details="", extras={"Total Hours":"1", + "Seconds Run":"%d" %total_time}) + """Tests""" @test_tracker_info(uuid="cd0016c6-58cf-4361-b551-821c0b8d2554") @@ -324,6 +418,20 @@ class WifiStressTest(WifiBaseTest): raise signals.TestPass(details="", extras={"Iterations":"%d" % self.stress_count, "Pass":"%d" %(count+1)}) + @test_tracker_info(uuid="6b928a39-6530-4381-9665-24c893fb3517") + def test_stress_connect_long_traffic_2g(self): + """Test connect to network with 2G band and hold connection + for few hours. + + Steps: + 1. Scan and connect to a network. + 2. Run IPerf to download data for few hours. + 3. Run IPerf to upload data for few hours. + 4. Verify no WiFi disconnects/data interruption. + + """ + self._test_stress_connect_long_traffic(self.wpa_2g) + @test_tracker_info(uuid="e9827dff-0755-43ec-8b50-1f9756958460") def test_stress_connect_long_traffic_5g(self): """Test to connect to network and hold connection for few hours. @@ -335,40 +443,20 @@ class WifiStressTest(WifiBaseTest): 4. Verify no WiFi disconnects/data interruption. """ - try: - self.scan_and_connect_by_ssid(self.wpa_5g) - # Start IPerf traffic from server to phone. - # Download data for 5 hours. - sec = self.stress_hours * 60 * 60 - args = "-p {} -t {} -R".format(self.iperf_server.port, sec) - self.log.info("Running iperf client {}".format(args)) - start_time = time.time() - result, data = self.dut.run_iperf_client(self.iperf_server_address, - args, timeout=sec+1) - if not result: - self.log.debug("Error occurred in iPerf traffic.") - start_time = time.time() - self.run_ping(sec) - # Start IPerf traffic from phone to server. - # Upload data for 5 hours. - args = "-p {} -t {}".format(self.iperf_server.port, sec) - self.log.info("Running iperf client {}".format(args)) - result, data = self.dut.run_iperf_client(self.iperf_server_address, - args, timeout=sec+1) - if not result: - self.log.debug("Error occurred in iPerf traffic.") - self.run_ping(sec) - except: - total_time = time.time() - start_time - raise signals.TestFailure("Network long-connect failed." - "WiFi State = %d" %self.dut.droid.wifiCheckState(), - extras={"Total Hours":"%d" %self.stress_hours, - "Seconds Run":"%d" %total_time}) - total_time = time.time() - start_time - self.log.debug("WiFi state = %d" %self.dut.droid.wifiCheckState()) - raise signals.TestPass(details="", extras={"Total Hours":"%d" % - self.stress_hours, "Seconds Run":"%d" %total_time}) + self._test_stress_connect_long_traffic(self.wpa_5g) + + @test_tracker_info(uuid="f4751895-0529-4f0f-8eec-c64bcb67c59e") + def test_stress_youtube_2g(self): + """Test to connect to 2G network and play various youtube videos. + + Steps: + 1. Scan and connect to a network. + 2. Loop through and play a list of youtube videos. + 3. Verify no WiFi disconnects/data interruption. + """ + self._test_stress_youtube(self.wpa_2g) + @test_tracker_info(uuid="591d257d-9477-4a89-a220-5715c93a76a7") def test_stress_youtube_5g(self): """Test to connect to network and play various youtube videos. @@ -378,27 +466,59 @@ class WifiStressTest(WifiBaseTest): 3. Verify no WiFi disconnects/data interruption. """ - # List of Youtube 4K videos. - videos = ["https://www.youtube.com/watch?v=TKmGU77INaM", - "https://www.youtube.com/watch?v=WNCl-69POro", - "https://www.youtube.com/watch?v=dVkK36KOcqs", - "https://www.youtube.com/watch?v=0wCC3aLXdOw", - "https://www.youtube.com/watch?v=rN6nlNC9WQA", - "https://www.youtube.com/watch?v=U--7hxRNPvk"] - try: - self.scan_and_connect_by_ssid(self.wpa_5g) - start_time = time.time() - for video in videos: - self.start_youtube_video(url=video, secs=10*60) - except: - total_time = time.time() - start_time - raise signals.TestFailure("The youtube stress test has failed." - "WiFi State = %d" %self.dut.droid.wifiCheckState(), - extras={"Total Hours":"1", "Seconds Run":"%d" %total_time}) - total_time = time.time() - start_time - self.log.debug("WiFi state = %d" %self.dut.droid.wifiCheckState()) - raise signals.TestPass(details="", extras={"Total Hours":"1", - "Seconds Run":"%d" %total_time}) + self._test_stress_youtube(self.wpa_5g) + + @test_tracker_info(uuid="7106efbe-f4cc-4b16-9a25-b6f2573e516b") + def test_stress_connect_AP_2g_on_off(self): + """Test to verify that verify that DUT connects back to the + to the wifi network with 2G band after AP is up. + + Steps: + 1. Scan and connect to a network. + 2. Attenuate the signal to max. + 3. Attenuate the signal to 0. + 4. Verify that DUT connects back to the wifi network. + """ + self._test_stress_connect_AP_on_off(self.wpa_2g) + + @test_tracker_info(uuid="aef24543-edea-4c9a-a271-1e71582405d2") + def test_stress_connect_AP_5g_on_off(self): + """Test to verify that verify that DUT connects back to the + to the wifi network with 2G band after AP is up. + + Steps: + 1. Scan and connect to a network. + 2. Attenuate the signal to max. + 3. Attenuate the signal to 0. + 4. Verify that DUT connects back to the wifi network. + """ + self._test_stress_connect_AP_on_off(self.wpa_5g) + + @test_tracker_info(uuid="0fffddcf-c8d6-477f-ba77-e4f5731bca1f") + def test_stress_connect_long_traffic_2g_weak_signal(self): + """Test connect to network with 2G band with weak signal strength + and hold connection for few hours + + Steps: + 1. Scan and connect to a network. + 2. Attenuate the signal to 70dB. + 3. Run IPerf to download data for few hours. + 4. Verify no WiFi disconnects/data interruption. + """ + self._test_stress_connect_long_traffic_weak_signal(self.wpa_2g) + + @test_tracker_info(uuid="49eab802-5596-4674-8b7c-557629fe2734") + def test_stress_connect_long_traffic_5g_weak_signal(self): + """Test connect to network with 5G band with weak signal strength + and hold connection for few hours + + Steps: + 1. Scan and connect to a network. + 2. Attenuate the signal to 70dB. + 3. Run IPerf to download data for few hours. + 4. Verify no WiFi disconnects/data interruption. + """ + self._test_stress_connect_long_traffic_weak_signal(self.wpa_5g) @test_tracker_info(uuid="d367c83e-5b00-4028-9ed8-f7b875997d13") def test_stress_wifi_failover(self): @@ -494,7 +614,7 @@ class WifiStressTest(WifiBaseTest): AP1_network = self.reference_networks[0]["5g"] AP2_network = self.reference_networks[1]["5g"] wutils.set_attns(self.attenuators, "AP1_on_AP2_off") - self.scan_and_connect_by_ssid(AP1_network) + self.scan_and_connect_by_ssid(self.dut, AP1_network) # Reduce iteration to half because each iteration does two roams. for count in range(int(self.stress_count/2)): self.log.info("Roaming iteration %d, from %s to %s", count, @@ -524,18 +644,15 @@ class WifiStressTest(WifiBaseTest): """ for attenuator in self.attenuators: attenuator.set_atten(95) - # add a saved network to DUT networks = [self.reference_networks[0]['2g']] self.add_networks(self.dut, networks) - for count in range(self.stress_count): - # move the DUT in range - self.attenuators[0].set_atten(0) - # verify - self.connect_and_verify_connected_bssid(self.reference_networks[0]['2g']['bssid']) + self.connect_and_verify_connected_ssid(self.reference_networks[0]['2g']) # move the DUT out of range self.attenuators[0].set_atten(95) + time.sleep(10) + wutils.set_attns(self.attenuators, "default") raise signals.TestPass(details="", extras={"Iterations":"%d" % self.stress_count, "Pass":"%d" %(count+1)}) @@ -545,15 +662,22 @@ class WifiStressTest(WifiBaseTest): Steps: 1. Save 2Ghz valid network configuration in the device. - 2. Attenuate 5Ghz network and wait for a few seconds to trigger PNO. - 3. Check the device connected to 2Ghz network automatically. - 4. Repeat step 2-3 + 2. Screen off DUT + 3. Attenuate 5Ghz network and wait for a few seconds to trigger PNO. + 4. Check the device connected to 2Ghz network automatically. + 5. Repeat step 3-4 """ + for attenuator in self.attenuators: + attenuator.set_atten(95) + # add a saved network to DUT networks = [self.reference_networks[0]['2g']] self.add_networks(self.dut, networks) + self.dut.droid.wakeLockRelease() + self.dut.droid.goToSleepNow() for count in range(self.stress_count): - self.trigger_pno_and_assert_connect("a_on_b_off", self.reference_networks[0]['2g']) - self.set_attns("b_on_a_off") + self.connect_and_verify_connected_ssid(self.reference_networks[0]['2g'], is_pno=True) + # move the DUT out of range + self.attenuators[0].set_atten(95) time.sleep(10) wutils.set_attns(self.attenuators, "default") raise signals.TestPass(details="", extras={"Iterations":"%d" % diff --git a/acts/tests/google/wifi/aware/functional/AttachTest.py b/acts/tests/google/wifi/aware/functional/AttachTest.py index 37f07e0834..167c29f809 100644 --- a/acts/tests/google/wifi/aware/functional/AttachTest.py +++ b/acts/tests/google/wifi/aware/functional/AttachTest.py @@ -26,142 +26,139 @@ from acts.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest class AttachTest(AwareBaseTest): - def __init__(self, controllers): - AwareBaseTest.__init__(self, controllers) + def __init__(self, controllers): + AwareBaseTest.__init__(self, controllers) - @test_tracker_info(uuid="cdafd1e0-bcf5-4fe8-ae32-f55483db9925") - def test_attach(self): - """Functional test case / Attach test cases / attach + @test_tracker_info(uuid="cdafd1e0-bcf5-4fe8-ae32-f55483db9925") + def test_attach(self): + """Functional test case / Attach test cases / attach Validates that attaching to the Wi-Fi Aware service works (receive the expected callback). """ - dut = self.android_devices[0] - dut.droid.wifiAwareAttach(False) - autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) - autils.fail_on_event(dut, aconsts.EVENT_CB_ON_IDENTITY_CHANGED) + dut = self.android_devices[0] + dut.droid.wifiAwareAttach(False) + autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) + autils.fail_on_event(dut, aconsts.EVENT_CB_ON_IDENTITY_CHANGED) - @test_tracker_info(uuid="82f2a8bc-a62b-49c2-ac8a-fe8460010ba2") - def test_attach_with_identity(self): - """Functional test case / Attach test cases / attach with identity callback + @test_tracker_info(uuid="82f2a8bc-a62b-49c2-ac8a-fe8460010ba2") + def test_attach_with_identity(self): + """Functional test case / Attach test cases / attach with identity callback Validates that attaching to the Wi-Fi Aware service works (receive the expected callbacks). """ - dut = self.android_devices[0] - dut.droid.wifiAwareAttach(True) - autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) - autils.wait_for_event(dut, aconsts.EVENT_CB_ON_IDENTITY_CHANGED) + dut = self.android_devices[0] + dut.droid.wifiAwareAttach(True) + autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) + autils.wait_for_event(dut, aconsts.EVENT_CB_ON_IDENTITY_CHANGED) - @test_tracker_info(uuid="d2714d14-f330-47d4-b8e9-ee4d5e5b7ea0") - def test_attach_multiple_sessions(self): - """Functional test case / Attach test cases / multiple attach sessions + @test_tracker_info(uuid="d2714d14-f330-47d4-b8e9-ee4d5e5b7ea0") + def test_attach_multiple_sessions(self): + """Functional test case / Attach test cases / multiple attach sessions Validates that when creating multiple attach sessions each can be configured independently as to whether or not to receive an identity callback. """ - dut = self.android_devices[0] - - # Create 3 attach sessions: 2 without identity callback, 1 with - id1 = dut.droid.wifiAwareAttach(False, None, True) - time.sleep(10) # to make sure all calls and callbacks are done - id2 = dut.droid.wifiAwareAttach(True, None, True) - time.sleep(10) # to make sure all calls and callbacks are done - id3 = dut.droid.wifiAwareAttach(False, None, True) - dut.log.info('id1=%d, id2=%d, id3=%d', id1, id2, id3) - - # Attach session 1: wait for attach, should not get identity - autils.wait_for_event(dut, - autils.decorate_event(aconsts.EVENT_CB_ON_ATTACHED, - id1)) - autils.fail_on_event(dut, - autils.decorate_event( - aconsts.EVENT_CB_ON_IDENTITY_CHANGED, id1)) - - # Attach session 2: wait for attach and for identity callback - autils.wait_for_event(dut, - autils.decorate_event(aconsts.EVENT_CB_ON_ATTACHED, - id2)) - autils.wait_for_event(dut, - autils.decorate_event( - aconsts.EVENT_CB_ON_IDENTITY_CHANGED, id2)) - - # Attach session 3: wait for attach, should not get identity - autils.wait_for_event(dut, - autils.decorate_event(aconsts.EVENT_CB_ON_ATTACHED, - id3)) - autils.fail_on_event(dut, - autils.decorate_event( - aconsts.EVENT_CB_ON_IDENTITY_CHANGED, id3)) - - @test_tracker_info(uuid="b8ea4d02-ae23-42a7-a85e-def52932c858") - def test_attach_with_no_wifi(self): - """Function test case / Attach test cases / attempt to attach with wifi off + dut = self.android_devices[0] + + # Create 3 attach sessions: 2 without identity callback, 1 with + id1 = dut.droid.wifiAwareAttach(False, None, True) + time.sleep(10) # to make sure all calls and callbacks are done + id2 = dut.droid.wifiAwareAttach(True, None, True) + time.sleep(10) # to make sure all calls and callbacks are done + id3 = dut.droid.wifiAwareAttach(False, None, True) + dut.log.info('id1=%d, id2=%d, id3=%d', id1, id2, id3) + + # Attach session 1: wait for attach, should not get identity + autils.wait_for_event( + dut, autils.decorate_event(aconsts.EVENT_CB_ON_ATTACHED, id1)) + autils.fail_on_event( + dut, + autils.decorate_event(aconsts.EVENT_CB_ON_IDENTITY_CHANGED, id1)) + + # Attach session 2: wait for attach and for identity callback + autils.wait_for_event( + dut, autils.decorate_event(aconsts.EVENT_CB_ON_ATTACHED, id2)) + autils.wait_for_event( + dut, + autils.decorate_event(aconsts.EVENT_CB_ON_IDENTITY_CHANGED, id2)) + + # Attach session 3: wait for attach, should not get identity + autils.wait_for_event( + dut, autils.decorate_event(aconsts.EVENT_CB_ON_ATTACHED, id3)) + autils.fail_on_event( + dut, + autils.decorate_event(aconsts.EVENT_CB_ON_IDENTITY_CHANGED, id3)) + + @test_tracker_info(uuid="b8ea4d02-ae23-42a7-a85e-def52932c858") + def test_attach_with_no_wifi(self): + """Function test case / Attach test cases / attempt to attach with wifi off Validates that if trying to attach with Wi-Fi disabled will receive the expected failure callback. As a side-effect also validates that the broadcast for Aware unavailable is received. """ - dut = self.android_devices[0] - wutils.wifi_toggle_state(dut, False) - autils.wait_for_event(dut, aconsts.BROADCAST_WIFI_AWARE_NOT_AVAILABLE) - dut.droid.wifiAwareAttach() - autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACH_FAILED) + dut = self.android_devices[0] + wutils.wifi_toggle_state(dut, False) + autils.wait_for_event(dut, aconsts.BROADCAST_WIFI_AWARE_NOT_AVAILABLE) + dut.droid.wifiAwareAttach() + autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACH_FAILED) - @test_tracker_info(uuid="7dcc4530-c936-4447-9d22-a7c5b315e2ce") - def test_attach_with_doze(self): - """Function test case / Attach test cases / attempt to attach with doze on + @test_tracker_info(uuid="7dcc4530-c936-4447-9d22-a7c5b315e2ce") + def test_attach_with_doze(self): + """Function test case / Attach test cases / attempt to attach with doze on Validates that if trying to attach with device in doze mode will receive the expected failure callback. As a side-effect also validates that the broadcast for Aware unavailable is received. """ - dut = self.android_devices[0] - asserts.assert_true(utils.enable_doze(dut), "Can't enable doze") - autils.wait_for_event(dut, aconsts.BROADCAST_WIFI_AWARE_NOT_AVAILABLE) - dut.droid.wifiAwareAttach() - autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACH_FAILED) - asserts.assert_true(utils.disable_doze(dut), "Can't disable doze") - autils.wait_for_event(dut, aconsts.BROADCAST_WIFI_AWARE_AVAILABLE) - - @test_tracker_info(uuid="2574fd01-8974-4dd0-aeb8-a7194461140e") - def test_attach_with_location_off(self): - """Function test case / Attach test cases / attempt to attach with location + dut = self.android_devices[0] + asserts.assert_true(utils.enable_doze(dut), "Can't enable doze") + autils.wait_for_event(dut, aconsts.BROADCAST_WIFI_AWARE_NOT_AVAILABLE) + dut.droid.wifiAwareAttach() + autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACH_FAILED) + asserts.assert_true(utils.disable_doze(dut), "Can't disable doze") + autils.wait_for_event(dut, aconsts.BROADCAST_WIFI_AWARE_AVAILABLE) + + @test_tracker_info(uuid="2574fd01-8974-4dd0-aeb8-a7194461140e") + def test_attach_with_location_off(self): + """Function test case / Attach test cases / attempt to attach with location mode off. Validates that if trying to attach with device location mode off will receive the expected failure callback. As a side-effect also validates that the broadcast for Aware unavailable is received. """ - dut = self.android_devices[0] - utils.set_location_service(dut, False) - autils.wait_for_event(dut, aconsts.BROADCAST_WIFI_AWARE_NOT_AVAILABLE) - dut.droid.wifiAwareAttach() - autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACH_FAILED) - utils.set_location_service(dut, True) - autils.wait_for_event(dut, aconsts.BROADCAST_WIFI_AWARE_AVAILABLE) - - @test_tracker_info(uuid="7ffde8e7-a010-4b77-97f5-959f263b5249") - def test_attach_apm_toggle_attach_again(self): - """Validates that enabling Airplane mode while Aware is on resets it + dut = self.android_devices[0] + utils.set_location_service(dut, False) + autils.wait_for_event(dut, aconsts.BROADCAST_WIFI_AWARE_NOT_AVAILABLE) + dut.droid.wifiAwareAttach() + autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACH_FAILED) + utils.set_location_service(dut, True) + autils.wait_for_event(dut, aconsts.BROADCAST_WIFI_AWARE_AVAILABLE) + + @test_tracker_info(uuid="7ffde8e7-a010-4b77-97f5-959f263b5249") + def test_attach_apm_toggle_attach_again(self): + """Validates that enabling Airplane mode while Aware is on resets it correctly, and allows it to be re-enabled when Airplane mode is then disabled.""" - dut = self.android_devices[0] + dut = self.android_devices[0] - # enable Aware (attach) - dut.droid.wifiAwareAttach() - autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) + # enable Aware (attach) + dut.droid.wifiAwareAttach() + autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) - # enable airplane mode - utils.force_airplane_mode(dut, True) - autils.wait_for_event(dut, aconsts.BROADCAST_WIFI_AWARE_NOT_AVAILABLE) + # enable airplane mode + utils.force_airplane_mode(dut, True) + autils.wait_for_event(dut, aconsts.BROADCAST_WIFI_AWARE_NOT_AVAILABLE) - # wait a few seconds and disable airplane mode - time.sleep(10) - utils.force_airplane_mode(dut, False) - autils.wait_for_event(dut, aconsts.BROADCAST_WIFI_AWARE_AVAILABLE) + # wait a few seconds and disable airplane mode + time.sleep(10) + utils.force_airplane_mode(dut, False) + autils.wait_for_event(dut, aconsts.BROADCAST_WIFI_AWARE_AVAILABLE) - # try enabling Aware again (attach) - dut.droid.wifiAwareAttach() - autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) + # try enabling Aware again (attach) + dut.droid.wifiAwareAttach() + autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) diff --git a/acts/tests/google/wifi/aware/functional/CapabilitiesTest.py b/acts/tests/google/wifi/aware/functional/CapabilitiesTest.py index b9b6108e84..ea5b8672fb 100644 --- a/acts/tests/google/wifi/aware/functional/CapabilitiesTest.py +++ b/acts/tests/google/wifi/aware/functional/CapabilitiesTest.py @@ -24,16 +24,16 @@ from acts.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest class CapabilitiesTest(AwareBaseTest): - """Set of tests for Wi-Fi Aware Capabilities - verifying that the provided + """Set of tests for Wi-Fi Aware Capabilities - verifying that the provided capabilities are real (i.e. available).""" - SERVICE_NAME = "GoogleTestXYZ" + SERVICE_NAME = "GoogleTestXYZ" - def __init__(self, controllers): - AwareBaseTest.__init__(self, controllers) + def __init__(self, controllers): + AwareBaseTest.__init__(self, controllers) - def create_config(self, dtype, service_name): - """Create a discovery configuration based on input parameters. + def create_config(self, dtype, service_name): + """Create a discovery configuration based on input parameters. Args: dtype: Publish or Subscribe discovery type @@ -42,14 +42,14 @@ class CapabilitiesTest(AwareBaseTest): Returns: Discovery configuration object. """ - config = {} - config[aconsts.DISCOVERY_KEY_DISCOVERY_TYPE] = dtype - config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = service_name - return config + config = {} + config[aconsts.DISCOVERY_KEY_DISCOVERY_TYPE] = dtype + config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = service_name + return config - def start_discovery_session(self, dut, session_id, is_publish, dtype, - service_name, expect_success): - """Start a discovery session + def start_discovery_session(self, dut, session_id, is_publish, dtype, + service_name, expect_success): + """Start a discovery session Args: dut: Device under test @@ -62,85 +62,86 @@ class CapabilitiesTest(AwareBaseTest): Returns: Discovery session ID. """ - config = {} - config[aconsts.DISCOVERY_KEY_DISCOVERY_TYPE] = dtype - config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = service_name - - if is_publish: - disc_id = dut.droid.wifiAwarePublish(session_id, config) - event_name = aconsts.SESSION_CB_ON_PUBLISH_STARTED - else: - disc_id = dut.droid.wifiAwareSubscribe(session_id, config) - event_name = aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED - - if expect_success: - autils.wait_for_event(dut, event_name) - else: - autils.wait_for_event(dut, aconsts.SESSION_CB_ON_SESSION_CONFIG_FAILED) - - return disc_id - - ############################### - - @test_tracker_info(uuid="45da8a41-6c02-4434-9eb9-aa0a36ff9f65") - def test_max_discovery_sessions(self): - """Validate that the device can create as many discovery sessions as are + config = {} + config[aconsts.DISCOVERY_KEY_DISCOVERY_TYPE] = dtype + config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = service_name + + if is_publish: + disc_id = dut.droid.wifiAwarePublish(session_id, config) + event_name = aconsts.SESSION_CB_ON_PUBLISH_STARTED + else: + disc_id = dut.droid.wifiAwareSubscribe(session_id, config) + event_name = aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED + + if expect_success: + autils.wait_for_event(dut, event_name) + else: + autils.wait_for_event(dut, + aconsts.SESSION_CB_ON_SESSION_CONFIG_FAILED) + + return disc_id + + ############################### + + @test_tracker_info(uuid="45da8a41-6c02-4434-9eb9-aa0a36ff9f65") + def test_max_discovery_sessions(self): + """Validate that the device can create as many discovery sessions as are indicated in the device capabilities """ - dut = self.android_devices[0] - - # attach - session_id = dut.droid.wifiAwareAttach(True) - autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) - - service_name_template = 'GoogleTestService-%s-%d' - - # start the max number of publish sessions - for i in range(dut.aware_capabilities[aconsts.CAP_MAX_PUBLISHES]): - # create publish discovery session of both types - pub_disc_id = self.start_discovery_session( - dut, session_id, True, aconsts.PUBLISH_TYPE_UNSOLICITED - if i % 2 == 0 else aconsts.PUBLISH_TYPE_SOLICITED, - service_name_template % ('pub', i), True) - - # start the max number of subscribe sessions - for i in range(dut.aware_capabilities[aconsts.CAP_MAX_SUBSCRIBES]): - # create publish discovery session of both types - sub_disc_id = self.start_discovery_session( - dut, session_id, False, aconsts.SUBSCRIBE_TYPE_PASSIVE - if i % 2 == 0 else aconsts.SUBSCRIBE_TYPE_ACTIVE, - service_name_template % ('sub', i), True) - - # start another publish & subscribe and expect failure - self.start_discovery_session(dut, session_id, True, - aconsts.PUBLISH_TYPE_UNSOLICITED, - service_name_template % ('pub', 900), False) - self.start_discovery_session(dut, session_id, False, - aconsts.SUBSCRIBE_TYPE_ACTIVE, - service_name_template % ('pub', 901), False) - - # delete one of the publishes and try again (see if can create subscribe - # instead - should not) - dut.droid.wifiAwareDestroyDiscoverySession(pub_disc_id) - self.start_discovery_session(dut, session_id, False, - aconsts.SUBSCRIBE_TYPE_ACTIVE, - service_name_template % ('pub', 902), False) - self.start_discovery_session(dut, session_id, True, - aconsts.PUBLISH_TYPE_UNSOLICITED, - service_name_template % ('pub', 903), True) - - # delete one of the subscribes and try again (see if can create publish - # instead - should not) - dut.droid.wifiAwareDestroyDiscoverySession(sub_disc_id) - self.start_discovery_session(dut, session_id, True, - aconsts.PUBLISH_TYPE_UNSOLICITED, - service_name_template % ('pub', 904), False) - self.start_discovery_session(dut, session_id, False, - aconsts.SUBSCRIBE_TYPE_ACTIVE, - service_name_template % ('pub', 905), True) - - def test_max_ndp(self): - """Validate that the device can create as many NDPs as are specified + dut = self.android_devices[0] + + # attach + session_id = dut.droid.wifiAwareAttach(True) + autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) + + service_name_template = 'GoogleTestService-%s-%d' + + # start the max number of publish sessions + for i in range(dut.aware_capabilities[aconsts.CAP_MAX_PUBLISHES]): + # create publish discovery session of both types + pub_disc_id = self.start_discovery_session( + dut, session_id, True, aconsts.PUBLISH_TYPE_UNSOLICITED + if i % 2 == 0 else aconsts.PUBLISH_TYPE_SOLICITED, + service_name_template % ('pub', i), True) + + # start the max number of subscribe sessions + for i in range(dut.aware_capabilities[aconsts.CAP_MAX_SUBSCRIBES]): + # create publish discovery session of both types + sub_disc_id = self.start_discovery_session( + dut, session_id, False, aconsts.SUBSCRIBE_TYPE_PASSIVE + if i % 2 == 0 else aconsts.SUBSCRIBE_TYPE_ACTIVE, + service_name_template % ('sub', i), True) + + # start another publish & subscribe and expect failure + self.start_discovery_session( + dut, session_id, True, aconsts.PUBLISH_TYPE_UNSOLICITED, + service_name_template % ('pub', 900), False) + self.start_discovery_session( + dut, session_id, False, aconsts.SUBSCRIBE_TYPE_ACTIVE, + service_name_template % ('pub', 901), False) + + # delete one of the publishes and try again (see if can create subscribe + # instead - should not) + dut.droid.wifiAwareDestroyDiscoverySession(pub_disc_id) + self.start_discovery_session( + dut, session_id, False, aconsts.SUBSCRIBE_TYPE_ACTIVE, + service_name_template % ('pub', 902), False) + self.start_discovery_session( + dut, session_id, True, aconsts.PUBLISH_TYPE_UNSOLICITED, + service_name_template % ('pub', 903), True) + + # delete one of the subscribes and try again (see if can create publish + # instead - should not) + dut.droid.wifiAwareDestroyDiscoverySession(sub_disc_id) + self.start_discovery_session( + dut, session_id, True, aconsts.PUBLISH_TYPE_UNSOLICITED, + service_name_template % ('pub', 904), False) + self.start_discovery_session( + dut, session_id, False, aconsts.SUBSCRIBE_TYPE_ACTIVE, + service_name_template % ('pub', 905), True) + + def test_max_ndp(self): + """Validate that the device can create as many NDPs as are specified by its capabilities. Mechanics: @@ -151,113 +152,127 @@ class CapabilitiesTest(AwareBaseTest): Note: the test requires MAX_NDP + 2 devices to be validated. If these are not available the test will fail. """ - dut = self.android_devices[0] - - # get max NDP: using first available device (assumes all devices are the - # same) - max_ndp = dut.aware_capabilities[aconsts.CAP_MAX_NDP_SESSIONS] - - # get number of attached devices: needs to be max_ndp+2 to allow for max_ndp - # NDPs + an additional one expected to fail. - # However, will run the test with max_ndp+1 devices to verify that at least - # that many NDPs can be created. Will still fail at the end to indicate that - # full test was not run. - num_peer_devices = min(len(self.android_devices) - 1, max_ndp + 1) - asserts.assert_true( - num_peer_devices >= max_ndp, - 'A minimum of %d devices is needed to run the test, have %d' % - (max_ndp + 1, len(self.android_devices))) - - # attach - session_id = dut.droid.wifiAwareAttach() - autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) - - # start publisher - p_disc_id = self.start_discovery_session( - dut, - session_id, - is_publish=True, - dtype=aconsts.PUBLISH_TYPE_UNSOLICITED, - service_name=self.SERVICE_NAME, - expect_success=True) - - # loop over other DUTs - for i in range(num_peer_devices): - other_dut = self.android_devices[i + 1] - - # attach - other_session_id = other_dut.droid.wifiAwareAttach() - autils.wait_for_event(other_dut, aconsts.EVENT_CB_ON_ATTACHED) - - # start subscriber - s_disc_id = self.start_discovery_session( - other_dut, - other_session_id, - is_publish=False, - dtype=aconsts.SUBSCRIBE_TYPE_PASSIVE, - service_name=self.SERVICE_NAME, - expect_success=True) - - discovery_event = autils.wait_for_event( - other_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) - peer_id_on_sub = discovery_event['data'][aconsts.SESSION_CB_KEY_PEER_ID] - - # Subscriber: send message to peer (Publisher - so it knows our address) - other_dut.droid.wifiAwareSendMessage( - s_disc_id, peer_id_on_sub, - self.get_next_msg_id(), "ping", aconsts.MAX_TX_RETRIES) - autils.wait_for_event(other_dut, aconsts.SESSION_CB_ON_MESSAGE_SENT) - - # Publisher: wait for received message - pub_rx_msg_event = autils.wait_for_event( - dut, aconsts.SESSION_CB_ON_MESSAGE_RECEIVED) - peer_id_on_pub = pub_rx_msg_event['data'][aconsts.SESSION_CB_KEY_PEER_ID] - - # publisher (responder): request network - p_req_key = autils.request_network( - dut, - dut.droid.wifiAwareCreateNetworkSpecifier(p_disc_id, peer_id_on_pub)) - - # subscriber (initiator): request network - s_req_key = autils.request_network( - other_dut, - other_dut.droid.wifiAwareCreateNetworkSpecifier( - s_disc_id, peer_id_on_sub)) - - # wait for network (or not - on the last iteration) - if i != max_ndp: - p_net_event = autils.wait_for_event_with_keys( - dut, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, p_req_key)) - s_net_event = autils.wait_for_event_with_keys( - other_dut, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, s_req_key)) - - p_aware_if = p_net_event['data'][cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - s_aware_if = s_net_event['data'][cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - self.log.info('Interface names: p=%s, s=%s', p_aware_if, s_aware_if) - - p_ipv6 = dut.droid.connectivityGetLinkLocalIpv6Address( - p_aware_if).split('%')[0] - s_ipv6 = other_dut.droid.connectivityGetLinkLocalIpv6Address( - s_aware_if).split('%')[0] - self.log.info('Interface addresses (IPv6): p=%s, s=%s', p_ipv6, s_ipv6) - else: - autils.fail_on_event_with_keys( - dut, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, p_req_key)) - autils.fail_on_event_with_keys( - other_dut, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, s_req_key)) - - asserts.assert_true(num_peer_devices > max_ndp, - 'Needed %d devices to run the test, have %d' % - (max_ndp + 2, len(self.android_devices))) + dut = self.android_devices[0] + + # get max NDP: using first available device (assumes all devices are the + # same) + max_ndp = dut.aware_capabilities[aconsts.CAP_MAX_NDP_SESSIONS] + + # get number of attached devices: needs to be max_ndp+2 to allow for max_ndp + # NDPs + an additional one expected to fail. + # However, will run the test with max_ndp+1 devices to verify that at least + # that many NDPs can be created. Will still fail at the end to indicate that + # full test was not run. + num_peer_devices = min(len(self.android_devices) - 1, max_ndp + 1) + asserts.assert_true( + num_peer_devices >= max_ndp, + 'A minimum of %d devices is needed to run the test, have %d' % + (max_ndp + 1, len(self.android_devices))) + + # attach + session_id = dut.droid.wifiAwareAttach() + autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) + + # start publisher + p_disc_id = self.start_discovery_session( + dut, + session_id, + is_publish=True, + dtype=aconsts.PUBLISH_TYPE_UNSOLICITED, + service_name=self.SERVICE_NAME, + expect_success=True) + + # loop over other DUTs + for i in range(num_peer_devices): + other_dut = self.android_devices[i + 1] + + # attach + other_session_id = other_dut.droid.wifiAwareAttach() + autils.wait_for_event(other_dut, aconsts.EVENT_CB_ON_ATTACHED) + + # start subscriber + s_disc_id = self.start_discovery_session( + other_dut, + other_session_id, + is_publish=False, + dtype=aconsts.SUBSCRIBE_TYPE_PASSIVE, + service_name=self.SERVICE_NAME, + expect_success=True) + + discovery_event = autils.wait_for_event( + other_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) + peer_id_on_sub = discovery_event['data'][ + aconsts.SESSION_CB_KEY_PEER_ID] + + # Subscriber: send message to peer (Publisher - so it knows our address) + other_dut.droid.wifiAwareSendMessage(s_disc_id, peer_id_on_sub, + self.get_next_msg_id(), + "ping", + aconsts.MAX_TX_RETRIES) + autils.wait_for_event(other_dut, + aconsts.SESSION_CB_ON_MESSAGE_SENT) + + # Publisher: wait for received message + pub_rx_msg_event = autils.wait_for_event( + dut, aconsts.SESSION_CB_ON_MESSAGE_RECEIVED) + peer_id_on_pub = pub_rx_msg_event['data'][ + aconsts.SESSION_CB_KEY_PEER_ID] + + # publisher (responder): request network + p_req_key = autils.request_network( + dut, + dut.droid.wifiAwareCreateNetworkSpecifier( + p_disc_id, peer_id_on_pub)) + + # subscriber (initiator): request network + s_req_key = autils.request_network( + other_dut, + other_dut.droid.wifiAwareCreateNetworkSpecifier( + s_disc_id, peer_id_on_sub)) + + # wait for network (or not - on the last iteration) + if i != max_ndp: + p_net_event = autils.wait_for_event_with_keys( + dut, cconsts.EVENT_NETWORK_CALLBACK, + autils.EVENT_NDP_TIMEOUT, + (cconsts.NETWORK_CB_KEY_EVENT, + cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), + (cconsts.NETWORK_CB_KEY_ID, p_req_key)) + s_net_event = autils.wait_for_event_with_keys( + other_dut, cconsts.EVENT_NETWORK_CALLBACK, + autils.EVENT_NDP_TIMEOUT, + (cconsts.NETWORK_CB_KEY_EVENT, + cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), + (cconsts.NETWORK_CB_KEY_ID, s_req_key)) + + p_aware_if = p_net_event['data'][ + cconsts.NETWORK_CB_KEY_INTERFACE_NAME] + s_aware_if = s_net_event['data'][ + cconsts.NETWORK_CB_KEY_INTERFACE_NAME] + self.log.info('Interface names: p=%s, s=%s', p_aware_if, + s_aware_if) + + p_ipv6 = dut.droid.connectivityGetLinkLocalIpv6Address( + p_aware_if).split('%')[0] + s_ipv6 = other_dut.droid.connectivityGetLinkLocalIpv6Address( + s_aware_if).split('%')[0] + self.log.info('Interface addresses (IPv6): p=%s, s=%s', p_ipv6, + s_ipv6) + else: + autils.fail_on_event_with_keys( + dut, cconsts.EVENT_NETWORK_CALLBACK, + autils.EVENT_NDP_TIMEOUT, + (cconsts.NETWORK_CB_KEY_EVENT, + cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), + (cconsts.NETWORK_CB_KEY_ID, p_req_key)) + autils.fail_on_event_with_keys( + other_dut, cconsts.EVENT_NETWORK_CALLBACK, + autils.EVENT_NDP_TIMEOUT, + (cconsts.NETWORK_CB_KEY_EVENT, + cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), + (cconsts.NETWORK_CB_KEY_ID, s_req_key)) + + asserts.assert_true( + num_peer_devices > max_ndp, + 'Needed %d devices to run the test, have %d' % + (max_ndp + 2, len(self.android_devices))) diff --git a/acts/tests/google/wifi/aware/functional/DataPathTest.py b/acts/tests/google/wifi/aware/functional/DataPathTest.py index 8afb2a4574..cc814338c2 100644 --- a/acts/tests/google/wifi/aware/functional/DataPathTest.py +++ b/acts/tests/google/wifi/aware/functional/DataPathTest.py @@ -26,36 +26,36 @@ from acts.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest class DataPathTest(AwareBaseTest): - """Set of tests for Wi-Fi Aware data-path.""" + """Set of tests for Wi-Fi Aware data-path.""" - # configuration parameters used by tests - ENCR_TYPE_OPEN = 0 - ENCR_TYPE_PASSPHRASE = 1 - ENCR_TYPE_PMK = 2 + # configuration parameters used by tests + ENCR_TYPE_OPEN = 0 + ENCR_TYPE_PASSPHRASE = 1 + ENCR_TYPE_PMK = 2 - PASSPHRASE = "This is some random passphrase - very very secure!!" - PASSPHRASE_MIN = "01234567" - PASSPHRASE_MAX = "012345678901234567890123456789012345678901234567890123456789012" - PMK = "ODU0YjE3YzdmNDJiNWI4NTQ2NDJjNDI3M2VkZTQyZGU=" - PASSPHRASE2 = "This is some random passphrase - very very secure - but diff!!" - PMK2 = "MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=" + PASSPHRASE = "This is some random passphrase - very very secure!!" + PASSPHRASE_MIN = "01234567" + PASSPHRASE_MAX = "012345678901234567890123456789012345678901234567890123456789012" + PMK = "ODU0YjE3YzdmNDJiNWI4NTQ2NDJjNDI3M2VkZTQyZGU=" + PASSPHRASE2 = "This is some random passphrase - very very secure - but diff!!" + PMK2 = "MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTI=" - PING_MSG = "ping" + PING_MSG = "ping" - # message re-transmit counter (increases reliability in open-environment) - # Note: reliability of message transmission is tested elsewhere - MSG_RETX_COUNT = 5 # hard-coded max value, internal API + # message re-transmit counter (increases reliability in open-environment) + # Note: reliability of message transmission is tested elsewhere + MSG_RETX_COUNT = 5 # hard-coded max value, internal API - # number of second to 'reasonably' wait to make sure that devices synchronize - # with each other - useful for OOB test cases, where the OOB discovery would - # take some time - WAIT_FOR_CLUSTER = 5 + # number of second to 'reasonably' wait to make sure that devices synchronize + # with each other - useful for OOB test cases, where the OOB discovery would + # take some time + WAIT_FOR_CLUSTER = 5 - def __init__(self, controllers): - AwareBaseTest.__init__(self, controllers) + def __init__(self, controllers): + AwareBaseTest.__init__(self, controllers) - def create_config(self, dtype): - """Create a base configuration based on input parameters. + def create_config(self, dtype): + """Create a base configuration based on input parameters. Args: dtype: Publish or Subscribe discovery type @@ -63,25 +63,30 @@ class DataPathTest(AwareBaseTest): Returns: Discovery configuration object. """ - config = {} - config[aconsts.DISCOVERY_KEY_DISCOVERY_TYPE] = dtype - config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = "GoogleTestServiceDataPath" - return config + config = {} + config[aconsts.DISCOVERY_KEY_DISCOVERY_TYPE] = dtype + config[ + aconsts.DISCOVERY_KEY_SERVICE_NAME] = "GoogleTestServiceDataPath" + return config - def request_network(self, dut, ns): - """Request a Wi-Fi Aware network. + def request_network(self, dut, ns): + """Request a Wi-Fi Aware network. Args: dut: Device ns: Network specifier Returns: the request key """ - network_req = {"TransportType": 5, "NetworkSpecifier": ns} - return dut.droid.connectivityRequestWifiAwareNetwork(network_req) + network_req = {"TransportType": 5, "NetworkSpecifier": ns} + return dut.droid.connectivityRequestWifiAwareNetwork(network_req) - def set_up_discovery(self, ptype, stype, get_peer_id, pub_on_both=False, - pub_on_both_same=True): - """Set up discovery sessions and wait for service discovery. + def set_up_discovery(self, + ptype, + stype, + get_peer_id, + pub_on_both=False, + pub_on_both_same=True): + """Set up discovery sessions and wait for service discovery. Args: ptype: Publish discovery type @@ -92,66 +97,71 @@ class DataPathTest(AwareBaseTest): pub_on_both_same: If True then the second publish uses an identical service name, otherwise a different service name. """ - p_dut = self.android_devices[0] - p_dut.pretty_name = "Publisher" - s_dut = self.android_devices[1] - s_dut.pretty_name = "Subscriber" - - # Publisher+Subscriber: attach and wait for confirmation - p_id = p_dut.droid.wifiAwareAttach() - autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED) - time.sleep(self.device_startup_offset) - s_id = s_dut.droid.wifiAwareAttach() - autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED) - - # Publisher: start publish and wait for confirmation - p_disc_id = p_dut.droid.wifiAwarePublish(p_id, self.create_config(ptype)) - autils.wait_for_event(p_dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED) - - # Optionally set up a publish session on the Subscriber device - if pub_on_both: - p2_config = self.create_config(ptype) - if not pub_on_both_same: - p2_config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = ( - p2_config[aconsts.DISCOVERY_KEY_SERVICE_NAME] + "-XYZXYZ") - s_dut.droid.wifiAwarePublish(s_id, p2_config) - autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED) - - # Subscriber: start subscribe and wait for confirmation - s_disc_id = s_dut.droid.wifiAwareSubscribe(s_id, self.create_config(stype)) - autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED) - - # Subscriber: wait for service discovery - discovery_event = autils.wait_for_event( - s_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) - peer_id_on_sub = discovery_event["data"][aconsts.SESSION_CB_KEY_PEER_ID] - - peer_id_on_pub = None - if get_peer_id: # only need message to receive peer ID - # Subscriber: send message to peer (Publisher - so it knows our address) - s_dut.droid.wifiAwareSendMessage(s_disc_id, peer_id_on_sub, - self.get_next_msg_id(), self.PING_MSG, - self.MSG_RETX_COUNT) - autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_MESSAGE_SENT) - - # Publisher: wait for received message - pub_rx_msg_event = autils.wait_for_event( - p_dut, aconsts.SESSION_CB_ON_MESSAGE_RECEIVED) - peer_id_on_pub = pub_rx_msg_event["data"][aconsts.SESSION_CB_KEY_PEER_ID] - - return (p_dut, s_dut, p_id, s_id, p_disc_id, s_disc_id, peer_id_on_sub, - peer_id_on_pub) - - def run_ib_data_path_test(self, - ptype, - stype, - encr_type, - use_peer_id, - passphrase_to_use=None, - pub_on_both=False, - pub_on_both_same=True, - expect_failure=False): - """Runs the in-band data-path tests. + p_dut = self.android_devices[0] + p_dut.pretty_name = "Publisher" + s_dut = self.android_devices[1] + s_dut.pretty_name = "Subscriber" + + # Publisher+Subscriber: attach and wait for confirmation + p_id = p_dut.droid.wifiAwareAttach() + autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED) + time.sleep(self.device_startup_offset) + s_id = s_dut.droid.wifiAwareAttach() + autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED) + + # Publisher: start publish and wait for confirmation + p_disc_id = p_dut.droid.wifiAwarePublish(p_id, + self.create_config(ptype)) + autils.wait_for_event(p_dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED) + + # Optionally set up a publish session on the Subscriber device + if pub_on_both: + p2_config = self.create_config(ptype) + if not pub_on_both_same: + p2_config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = ( + p2_config[aconsts.DISCOVERY_KEY_SERVICE_NAME] + "-XYZXYZ") + s_dut.droid.wifiAwarePublish(s_id, p2_config) + autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED) + + # Subscriber: start subscribe and wait for confirmation + s_disc_id = s_dut.droid.wifiAwareSubscribe(s_id, + self.create_config(stype)) + autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED) + + # Subscriber: wait for service discovery + discovery_event = autils.wait_for_event( + s_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) + peer_id_on_sub = discovery_event["data"][ + aconsts.SESSION_CB_KEY_PEER_ID] + + peer_id_on_pub = None + if get_peer_id: # only need message to receive peer ID + # Subscriber: send message to peer (Publisher - so it knows our address) + s_dut.droid.wifiAwareSendMessage(s_disc_id, peer_id_on_sub, + self.get_next_msg_id(), + self.PING_MSG, + self.MSG_RETX_COUNT) + autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_MESSAGE_SENT) + + # Publisher: wait for received message + pub_rx_msg_event = autils.wait_for_event( + p_dut, aconsts.SESSION_CB_ON_MESSAGE_RECEIVED) + peer_id_on_pub = pub_rx_msg_event["data"][ + aconsts.SESSION_CB_KEY_PEER_ID] + + return (p_dut, s_dut, p_id, s_id, p_disc_id, s_disc_id, peer_id_on_sub, + peer_id_on_pub) + + def run_ib_data_path_test(self, + ptype, + stype, + encr_type, + use_peer_id, + passphrase_to_use=None, + pub_on_both=False, + pub_on_both_same=True, + expect_failure=False): + """Runs the in-band data-path tests. Args: ptype: Publish discovery type @@ -168,85 +178,100 @@ class DataPathTest(AwareBaseTest): expect_failure: If True then don't expect NDP formation, otherwise expect NDP setup to succeed. """ - (p_dut, s_dut, p_id, s_id, p_disc_id, s_disc_id, peer_id_on_sub, - peer_id_on_pub) = self.set_up_discovery(ptype, stype, use_peer_id, - pub_on_both=pub_on_both, - pub_on_both_same=pub_on_both_same) - - passphrase = None - pmk = None - if encr_type == self.ENCR_TYPE_PASSPHRASE: - passphrase = ( - self.PASSPHRASE if passphrase_to_use == None else passphrase_to_use) - elif encr_type == self.ENCR_TYPE_PMK: - pmk = self.PMK - - # Publisher: request network - p_req_key = self.request_network( - p_dut, - p_dut.droid.wifiAwareCreateNetworkSpecifier(p_disc_id, peer_id_on_pub if - use_peer_id else None, passphrase, pmk)) - - # Subscriber: request network - s_req_key = self.request_network( - s_dut, - s_dut.droid.wifiAwareCreateNetworkSpecifier(s_disc_id, peer_id_on_sub, - passphrase, pmk)) - - if expect_failure: - # Publisher & Subscriber: fail on network formation - time.sleep(autils.EVENT_NDP_TIMEOUT) - autils.fail_on_event_with_keys(p_dut, cconsts.EVENT_NETWORK_CALLBACK, 0, - (cconsts.NETWORK_CB_KEY_ID, p_req_key)) - autils.fail_on_event_with_keys(s_dut, cconsts.EVENT_NETWORK_CALLBACK, 0, - (cconsts.NETWORK_CB_KEY_ID, s_req_key)) - else: - # Publisher & Subscriber: wait for network formation - p_net_event = autils.wait_for_event_with_keys( - p_dut, cconsts.EVENT_NETWORK_CALLBACK, - autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, p_req_key)) - s_net_event = autils.wait_for_event_with_keys( - s_dut, cconsts.EVENT_NETWORK_CALLBACK, - autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, s_req_key)) - - p_aware_if = p_net_event["data"][cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - s_aware_if = s_net_event["data"][cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - self.log.info("Interface names: p=%s, s=%s", p_aware_if, s_aware_if) - - p_ipv6 = \ - p_dut.droid.connectivityGetLinkLocalIpv6Address(p_aware_if).split("%")[0] - s_ipv6 = \ - s_dut.droid.connectivityGetLinkLocalIpv6Address(s_aware_if).split("%")[0] - self.log.info("Interface addresses (IPv6): p=%s, s=%s", p_ipv6, s_ipv6) - - # TODO: possibly send messages back and forth, prefer to use netcat/nc - - # terminate sessions and wait for ON_LOST callbacks - p_dut.droid.wifiAwareDestroy(p_id) - s_dut.droid.wifiAwareDestroy(s_id) - - autils.wait_for_event_with_keys( - p_dut, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_LOST), (cconsts.NETWORK_CB_KEY_ID, p_req_key)) - autils.wait_for_event_with_keys( - s_dut, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_LOST), (cconsts.NETWORK_CB_KEY_ID, s_req_key)) - - # clean-up - p_dut.droid.connectivityUnregisterNetworkCallback(p_req_key) - s_dut.droid.connectivityUnregisterNetworkCallback(s_req_key) - - def run_oob_data_path_test(self, encr_type, use_peer_id, - setup_discovery_sessions=False, expect_failure=False): - """Runs the out-of-band data-path tests. + (p_dut, s_dut, p_id, s_id, p_disc_id, s_disc_id, peer_id_on_sub, + peer_id_on_pub) = self.set_up_discovery( + ptype, + stype, + use_peer_id, + pub_on_both=pub_on_both, + pub_on_both_same=pub_on_both_same) + + passphrase = None + pmk = None + if encr_type == self.ENCR_TYPE_PASSPHRASE: + passphrase = (self.PASSPHRASE + if passphrase_to_use == None else passphrase_to_use) + elif encr_type == self.ENCR_TYPE_PMK: + pmk = self.PMK + + # Publisher: request network + p_req_key = self.request_network( + p_dut, + p_dut.droid.wifiAwareCreateNetworkSpecifier( + p_disc_id, peer_id_on_pub + if use_peer_id else None, passphrase, pmk)) + + # Subscriber: request network + s_req_key = self.request_network( + s_dut, + s_dut.droid.wifiAwareCreateNetworkSpecifier( + s_disc_id, peer_id_on_sub, passphrase, pmk)) + + if expect_failure: + # Publisher & Subscriber: fail on network formation + time.sleep(autils.EVENT_NDP_TIMEOUT) + autils.fail_on_event_with_keys( + p_dut, cconsts.EVENT_NETWORK_CALLBACK, 0, + (cconsts.NETWORK_CB_KEY_ID, p_req_key)) + autils.fail_on_event_with_keys( + s_dut, cconsts.EVENT_NETWORK_CALLBACK, 0, + (cconsts.NETWORK_CB_KEY_ID, s_req_key)) + else: + # Publisher & Subscriber: wait for network formation + p_net_event = autils.wait_for_event_with_keys( + p_dut, cconsts.EVENT_NETWORK_CALLBACK, + autils.EVENT_NDP_TIMEOUT, + (cconsts.NETWORK_CB_KEY_EVENT, + cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), + (cconsts.NETWORK_CB_KEY_ID, p_req_key)) + s_net_event = autils.wait_for_event_with_keys( + s_dut, cconsts.EVENT_NETWORK_CALLBACK, + autils.EVENT_NDP_TIMEOUT, + (cconsts.NETWORK_CB_KEY_EVENT, + cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), + (cconsts.NETWORK_CB_KEY_ID, s_req_key)) + + p_aware_if = p_net_event["data"][ + cconsts.NETWORK_CB_KEY_INTERFACE_NAME] + s_aware_if = s_net_event["data"][ + cconsts.NETWORK_CB_KEY_INTERFACE_NAME] + self.log.info("Interface names: p=%s, s=%s", p_aware_if, + s_aware_if) + + p_ipv6 = \ + p_dut.droid.connectivityGetLinkLocalIpv6Address(p_aware_if).split("%")[0] + s_ipv6 = \ + s_dut.droid.connectivityGetLinkLocalIpv6Address(s_aware_if).split("%")[0] + self.log.info("Interface addresses (IPv6): p=%s, s=%s", p_ipv6, + s_ipv6) + + # TODO: possibly send messages back and forth, prefer to use netcat/nc + + # terminate sessions and wait for ON_LOST callbacks + p_dut.droid.wifiAwareDestroy(p_id) + s_dut.droid.wifiAwareDestroy(s_id) + + autils.wait_for_event_with_keys( + p_dut, cconsts.EVENT_NETWORK_CALLBACK, + autils.EVENT_NDP_TIMEOUT, + (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_LOST), + (cconsts.NETWORK_CB_KEY_ID, p_req_key)) + autils.wait_for_event_with_keys( + s_dut, cconsts.EVENT_NETWORK_CALLBACK, + autils.EVENT_NDP_TIMEOUT, + (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_LOST), + (cconsts.NETWORK_CB_KEY_ID, s_req_key)) + + # clean-up + p_dut.droid.connectivityUnregisterNetworkCallback(p_req_key) + s_dut.droid.connectivityUnregisterNetworkCallback(s_req_key) + + def run_oob_data_path_test(self, + encr_type, + use_peer_id, + setup_discovery_sessions=False, + expect_failure=False): + """Runs the out-of-band data-path tests. Args: encr_type: Encryption type, one of ENCR_TYPE_* @@ -258,162 +283,173 @@ class DataPathTest(AwareBaseTest): expect_failure: If True then don't expect NDP formation, otherwise expect NDP setup to succeed. """ - init_dut = self.android_devices[0] - init_dut.pretty_name = "Initiator" - resp_dut = self.android_devices[1] - resp_dut.pretty_name = "Responder" - - # Initiator+Responder: attach and wait for confirmation & identity - init_id = init_dut.droid.wifiAwareAttach(True) - autils.wait_for_event(init_dut, aconsts.EVENT_CB_ON_ATTACHED) - init_ident_event = autils.wait_for_event( - init_dut, aconsts.EVENT_CB_ON_IDENTITY_CHANGED) - init_mac = init_ident_event["data"]["mac"] - time.sleep(self.device_startup_offset) - resp_id = resp_dut.droid.wifiAwareAttach(True) - autils.wait_for_event(resp_dut, aconsts.EVENT_CB_ON_ATTACHED) - resp_ident_event = autils.wait_for_event( - resp_dut, aconsts.EVENT_CB_ON_IDENTITY_CHANGED) - resp_mac = resp_ident_event["data"]["mac"] - - # wait for for devices to synchronize with each other - there are no other - # mechanisms to make sure this happens for OOB discovery (except retrying - # to execute the data-path request) - time.sleep(self.WAIT_FOR_CLUSTER) - - if setup_discovery_sessions: - init_dut.droid.wifiAwarePublish(init_id, self.create_config( - aconsts.PUBLISH_TYPE_UNSOLICITED)) - autils.wait_for_event(init_dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED) - resp_dut.droid.wifiAwarePublish(resp_id, self.create_config( - aconsts.PUBLISH_TYPE_UNSOLICITED)) - autils.wait_for_event(resp_dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED) - resp_dut.droid.wifiAwareSubscribe(resp_id, self.create_config( - aconsts.SUBSCRIBE_TYPE_PASSIVE)) - autils.wait_for_event(resp_dut, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED) - autils.wait_for_event(resp_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) - - passphrase = None - pmk = None - if encr_type == self.ENCR_TYPE_PASSPHRASE: - passphrase = self.PASSPHRASE - elif encr_type == self.ENCR_TYPE_PMK: - pmk = self.PMK - - # Responder: request network - resp_req_key = self.request_network( - resp_dut, - resp_dut.droid.wifiAwareCreateNetworkSpecifierOob( - resp_id, aconsts.DATA_PATH_RESPONDER, init_mac - if use_peer_id else None, passphrase, pmk)) - - # Initiator: request network - init_req_key = self.request_network( - init_dut, - init_dut.droid.wifiAwareCreateNetworkSpecifierOob( - init_id, aconsts.DATA_PATH_INITIATOR, resp_mac, passphrase, pmk)) - - if expect_failure: - # Initiator & Responder: fail on network formation - time.sleep(autils.EVENT_NDP_TIMEOUT) - autils.fail_on_event_with_keys(resp_dut, cconsts.EVENT_NETWORK_CALLBACK, - 0, - (cconsts.NETWORK_CB_KEY_ID, resp_req_key)) - autils.fail_on_event_with_keys(init_dut, cconsts.EVENT_NETWORK_CALLBACK, - 0, - (cconsts.NETWORK_CB_KEY_ID, init_req_key)) - else: - # Initiator & Responder: wait for network formation - init_net_event = autils.wait_for_event_with_keys( - init_dut, cconsts.EVENT_NETWORK_CALLBACK, - autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, init_req_key)) - resp_net_event = autils.wait_for_event_with_keys( - resp_dut, cconsts.EVENT_NETWORK_CALLBACK, - autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, resp_req_key)) - - init_aware_if = init_net_event["data"][ - cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - resp_aware_if = resp_net_event["data"][ - cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - self.log.info("Interface names: I=%s, R=%s", init_aware_if, resp_aware_if) - - init_ipv6 = init_dut.droid.connectivityGetLinkLocalIpv6Address( - init_aware_if).split("%")[0] - resp_ipv6 = resp_dut.droid.connectivityGetLinkLocalIpv6Address( - resp_aware_if).split("%")[0] - self.log.info("Interface addresses (IPv6): I=%s, R=%s", init_ipv6, - resp_ipv6) - - # TODO: possibly send messages back and forth, prefer to use netcat/nc - - # terminate sessions and wait for ON_LOST callbacks - init_dut.droid.wifiAwareDestroy(init_id) - resp_dut.droid.wifiAwareDestroy(resp_id) - - autils.wait_for_event_with_keys( - init_dut, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_LOST), (cconsts.NETWORK_CB_KEY_ID, init_req_key)) - autils.wait_for_event_with_keys( - resp_dut, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_LOST), (cconsts.NETWORK_CB_KEY_ID, resp_req_key)) - - # clean-up - resp_dut.droid.connectivityUnregisterNetworkCallback(resp_req_key) - init_dut.droid.connectivityUnregisterNetworkCallback(init_req_key) - - def run_mismatched_ib_data_path_test(self, pub_mismatch, sub_mismatch): - """Runs the negative in-band data-path tests: mismatched peer ID. + init_dut = self.android_devices[0] + init_dut.pretty_name = "Initiator" + resp_dut = self.android_devices[1] + resp_dut.pretty_name = "Responder" + + # Initiator+Responder: attach and wait for confirmation & identity + init_id = init_dut.droid.wifiAwareAttach(True) + autils.wait_for_event(init_dut, aconsts.EVENT_CB_ON_ATTACHED) + init_ident_event = autils.wait_for_event( + init_dut, aconsts.EVENT_CB_ON_IDENTITY_CHANGED) + init_mac = init_ident_event["data"]["mac"] + time.sleep(self.device_startup_offset) + resp_id = resp_dut.droid.wifiAwareAttach(True) + autils.wait_for_event(resp_dut, aconsts.EVENT_CB_ON_ATTACHED) + resp_ident_event = autils.wait_for_event( + resp_dut, aconsts.EVENT_CB_ON_IDENTITY_CHANGED) + resp_mac = resp_ident_event["data"]["mac"] + + # wait for for devices to synchronize with each other - there are no other + # mechanisms to make sure this happens for OOB discovery (except retrying + # to execute the data-path request) + time.sleep(self.WAIT_FOR_CLUSTER) + + if setup_discovery_sessions: + init_dut.droid.wifiAwarePublish( + init_id, self.create_config(aconsts.PUBLISH_TYPE_UNSOLICITED)) + autils.wait_for_event(init_dut, + aconsts.SESSION_CB_ON_PUBLISH_STARTED) + resp_dut.droid.wifiAwarePublish( + resp_id, self.create_config(aconsts.PUBLISH_TYPE_UNSOLICITED)) + autils.wait_for_event(resp_dut, + aconsts.SESSION_CB_ON_PUBLISH_STARTED) + resp_dut.droid.wifiAwareSubscribe( + resp_id, self.create_config(aconsts.SUBSCRIBE_TYPE_PASSIVE)) + autils.wait_for_event(resp_dut, + aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED) + autils.wait_for_event(resp_dut, + aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) + + passphrase = None + pmk = None + if encr_type == self.ENCR_TYPE_PASSPHRASE: + passphrase = self.PASSPHRASE + elif encr_type == self.ENCR_TYPE_PMK: + pmk = self.PMK + + # Responder: request network + resp_req_key = self.request_network( + resp_dut, + resp_dut.droid.wifiAwareCreateNetworkSpecifierOob( + resp_id, aconsts.DATA_PATH_RESPONDER, init_mac + if use_peer_id else None, passphrase, pmk)) + + # Initiator: request network + init_req_key = self.request_network( + init_dut, + init_dut.droid.wifiAwareCreateNetworkSpecifierOob( + init_id, aconsts.DATA_PATH_INITIATOR, resp_mac, passphrase, + pmk)) + + if expect_failure: + # Initiator & Responder: fail on network formation + time.sleep(autils.EVENT_NDP_TIMEOUT) + autils.fail_on_event_with_keys( + resp_dut, cconsts.EVENT_NETWORK_CALLBACK, 0, + (cconsts.NETWORK_CB_KEY_ID, resp_req_key)) + autils.fail_on_event_with_keys( + init_dut, cconsts.EVENT_NETWORK_CALLBACK, 0, + (cconsts.NETWORK_CB_KEY_ID, init_req_key)) + else: + # Initiator & Responder: wait for network formation + init_net_event = autils.wait_for_event_with_keys( + init_dut, cconsts.EVENT_NETWORK_CALLBACK, + autils.EVENT_NDP_TIMEOUT, + (cconsts.NETWORK_CB_KEY_EVENT, + cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), + (cconsts.NETWORK_CB_KEY_ID, init_req_key)) + resp_net_event = autils.wait_for_event_with_keys( + resp_dut, cconsts.EVENT_NETWORK_CALLBACK, + autils.EVENT_NDP_TIMEOUT, + (cconsts.NETWORK_CB_KEY_EVENT, + cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), + (cconsts.NETWORK_CB_KEY_ID, resp_req_key)) + + init_aware_if = init_net_event["data"][ + cconsts.NETWORK_CB_KEY_INTERFACE_NAME] + resp_aware_if = resp_net_event["data"][ + cconsts.NETWORK_CB_KEY_INTERFACE_NAME] + self.log.info("Interface names: I=%s, R=%s", init_aware_if, + resp_aware_if) + + init_ipv6 = init_dut.droid.connectivityGetLinkLocalIpv6Address( + init_aware_if).split("%")[0] + resp_ipv6 = resp_dut.droid.connectivityGetLinkLocalIpv6Address( + resp_aware_if).split("%")[0] + self.log.info("Interface addresses (IPv6): I=%s, R=%s", init_ipv6, + resp_ipv6) + + # TODO: possibly send messages back and forth, prefer to use netcat/nc + + # terminate sessions and wait for ON_LOST callbacks + init_dut.droid.wifiAwareDestroy(init_id) + resp_dut.droid.wifiAwareDestroy(resp_id) + + autils.wait_for_event_with_keys( + init_dut, cconsts.EVENT_NETWORK_CALLBACK, + autils.EVENT_NDP_TIMEOUT, + (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_LOST), + (cconsts.NETWORK_CB_KEY_ID, init_req_key)) + autils.wait_for_event_with_keys( + resp_dut, cconsts.EVENT_NETWORK_CALLBACK, + autils.EVENT_NDP_TIMEOUT, + (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_LOST), + (cconsts.NETWORK_CB_KEY_ID, resp_req_key)) + + # clean-up + resp_dut.droid.connectivityUnregisterNetworkCallback(resp_req_key) + init_dut.droid.connectivityUnregisterNetworkCallback(init_req_key) + + def run_mismatched_ib_data_path_test(self, pub_mismatch, sub_mismatch): + """Runs the negative in-band data-path tests: mismatched peer ID. Args: pub_mismatch: Mismatch the publisher's ID sub_mismatch: Mismatch the subscriber's ID """ - (p_dut, s_dut, p_id, s_id, p_disc_id, s_disc_id, - peer_id_on_sub, peer_id_on_pub) = self.set_up_discovery( - aconsts.PUBLISH_TYPE_UNSOLICITED, aconsts.SUBSCRIBE_TYPE_PASSIVE, True) - - if pub_mismatch: - peer_id_on_pub = peer_id_on_pub -1 - if sub_mismatch: - peer_id_on_sub = peer_id_on_sub - 1 - - # Publisher: request network - p_req_key = self.request_network( - p_dut, - p_dut.droid.wifiAwareCreateNetworkSpecifier(p_disc_id, peer_id_on_pub, - None)) - - # Subscriber: request network - s_req_key = self.request_network( - s_dut, - s_dut.droid.wifiAwareCreateNetworkSpecifier(s_disc_id, peer_id_on_sub, - None)) - - # Publisher & Subscriber: fail on network formation - time.sleep(autils.EVENT_NDP_TIMEOUT) - autils.fail_on_event_with_keys(p_dut, cconsts.EVENT_NETWORK_CALLBACK, 0, - (cconsts.NETWORK_CB_KEY_ID, p_req_key)) - autils.fail_on_event_with_keys(s_dut, cconsts.EVENT_NETWORK_CALLBACK, 0, - (cconsts.NETWORK_CB_KEY_ID, s_req_key)) - - # clean-up - p_dut.droid.connectivityUnregisterNetworkCallback(p_req_key) - s_dut.droid.connectivityUnregisterNetworkCallback(s_req_key) - - def run_mismatched_oob_data_path_test(self, - init_mismatch_mac=False, - resp_mismatch_mac=False, - init_encr_type=ENCR_TYPE_OPEN, - resp_encr_type=ENCR_TYPE_OPEN): - """Runs the negative out-of-band data-path tests: mismatched information + (p_dut, s_dut, p_id, s_id, p_disc_id, s_disc_id, peer_id_on_sub, + peer_id_on_pub) = self.set_up_discovery( + aconsts.PUBLISH_TYPE_UNSOLICITED, aconsts.SUBSCRIBE_TYPE_PASSIVE, + True) + + if pub_mismatch: + peer_id_on_pub = peer_id_on_pub - 1 + if sub_mismatch: + peer_id_on_sub = peer_id_on_sub - 1 + + # Publisher: request network + p_req_key = self.request_network( + p_dut, + p_dut.droid.wifiAwareCreateNetworkSpecifier( + p_disc_id, peer_id_on_pub, None)) + + # Subscriber: request network + s_req_key = self.request_network( + s_dut, + s_dut.droid.wifiAwareCreateNetworkSpecifier( + s_disc_id, peer_id_on_sub, None)) + + # Publisher & Subscriber: fail on network formation + time.sleep(autils.EVENT_NDP_TIMEOUT) + autils.fail_on_event_with_keys(p_dut, cconsts.EVENT_NETWORK_CALLBACK, + 0, + (cconsts.NETWORK_CB_KEY_ID, p_req_key)) + autils.fail_on_event_with_keys(s_dut, cconsts.EVENT_NETWORK_CALLBACK, + 0, + (cconsts.NETWORK_CB_KEY_ID, s_req_key)) + + # clean-up + p_dut.droid.connectivityUnregisterNetworkCallback(p_req_key) + s_dut.droid.connectivityUnregisterNetworkCallback(s_req_key) + + def run_mismatched_oob_data_path_test(self, + init_mismatch_mac=False, + resp_mismatch_mac=False, + init_encr_type=ENCR_TYPE_OPEN, + resp_encr_type=ENCR_TYPE_OPEN): + """Runs the negative out-of-band data-path tests: mismatched information between Responder and Initiator. Args: @@ -422,786 +458,794 @@ class DataPathTest(AwareBaseTest): init_encr_type: Encryption type of Initiator - ENCR_TYPE_* resp_encr_type: Encryption type of Responder - ENCR_TYPE_* """ - init_dut = self.android_devices[0] - init_dut.pretty_name = "Initiator" - resp_dut = self.android_devices[1] - resp_dut.pretty_name = "Responder" - - # Initiator+Responder: attach and wait for confirmation & identity - init_id = init_dut.droid.wifiAwareAttach(True) - autils.wait_for_event(init_dut, aconsts.EVENT_CB_ON_ATTACHED) - init_ident_event = autils.wait_for_event( - init_dut, aconsts.EVENT_CB_ON_IDENTITY_CHANGED) - init_mac = init_ident_event["data"]["mac"] - time.sleep(self.device_startup_offset) - resp_id = resp_dut.droid.wifiAwareAttach(True) - autils.wait_for_event(resp_dut, aconsts.EVENT_CB_ON_ATTACHED) - resp_ident_event = autils.wait_for_event( - resp_dut, aconsts.EVENT_CB_ON_IDENTITY_CHANGED) - resp_mac = resp_ident_event["data"]["mac"] - - if init_mismatch_mac: # assumes legit ones don't start with "00" - init_mac = "00" + init_mac[2:] - if resp_mismatch_mac: - resp_mac = "00" + resp_mac[2:] - - # wait for for devices to synchronize with each other - there are no other - # mechanisms to make sure this happens for OOB discovery (except retrying - # to execute the data-path request) - time.sleep(self.WAIT_FOR_CLUSTER) - - # set up separate keys: even if types are the same we want a mismatch - init_passphrase = None - init_pmk = None - if init_encr_type == self.ENCR_TYPE_PASSPHRASE: - init_passphrase = self.PASSPHRASE - elif init_encr_type == self.ENCR_TYPE_PMK: - init_pmk = self.PMK - - resp_passphrase = None - resp_pmk = None - if resp_encr_type == self.ENCR_TYPE_PASSPHRASE: - resp_passphrase = self.PASSPHRASE2 - elif resp_encr_type == self.ENCR_TYPE_PMK: - resp_pmk = self.PMK2 - - # Responder: request network - resp_req_key = self.request_network( - resp_dut, - resp_dut.droid.wifiAwareCreateNetworkSpecifierOob( - resp_id, aconsts.DATA_PATH_RESPONDER, init_mac, resp_passphrase, - resp_pmk)) - - # Initiator: request network - init_req_key = self.request_network( - init_dut, - init_dut.droid.wifiAwareCreateNetworkSpecifierOob( - init_id, aconsts.DATA_PATH_INITIATOR, resp_mac, init_passphrase, - init_pmk)) - - # Initiator & Responder: fail on network formation - time.sleep(autils.EVENT_NDP_TIMEOUT) - autils.fail_on_event_with_keys(init_dut, cconsts.EVENT_NETWORK_CALLBACK, 0, - (cconsts.NETWORK_CB_KEY_ID, init_req_key)) - autils.fail_on_event_with_keys(resp_dut, cconsts.EVENT_NETWORK_CALLBACK, 0, - (cconsts.NETWORK_CB_KEY_ID, resp_req_key)) - - # clean-up - resp_dut.droid.connectivityUnregisterNetworkCallback(resp_req_key) - init_dut.droid.connectivityUnregisterNetworkCallback(init_req_key) - - - ####################################### - # Positive In-Band (IB) tests key: - # - # names is: test_ib_<pub_type>_<sub_type>_<encr_type>_<peer_spec> - # where: - # - # pub_type: Type of publish discovery session: unsolicited or solicited. - # sub_type: Type of subscribe discovery session: passive or active. - # encr_type: Encription type: open, passphrase - # peer_spec: Peer specification method: any or specific - # - # Note: In-Band means using Wi-Fi Aware for discovery and referring to the - # peer using the Aware-provided peer handle (as opposed to a MAC address). - ####################################### - - @test_tracker_info(uuid="fa30bedc-d1de-4440-bf25-ec00d10555af") - def test_ib_unsolicited_passive_open_specific(self): - """Data-path: in-band, unsolicited/passive, open encryption, specific peer + init_dut = self.android_devices[0] + init_dut.pretty_name = "Initiator" + resp_dut = self.android_devices[1] + resp_dut.pretty_name = "Responder" + + # Initiator+Responder: attach and wait for confirmation & identity + init_id = init_dut.droid.wifiAwareAttach(True) + autils.wait_for_event(init_dut, aconsts.EVENT_CB_ON_ATTACHED) + init_ident_event = autils.wait_for_event( + init_dut, aconsts.EVENT_CB_ON_IDENTITY_CHANGED) + init_mac = init_ident_event["data"]["mac"] + time.sleep(self.device_startup_offset) + resp_id = resp_dut.droid.wifiAwareAttach(True) + autils.wait_for_event(resp_dut, aconsts.EVENT_CB_ON_ATTACHED) + resp_ident_event = autils.wait_for_event( + resp_dut, aconsts.EVENT_CB_ON_IDENTITY_CHANGED) + resp_mac = resp_ident_event["data"]["mac"] + + if init_mismatch_mac: # assumes legit ones don't start with "00" + init_mac = "00" + init_mac[2:] + if resp_mismatch_mac: + resp_mac = "00" + resp_mac[2:] + + # wait for for devices to synchronize with each other - there are no other + # mechanisms to make sure this happens for OOB discovery (except retrying + # to execute the data-path request) + time.sleep(self.WAIT_FOR_CLUSTER) + + # set up separate keys: even if types are the same we want a mismatch + init_passphrase = None + init_pmk = None + if init_encr_type == self.ENCR_TYPE_PASSPHRASE: + init_passphrase = self.PASSPHRASE + elif init_encr_type == self.ENCR_TYPE_PMK: + init_pmk = self.PMK + + resp_passphrase = None + resp_pmk = None + if resp_encr_type == self.ENCR_TYPE_PASSPHRASE: + resp_passphrase = self.PASSPHRASE2 + elif resp_encr_type == self.ENCR_TYPE_PMK: + resp_pmk = self.PMK2 + + # Responder: request network + resp_req_key = self.request_network( + resp_dut, + resp_dut.droid.wifiAwareCreateNetworkSpecifierOob( + resp_id, aconsts.DATA_PATH_RESPONDER, init_mac, + resp_passphrase, resp_pmk)) + + # Initiator: request network + init_req_key = self.request_network( + init_dut, + init_dut.droid.wifiAwareCreateNetworkSpecifierOob( + init_id, aconsts.DATA_PATH_INITIATOR, resp_mac, + init_passphrase, init_pmk)) + + # Initiator & Responder: fail on network formation + time.sleep(autils.EVENT_NDP_TIMEOUT) + autils.fail_on_event_with_keys( + init_dut, cconsts.EVENT_NETWORK_CALLBACK, 0, + (cconsts.NETWORK_CB_KEY_ID, init_req_key)) + autils.fail_on_event_with_keys( + resp_dut, cconsts.EVENT_NETWORK_CALLBACK, 0, + (cconsts.NETWORK_CB_KEY_ID, resp_req_key)) + + # clean-up + resp_dut.droid.connectivityUnregisterNetworkCallback(resp_req_key) + init_dut.droid.connectivityUnregisterNetworkCallback(init_req_key) + + ####################################### + # Positive In-Band (IB) tests key: + # + # names is: test_ib_<pub_type>_<sub_type>_<encr_type>_<peer_spec> + # where: + # + # pub_type: Type of publish discovery session: unsolicited or solicited. + # sub_type: Type of subscribe discovery session: passive or active. + # encr_type: Encription type: open, passphrase + # peer_spec: Peer specification method: any or specific + # + # Note: In-Band means using Wi-Fi Aware for discovery and referring to the + # peer using the Aware-provided peer handle (as opposed to a MAC address). + ####################################### + + @test_tracker_info(uuid="fa30bedc-d1de-4440-bf25-ec00d10555af") + def test_ib_unsolicited_passive_open_specific(self): + """Data-path: in-band, unsolicited/passive, open encryption, specific peer Verifies end-to-end discovery + data-path creation. """ - self.run_ib_data_path_test( - ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, - stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, - encr_type=self.ENCR_TYPE_OPEN, - use_peer_id=True) + self.run_ib_data_path_test( + ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, + stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, + encr_type=self.ENCR_TYPE_OPEN, + use_peer_id=True) - @test_tracker_info(uuid="57fc9d53-32ae-470f-a8b1-2fe37893687d") - def test_ib_unsolicited_passive_open_any(self): - """Data-path: in-band, unsolicited/passive, open encryption, any peer + @test_tracker_info(uuid="57fc9d53-32ae-470f-a8b1-2fe37893687d") + def test_ib_unsolicited_passive_open_any(self): + """Data-path: in-band, unsolicited/passive, open encryption, any peer Verifies end-to-end discovery + data-path creation. """ - self.run_ib_data_path_test( - ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, - stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, - encr_type=self.ENCR_TYPE_OPEN, - use_peer_id=False) + self.run_ib_data_path_test( + ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, + stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, + encr_type=self.ENCR_TYPE_OPEN, + use_peer_id=False) - @test_tracker_info(uuid="93b2a23d-8579-448a-936c-7812929464cf") - def test_ib_unsolicited_passive_passphrase_specific(self): - """Data-path: in-band, unsolicited/passive, passphrase, specific peer + @test_tracker_info(uuid="93b2a23d-8579-448a-936c-7812929464cf") + def test_ib_unsolicited_passive_passphrase_specific(self): + """Data-path: in-band, unsolicited/passive, passphrase, specific peer Verifies end-to-end discovery + data-path creation. """ - self.run_ib_data_path_test( - ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, - stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, - encr_type=self.ENCR_TYPE_PASSPHRASE, - use_peer_id=True) + self.run_ib_data_path_test( + ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, + stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, + encr_type=self.ENCR_TYPE_PASSPHRASE, + use_peer_id=True) - @test_tracker_info(uuid="1736126f-a0ff-4712-acc4-f89b4eef5716") - def test_ib_unsolicited_passive_passphrase_any(self): - """Data-path: in-band, unsolicited/passive, passphrase, any peer + @test_tracker_info(uuid="1736126f-a0ff-4712-acc4-f89b4eef5716") + def test_ib_unsolicited_passive_passphrase_any(self): + """Data-path: in-band, unsolicited/passive, passphrase, any peer Verifies end-to-end discovery + data-path creation. """ - self.run_ib_data_path_test( - ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, - stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, - encr_type=self.ENCR_TYPE_PASSPHRASE, - use_peer_id=False) + self.run_ib_data_path_test( + ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, + stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, + encr_type=self.ENCR_TYPE_PASSPHRASE, + use_peer_id=False) - @test_tracker_info(uuid="b9353d5b-3f77-46bf-bfd9-65d56a7c939a") - def test_ib_unsolicited_passive_pmk_specific(self): - """Data-path: in-band, unsolicited/passive, PMK, specific peer + @test_tracker_info(uuid="b9353d5b-3f77-46bf-bfd9-65d56a7c939a") + def test_ib_unsolicited_passive_pmk_specific(self): + """Data-path: in-band, unsolicited/passive, PMK, specific peer Verifies end-to-end discovery + data-path creation. """ - self.run_ib_data_path_test( - ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, - stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, - encr_type=self.ENCR_TYPE_PMK, - use_peer_id=True) + self.run_ib_data_path_test( + ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, + stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, + encr_type=self.ENCR_TYPE_PMK, + use_peer_id=True) - @test_tracker_info(uuid="06f3b2ab-4a10-4398-83a4-6a23851b1662") - def test_ib_unsolicited_passive_pmk_any(self): - """Data-path: in-band, unsolicited/passive, PMK, any peer + @test_tracker_info(uuid="06f3b2ab-4a10-4398-83a4-6a23851b1662") + def test_ib_unsolicited_passive_pmk_any(self): + """Data-path: in-band, unsolicited/passive, PMK, any peer Verifies end-to-end discovery + data-path creation. """ - self.run_ib_data_path_test( - ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, - stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, - encr_type=self.ENCR_TYPE_PMK, - use_peer_id=False) + self.run_ib_data_path_test( + ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, + stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, + encr_type=self.ENCR_TYPE_PMK, + use_peer_id=False) - @test_tracker_info(uuid="0ed7d8b3-a69e-46ba-aeb7-13e507ecf290") - def test_ib_solicited_active_open_specific(self): - """Data-path: in-band, solicited/active, open encryption, specific peer + @test_tracker_info(uuid="0ed7d8b3-a69e-46ba-aeb7-13e507ecf290") + def test_ib_solicited_active_open_specific(self): + """Data-path: in-band, solicited/active, open encryption, specific peer Verifies end-to-end discovery + data-path creation. """ - self.run_ib_data_path_test( - ptype=aconsts.PUBLISH_TYPE_SOLICITED, - stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, - encr_type=self.ENCR_TYPE_OPEN, - use_peer_id=True) + self.run_ib_data_path_test( + ptype=aconsts.PUBLISH_TYPE_SOLICITED, + stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, + encr_type=self.ENCR_TYPE_OPEN, + use_peer_id=True) - @test_tracker_info(uuid="c7ba6d28-5ef6-45d9-95d5-583ad6d981f3") - def test_ib_solicited_active_open_any(self): - """Data-path: in-band, solicited/active, open encryption, any peer + @test_tracker_info(uuid="c7ba6d28-5ef6-45d9-95d5-583ad6d981f3") + def test_ib_solicited_active_open_any(self): + """Data-path: in-band, solicited/active, open encryption, any peer Verifies end-to-end discovery + data-path creation. """ - self.run_ib_data_path_test( - ptype=aconsts.PUBLISH_TYPE_SOLICITED, - stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, - encr_type=self.ENCR_TYPE_OPEN, - use_peer_id=False) + self.run_ib_data_path_test( + ptype=aconsts.PUBLISH_TYPE_SOLICITED, + stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, + encr_type=self.ENCR_TYPE_OPEN, + use_peer_id=False) - @test_tracker_info(uuid="388cea99-0e2e-49ea-b00e-f3e56b6236e5") - def test_ib_solicited_active_passphrase_specific(self): - """Data-path: in-band, solicited/active, passphrase, specific peer + @test_tracker_info(uuid="388cea99-0e2e-49ea-b00e-f3e56b6236e5") + def test_ib_solicited_active_passphrase_specific(self): + """Data-path: in-band, solicited/active, passphrase, specific peer Verifies end-to-end discovery + data-path creation. """ - self.run_ib_data_path_test( - ptype=aconsts.PUBLISH_TYPE_SOLICITED, - stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, - encr_type=self.ENCR_TYPE_PASSPHRASE, - use_peer_id=True) + self.run_ib_data_path_test( + ptype=aconsts.PUBLISH_TYPE_SOLICITED, + stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, + encr_type=self.ENCR_TYPE_PASSPHRASE, + use_peer_id=True) - @test_tracker_info(uuid="fcd3e28a-5eab-4169-8a0c-dc7204dcdc13") - def test_ib_solicited_active_passphrase_any(self): - """Data-path: in-band, solicited/active, passphrase, any peer + @test_tracker_info(uuid="fcd3e28a-5eab-4169-8a0c-dc7204dcdc13") + def test_ib_solicited_active_passphrase_any(self): + """Data-path: in-band, solicited/active, passphrase, any peer Verifies end-to-end discovery + data-path creation. """ - self.run_ib_data_path_test( - ptype=aconsts.PUBLISH_TYPE_SOLICITED, - stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, - encr_type=self.ENCR_TYPE_PASSPHRASE, - use_peer_id=False) + self.run_ib_data_path_test( + ptype=aconsts.PUBLISH_TYPE_SOLICITED, + stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, + encr_type=self.ENCR_TYPE_PASSPHRASE, + use_peer_id=False) - @test_tracker_info(uuid="9d4eaad7-ba53-4a06-8ce0-e308daea3309") - def test_ib_solicited_active_pmk_specific(self): - """Data-path: in-band, solicited/active, PMK, specific peer + @test_tracker_info(uuid="9d4eaad7-ba53-4a06-8ce0-e308daea3309") + def test_ib_solicited_active_pmk_specific(self): + """Data-path: in-band, solicited/active, PMK, specific peer Verifies end-to-end discovery + data-path creation. """ - self.run_ib_data_path_test( - ptype=aconsts.PUBLISH_TYPE_SOLICITED, - stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, - encr_type=self.ENCR_TYPE_PMK, - use_peer_id=True) + self.run_ib_data_path_test( + ptype=aconsts.PUBLISH_TYPE_SOLICITED, + stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, + encr_type=self.ENCR_TYPE_PMK, + use_peer_id=True) - @test_tracker_info(uuid="129d850e-c312-4137-a67b-05ae95fe66cc") - def test_ib_solicited_active_pmk_any(self): - """Data-path: in-band, solicited/active, PMK, any peer + @test_tracker_info(uuid="129d850e-c312-4137-a67b-05ae95fe66cc") + def test_ib_solicited_active_pmk_any(self): + """Data-path: in-band, solicited/active, PMK, any peer Verifies end-to-end discovery + data-path creation. """ - self.run_ib_data_path_test( - ptype=aconsts.PUBLISH_TYPE_SOLICITED, - stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, - encr_type=self.ENCR_TYPE_PMK, - use_peer_id=False) - - ####################################### - # Positive In-Band (IB) with a publish session running on the subscriber - # tests key: - # - # names is: test_ib_extra_pub_<same|diff>_<pub_type>_<sub_type> - # _<encr_type>_<peer_spec> - # where: - # - # same|diff: Whether the extra publish session (on the subscriber) is the same - # or different from the primary session. - # pub_type: Type of publish discovery session: unsolicited or solicited. - # sub_type: Type of subscribe discovery session: passive or active. - # encr_type: Encryption type: open, passphrase - # peer_spec: Peer specification method: any or specific - # - # Note: In-Band means using Wi-Fi Aware for discovery and referring to the - # peer using the Aware-provided peer handle (as opposed to a MAC address). - ####################################### - - @test_tracker_info(uuid="e855dd81-45c8-4bb2-a204-7687c48ff843") - def test_ib_extra_pub_same_unsolicited_passive_open_specific(self): - """Data-path: in-band, unsolicited/passive, open encryption, specific peer. + self.run_ib_data_path_test( + ptype=aconsts.PUBLISH_TYPE_SOLICITED, + stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, + encr_type=self.ENCR_TYPE_PMK, + use_peer_id=False) + + ####################################### + # Positive In-Band (IB) with a publish session running on the subscriber + # tests key: + # + # names is: test_ib_extra_pub_<same|diff>_<pub_type>_<sub_type> + # _<encr_type>_<peer_spec> + # where: + # + # same|diff: Whether the extra publish session (on the subscriber) is the same + # or different from the primary session. + # pub_type: Type of publish discovery session: unsolicited or solicited. + # sub_type: Type of subscribe discovery session: passive or active. + # encr_type: Encryption type: open, passphrase + # peer_spec: Peer specification method: any or specific + # + # Note: In-Band means using Wi-Fi Aware for discovery and referring to the + # peer using the Aware-provided peer handle (as opposed to a MAC address). + ####################################### + + @test_tracker_info(uuid="e855dd81-45c8-4bb2-a204-7687c48ff843") + def test_ib_extra_pub_same_unsolicited_passive_open_specific(self): + """Data-path: in-band, unsolicited/passive, open encryption, specific peer. Configuration contains a publisher (for the same service) running on *both* devices. Verifies end-to-end discovery + data-path creation. """ - self.run_ib_data_path_test( - ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, - stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, - encr_type=self.ENCR_TYPE_OPEN, - use_peer_id=True, - pub_on_both=True, - pub_on_both_same=True) - - @test_tracker_info(uuid="57fc9d53-32ae-470f-a8b1-2fe37893687d") - def test_ib_extra_pub_same_unsolicited_passive_open_any(self): - """Data-path: in-band, unsolicited/passive, open encryption, any peer. + self.run_ib_data_path_test( + ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, + stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, + encr_type=self.ENCR_TYPE_OPEN, + use_peer_id=True, + pub_on_both=True, + pub_on_both_same=True) + + @test_tracker_info(uuid="57fc9d53-32ae-470f-a8b1-2fe37893687d") + def test_ib_extra_pub_same_unsolicited_passive_open_any(self): + """Data-path: in-band, unsolicited/passive, open encryption, any peer. Configuration contains a publisher (for the same service) running on *both* devices. Verifies end-to-end discovery + data-path creation. """ - self.run_ib_data_path_test( - ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, - stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, - encr_type=self.ENCR_TYPE_OPEN, - use_peer_id=False, - pub_on_both=True, - pub_on_both_same=True) - - @test_tracker_info(uuid="7a32f439-d745-4716-a75e-b54109aaaf82") - def test_ib_extra_pub_diff_unsolicited_passive_open_specific(self): - """Data-path: in-band, unsolicited/passive, open encryption, specific peer. + self.run_ib_data_path_test( + ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, + stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, + encr_type=self.ENCR_TYPE_OPEN, + use_peer_id=False, + pub_on_both=True, + pub_on_both_same=True) + + @test_tracker_info(uuid="7a32f439-d745-4716-a75e-b54109aaaf82") + def test_ib_extra_pub_diff_unsolicited_passive_open_specific(self): + """Data-path: in-band, unsolicited/passive, open encryption, specific peer. Configuration contains a publisher (for a different service) running on *both* devices. Verifies end-to-end discovery + data-path creation. """ - self.run_ib_data_path_test( - ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, - stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, - encr_type=self.ENCR_TYPE_OPEN, - use_peer_id=True, - pub_on_both=True, - pub_on_both_same=False) - - @test_tracker_info(uuid="a14ddc66-88fd-4b49-ab37-225533867c63") - def test_ib_extra_pub_diff_unsolicited_passive_open_any(self): - """Data-path: in-band, unsolicited/passive, open encryption, any peer. + self.run_ib_data_path_test( + ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, + stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, + encr_type=self.ENCR_TYPE_OPEN, + use_peer_id=True, + pub_on_both=True, + pub_on_both_same=False) + + @test_tracker_info(uuid="a14ddc66-88fd-4b49-ab37-225533867c63") + def test_ib_extra_pub_diff_unsolicited_passive_open_any(self): + """Data-path: in-band, unsolicited/passive, open encryption, any peer. Configuration contains a publisher (for a different service) running on *both* devices. Verifies end-to-end discovery + data-path creation. """ - self.run_ib_data_path_test( - ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, - stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, - encr_type=self.ENCR_TYPE_OPEN, - use_peer_id=False, - pub_on_both=True, - pub_on_both_same=False) - - ####################################### - # Positive Out-of-Band (OOB) tests key: - # - # names is: test_oob_<encr_type>_<peer_spec> - # where: - # - # encr_type: Encryption type: open, passphrase - # peer_spec: Peer specification method: any or specific - # - # Optionally set up an extra discovery session to test coexistence. If so - # add "ib_coex" to test name. - # - # Note: Out-of-Band means using a non-Wi-Fi Aware mechanism for discovery and - # exchange of MAC addresses and then Wi-Fi Aware for data-path. - ####################################### - - @test_tracker_info(uuid="7db17d8c-1dce-4084-b695-215bbcfe7d41") - def test_oob_open_specific(self): - """Data-path: out-of-band, open encryption, specific peer + self.run_ib_data_path_test( + ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, + stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, + encr_type=self.ENCR_TYPE_OPEN, + use_peer_id=False, + pub_on_both=True, + pub_on_both_same=False) + + ####################################### + # Positive Out-of-Band (OOB) tests key: + # + # names is: test_oob_<encr_type>_<peer_spec> + # where: + # + # encr_type: Encryption type: open, passphrase + # peer_spec: Peer specification method: any or specific + # + # Optionally set up an extra discovery session to test coexistence. If so + # add "ib_coex" to test name. + # + # Note: Out-of-Band means using a non-Wi-Fi Aware mechanism for discovery and + # exchange of MAC addresses and then Wi-Fi Aware for data-path. + ####################################### + + @test_tracker_info(uuid="7db17d8c-1dce-4084-b695-215bbcfe7d41") + def test_oob_open_specific(self): + """Data-path: out-of-band, open encryption, specific peer Verifies end-to-end discovery + data-path creation. """ - self.run_oob_data_path_test( - encr_type=self.ENCR_TYPE_OPEN, - use_peer_id=True) + self.run_oob_data_path_test( + encr_type=self.ENCR_TYPE_OPEN, use_peer_id=True) - @test_tracker_info(uuid="ad416d89-cb95-4a07-8d29-ee213117450b") - def test_oob_open_any(self): - """Data-path: out-of-band, open encryption, any peer + @test_tracker_info(uuid="ad416d89-cb95-4a07-8d29-ee213117450b") + def test_oob_open_any(self): + """Data-path: out-of-band, open encryption, any peer Verifies end-to-end discovery + data-path creation. """ - self.run_oob_data_path_test( - encr_type=self.ENCR_TYPE_OPEN, - use_peer_id=False) + self.run_oob_data_path_test( + encr_type=self.ENCR_TYPE_OPEN, use_peer_id=False) - @test_tracker_info(uuid="74937a3a-d524-43e2-8979-4449271cab52") - def test_oob_passphrase_specific(self): - """Data-path: out-of-band, passphrase, specific peer + @test_tracker_info(uuid="74937a3a-d524-43e2-8979-4449271cab52") + def test_oob_passphrase_specific(self): + """Data-path: out-of-band, passphrase, specific peer Verifies end-to-end discovery + data-path creation. """ - self.run_oob_data_path_test( - encr_type=self.ENCR_TYPE_PASSPHRASE, - use_peer_id=True) + self.run_oob_data_path_test( + encr_type=self.ENCR_TYPE_PASSPHRASE, use_peer_id=True) - @test_tracker_info(uuid="afcbdc7e-d3a9-465b-b1da-ce2e42e3941e") - def test_oob_passphrase_any(self): - """Data-path: out-of-band, passphrase, any peer + @test_tracker_info(uuid="afcbdc7e-d3a9-465b-b1da-ce2e42e3941e") + def test_oob_passphrase_any(self): + """Data-path: out-of-band, passphrase, any peer Verifies end-to-end discovery + data-path creation. """ - self.run_oob_data_path_test( - encr_type=self.ENCR_TYPE_PASSPHRASE, - use_peer_id=False) + self.run_oob_data_path_test( + encr_type=self.ENCR_TYPE_PASSPHRASE, use_peer_id=False) - @test_tracker_info(uuid="0d095031-160a-4537-aab5-41b6ad5d55f8") - def test_oob_pmk_specific(self): - """Data-path: out-of-band, PMK, specific peer + @test_tracker_info(uuid="0d095031-160a-4537-aab5-41b6ad5d55f8") + def test_oob_pmk_specific(self): + """Data-path: out-of-band, PMK, specific peer Verifies end-to-end discovery + data-path creation. """ - self.run_oob_data_path_test( - encr_type=self.ENCR_TYPE_PMK, - use_peer_id=True) + self.run_oob_data_path_test( + encr_type=self.ENCR_TYPE_PMK, use_peer_id=True) - @test_tracker_info(uuid="e45477bd-66cc-4eb7-88dd-4518c8aa2a74") - def test_oob_pmk_any(self): - """Data-path: out-of-band, PMK, any peer + @test_tracker_info(uuid="e45477bd-66cc-4eb7-88dd-4518c8aa2a74") + def test_oob_pmk_any(self): + """Data-path: out-of-band, PMK, any peer Verifies end-to-end discovery + data-path creation. """ - self.run_oob_data_path_test( - encr_type=self.ENCR_TYPE_PMK, - use_peer_id=False) + self.run_oob_data_path_test( + encr_type=self.ENCR_TYPE_PMK, use_peer_id=False) - @test_tracker_info(uuid="dd464f24-b404-4eea-955c-d10c9e8adefc") - def test_oob_ib_coex_open_specific(self): - """Data-path: out-of-band, open encryption, specific peer - in-band coex: + @test_tracker_info(uuid="dd464f24-b404-4eea-955c-d10c9e8adefc") + def test_oob_ib_coex_open_specific(self): + """Data-path: out-of-band, open encryption, specific peer - in-band coex: set up a concurrent discovery session to verify no impact. The session consists of Publisher on both ends, and a Subscriber on the Responder. Verifies end-to-end discovery + data-path creation. """ - self.run_oob_data_path_test( - encr_type=self.ENCR_TYPE_OPEN, - use_peer_id=True, - setup_discovery_sessions=True) - - @test_tracker_info(uuid="088fcd3a-b015-4179-a9a5-91f782b03e3b") - def test_oob_ib_coex_open_any(self): - """Data-path: out-of-band, open encryption, any peer - in-band coex: + self.run_oob_data_path_test( + encr_type=self.ENCR_TYPE_OPEN, + use_peer_id=True, + setup_discovery_sessions=True) + + @test_tracker_info(uuid="088fcd3a-b015-4179-a9a5-91f782b03e3b") + def test_oob_ib_coex_open_any(self): + """Data-path: out-of-band, open encryption, any peer - in-band coex: set up a concurrent discovery session to verify no impact. The session consists of Publisher on both ends, and a Subscriber on the Responder. Verifies end-to-end discovery + data-path creation. """ - self.run_oob_data_path_test( - encr_type=self.ENCR_TYPE_OPEN, - use_peer_id=False, - setup_discovery_sessions=True) + self.run_oob_data_path_test( + encr_type=self.ENCR_TYPE_OPEN, + use_peer_id=False, + setup_discovery_sessions=True) - ############################################################## + ############################################################## - @test_tracker_info(uuid="1c2c9805-dc1e-43b5-a1b8-315e8c9a4337") - def test_passphrase_min(self): - """Data-path: minimum passphrase length + @test_tracker_info(uuid="1c2c9805-dc1e-43b5-a1b8-315e8c9a4337") + def test_passphrase_min(self): + """Data-path: minimum passphrase length Use in-band, unsolicited/passive, any peer combination """ - self.run_ib_data_path_test(ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, - stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, - encr_type=self.ENCR_TYPE_PASSPHRASE, - use_peer_id=False, - passphrase_to_use=self.PASSPHRASE_MIN) + self.run_ib_data_path_test( + ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, + stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, + encr_type=self.ENCR_TYPE_PASSPHRASE, + use_peer_id=False, + passphrase_to_use=self.PASSPHRASE_MIN) - @test_tracker_info(uuid="e696e2b9-87a9-4521-b337-61b9efaa2057") - def test_passphrase_max(self): - """Data-path: maximum passphrase length + @test_tracker_info(uuid="e696e2b9-87a9-4521-b337-61b9efaa2057") + def test_passphrase_max(self): + """Data-path: maximum passphrase length Use in-band, unsolicited/passive, any peer combination """ - self.run_ib_data_path_test(ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, - stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, - encr_type=self.ENCR_TYPE_PASSPHRASE, - use_peer_id=False, - passphrase_to_use=self.PASSPHRASE_MAX) - - @test_tracker_info(uuid="533cd44c-ff30-4283-ac28-f71fd7b4f02d") - def test_negative_mismatch_publisher_peer_id(self): - """Data-path: failure when publisher peer ID is mismatched""" - self.run_mismatched_ib_data_path_test(pub_mismatch=True, sub_mismatch=False) - - @test_tracker_info(uuid="682f275e-722a-4f8b-85e7-0dcea9d25532") - def test_negative_mismatch_subscriber_peer_id(self): - """Data-path: failure when subscriber peer ID is mismatched""" - self.run_mismatched_ib_data_path_test(pub_mismatch=False, sub_mismatch=True) - - @test_tracker_info(uuid="7fa82796-7fc9-4d9e-bbbb-84b751788943") - def test_negative_mismatch_init_mac(self): - """Data-path: failure when Initiator MAC address mismatch""" - self.run_mismatched_oob_data_path_test( - init_mismatch_mac=True, - resp_mismatch_mac=False) - - @test_tracker_info(uuid="edeae959-4644-44f9-8d41-bdeb5216954e") - def test_negative_mismatch_resp_mac(self): - """Data-path: failure when Responder MAC address mismatch""" - self.run_mismatched_oob_data_path_test( - init_mismatch_mac=False, - resp_mismatch_mac=True) - - @test_tracker_info(uuid="91f46949-c47f-49f9-a90f-6fae699613a7") - def test_negative_mismatch_passphrase(self): - """Data-path: failure when passphrases mismatch""" - self.run_mismatched_oob_data_path_test( - init_encr_type=self.ENCR_TYPE_PASSPHRASE, - resp_encr_type=self.ENCR_TYPE_PASSPHRASE) - - @test_tracker_info(uuid="01c49c2e-dc92-4a27-bb47-c4fc67617c23") - def test_negative_mismatch_pmk(self): - """Data-path: failure when PMK mismatch""" - self.run_mismatched_oob_data_path_test( - init_encr_type=self.ENCR_TYPE_PMK, - resp_encr_type=self.ENCR_TYPE_PMK) - - @test_tracker_info(uuid="4d651797-5fbb-408e-a4b6-a6e1944136da") - def test_negative_mismatch_open_passphrase(self): - """Data-path: failure when initiator is open, and responder passphrase""" - self.run_mismatched_oob_data_path_test( - init_encr_type=self.ENCR_TYPE_OPEN, - resp_encr_type=self.ENCR_TYPE_PASSPHRASE) - - @test_tracker_info(uuid="1ae697f4-5987-4187-aeef-1e22d07d4a7c") - def test_negative_mismatch_open_pmk(self): - """Data-path: failure when initiator is open, and responder PMK""" - self.run_mismatched_oob_data_path_test( - init_encr_type=self.ENCR_TYPE_OPEN, - resp_encr_type=self.ENCR_TYPE_PMK) - - @test_tracker_info(uuid="f027b1cc-0e7a-4075-b880-5e64b288afbd") - def test_negative_mismatch_pmk_passphrase(self): - """Data-path: failure when initiator is pmk, and responder passphrase""" - self.run_mismatched_oob_data_path_test( - init_encr_type=self.ENCR_TYPE_PMK, - resp_encr_type=self.ENCR_TYPE_PASSPHRASE) - - @test_tracker_info(uuid="0819bbd4-72ae-49c4-bd46-5448db2b0a06") - def test_negative_mismatch_passphrase_open(self): - """Data-path: failure when initiator is passphrase, and responder open""" - self.run_mismatched_oob_data_path_test( - init_encr_type=self.ENCR_TYPE_PASSPHRASE, - resp_encr_type=self.ENCR_TYPE_OPEN) - - @test_tracker_info(uuid="7ef24f62-8e6b-4732-88a3-80a43584dda4") - def test_negative_mismatch_pmk_open(self): - """Data-path: failure when initiator is PMK, and responder open""" - self.run_mismatched_oob_data_path_test( - init_encr_type=self.ENCR_TYPE_PMK, - resp_encr_type=self.ENCR_TYPE_OPEN) - - @test_tracker_info(uuid="7b9c9efc-1c06-465e-8a5e-d6a22ac1da97") - def test_negative_mismatch_passphrase_pmk(self): - """Data-path: failure when initiator is passphrase, and responder pmk""" - self.run_mismatched_oob_data_path_test( - init_encr_type=self.ENCR_TYPE_PASSPHRASE, - resp_encr_type=self.ENCR_TYPE_OPEN) - - - ########################################################################## - - def wait_for_request_responses(self, dut, req_keys, aware_ifs): - """Wait for network request confirmation for all request keys. + self.run_ib_data_path_test( + ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, + stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, + encr_type=self.ENCR_TYPE_PASSPHRASE, + use_peer_id=False, + passphrase_to_use=self.PASSPHRASE_MAX) + + @test_tracker_info(uuid="533cd44c-ff30-4283-ac28-f71fd7b4f02d") + def test_negative_mismatch_publisher_peer_id(self): + """Data-path: failure when publisher peer ID is mismatched""" + self.run_mismatched_ib_data_path_test( + pub_mismatch=True, sub_mismatch=False) + + @test_tracker_info(uuid="682f275e-722a-4f8b-85e7-0dcea9d25532") + def test_negative_mismatch_subscriber_peer_id(self): + """Data-path: failure when subscriber peer ID is mismatched""" + self.run_mismatched_ib_data_path_test( + pub_mismatch=False, sub_mismatch=True) + + @test_tracker_info(uuid="7fa82796-7fc9-4d9e-bbbb-84b751788943") + def test_negative_mismatch_init_mac(self): + """Data-path: failure when Initiator MAC address mismatch""" + self.run_mismatched_oob_data_path_test( + init_mismatch_mac=True, resp_mismatch_mac=False) + + @test_tracker_info(uuid="edeae959-4644-44f9-8d41-bdeb5216954e") + def test_negative_mismatch_resp_mac(self): + """Data-path: failure when Responder MAC address mismatch""" + self.run_mismatched_oob_data_path_test( + init_mismatch_mac=False, resp_mismatch_mac=True) + + @test_tracker_info(uuid="91f46949-c47f-49f9-a90f-6fae699613a7") + def test_negative_mismatch_passphrase(self): + """Data-path: failure when passphrases mismatch""" + self.run_mismatched_oob_data_path_test( + init_encr_type=self.ENCR_TYPE_PASSPHRASE, + resp_encr_type=self.ENCR_TYPE_PASSPHRASE) + + @test_tracker_info(uuid="01c49c2e-dc92-4a27-bb47-c4fc67617c23") + def test_negative_mismatch_pmk(self): + """Data-path: failure when PMK mismatch""" + self.run_mismatched_oob_data_path_test( + init_encr_type=self.ENCR_TYPE_PMK, + resp_encr_type=self.ENCR_TYPE_PMK) + + @test_tracker_info(uuid="4d651797-5fbb-408e-a4b6-a6e1944136da") + def test_negative_mismatch_open_passphrase(self): + """Data-path: failure when initiator is open, and responder passphrase""" + self.run_mismatched_oob_data_path_test( + init_encr_type=self.ENCR_TYPE_OPEN, + resp_encr_type=self.ENCR_TYPE_PASSPHRASE) + + @test_tracker_info(uuid="1ae697f4-5987-4187-aeef-1e22d07d4a7c") + def test_negative_mismatch_open_pmk(self): + """Data-path: failure when initiator is open, and responder PMK""" + self.run_mismatched_oob_data_path_test( + init_encr_type=self.ENCR_TYPE_OPEN, + resp_encr_type=self.ENCR_TYPE_PMK) + + @test_tracker_info(uuid="f027b1cc-0e7a-4075-b880-5e64b288afbd") + def test_negative_mismatch_pmk_passphrase(self): + """Data-path: failure when initiator is pmk, and responder passphrase""" + self.run_mismatched_oob_data_path_test( + init_encr_type=self.ENCR_TYPE_PMK, + resp_encr_type=self.ENCR_TYPE_PASSPHRASE) + + @test_tracker_info(uuid="0819bbd4-72ae-49c4-bd46-5448db2b0a06") + def test_negative_mismatch_passphrase_open(self): + """Data-path: failure when initiator is passphrase, and responder open""" + self.run_mismatched_oob_data_path_test( + init_encr_type=self.ENCR_TYPE_PASSPHRASE, + resp_encr_type=self.ENCR_TYPE_OPEN) + + @test_tracker_info(uuid="7ef24f62-8e6b-4732-88a3-80a43584dda4") + def test_negative_mismatch_pmk_open(self): + """Data-path: failure when initiator is PMK, and responder open""" + self.run_mismatched_oob_data_path_test( + init_encr_type=self.ENCR_TYPE_PMK, + resp_encr_type=self.ENCR_TYPE_OPEN) + + @test_tracker_info(uuid="7b9c9efc-1c06-465e-8a5e-d6a22ac1da97") + def test_negative_mismatch_passphrase_pmk(self): + """Data-path: failure when initiator is passphrase, and responder pmk""" + self.run_mismatched_oob_data_path_test( + init_encr_type=self.ENCR_TYPE_PASSPHRASE, + resp_encr_type=self.ENCR_TYPE_OPEN) + + ########################################################################## + + def wait_for_request_responses(self, dut, req_keys, aware_ifs): + """Wait for network request confirmation for all request keys. Args: dut: Device under test req_keys: (in) A list of the network requests aware_ifs: (out) A list into which to append the network interface """ - num_events = 0 - while num_events != len(req_keys): - event = autils.wait_for_event(dut, cconsts.EVENT_NETWORK_CALLBACK, - timeout=autils.EVENT_NDP_TIMEOUT) - if (event["data"][cconsts.NETWORK_CB_KEY_EVENT] == - cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED): - if event["data"][cconsts.NETWORK_CB_KEY_ID] in req_keys: - num_events = num_events + 1 - aware_ifs.append(event["data"][cconsts.NETWORK_CB_KEY_INTERFACE_NAME]) - else: - self.log.info("Received an unexpected connectivity, the revoked " + num_events = 0 + while num_events != len(req_keys): + event = autils.wait_for_event( + dut, + cconsts.EVENT_NETWORK_CALLBACK, + timeout=autils.EVENT_NDP_TIMEOUT) + if (event["data"][cconsts.NETWORK_CB_KEY_EVENT] == + cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED): + if event["data"][cconsts.NETWORK_CB_KEY_ID] in req_keys: + num_events = num_events + 1 + aware_ifs.append( + event["data"][cconsts.NETWORK_CB_KEY_INTERFACE_NAME]) + else: + self.log.info( + "Received an unexpected connectivity, the revoked " "network request probably went through -- %s", event) - @test_tracker_info(uuid="2e325e2b-d552-4890-b470-20b40284395d") - def test_multiple_identical_networks(self): - """Validate that creating multiple networks between 2 devices, each network + @test_tracker_info(uuid="2e325e2b-d552-4890-b470-20b40284395d") + def test_multiple_identical_networks(self): + """Validate that creating multiple networks between 2 devices, each network with identical configuration is supported over a single NDP. Verify that the interface and IPv6 address is the same for all networks. """ - init_dut = self.android_devices[0] - init_dut.pretty_name = "Initiator" - resp_dut = self.android_devices[1] - resp_dut.pretty_name = "Responder" - - N = 2 # first iteration (must be 2 to give us a chance to cancel the first) - M = 5 # second iteration - - init_ids = [] - resp_ids = [] - - # Initiator+Responder: attach and wait for confirmation & identity - # create N+M sessions to be used in the different (but identical) NDPs - for i in range(N + M): - id, init_mac = autils.attach_with_identity(init_dut) - init_ids.append(id) - id, resp_mac = autils.attach_with_identity(resp_dut) - resp_ids.append(id) - - # wait for for devices to synchronize with each other - there are no other - # mechanisms to make sure this happens for OOB discovery (except retrying - # to execute the data-path request) - time.sleep(autils.WAIT_FOR_CLUSTER) - - resp_req_keys = [] - init_req_keys = [] - resp_aware_ifs = [] - init_aware_ifs = [] - - # issue N quick requests for identical NDPs - without waiting for result - # tests whether pre-setup multiple NDP procedure - for i in range(N): - # Responder: request network - resp_req_keys.append(autils.request_network( - resp_dut, - resp_dut.droid.wifiAwareCreateNetworkSpecifierOob( - resp_ids[i], aconsts.DATA_PATH_RESPONDER, init_mac, None))) - - # Initiator: request network - init_req_keys.append(autils.request_network( - init_dut, - init_dut.droid.wifiAwareCreateNetworkSpecifierOob( - init_ids[i], aconsts.DATA_PATH_INITIATOR, resp_mac, None))) - - # remove the first request (hopefully before completed) testing that NDP - # is still created - resp_dut.droid.connectivityUnregisterNetworkCallback(resp_req_keys[0]) - resp_req_keys.remove(resp_req_keys[0]) - init_dut.droid.connectivityUnregisterNetworkCallback(init_req_keys[0]) - init_req_keys.remove(init_req_keys[0]) - - # wait for network formation for all initial requests - self.wait_for_request_responses(resp_dut, resp_req_keys, resp_aware_ifs) - self.wait_for_request_responses(init_dut, init_req_keys, init_aware_ifs) - - # issue M more requests for the same NDPs - tests post-setup multiple NDP - for i in range(M): - # Responder: request network - resp_req_keys.append(autils.request_network( - resp_dut, - resp_dut.droid.wifiAwareCreateNetworkSpecifierOob( - resp_ids[N + i], aconsts.DATA_PATH_RESPONDER, init_mac, None))) - - # Initiator: request network - init_req_keys.append(autils.request_network( - init_dut, - init_dut.droid.wifiAwareCreateNetworkSpecifierOob( - init_ids[N + i], aconsts.DATA_PATH_INITIATOR, resp_mac, None))) - - # wait for network formation for all subsequent requests - self.wait_for_request_responses(resp_dut, resp_req_keys[N - 1:], - resp_aware_ifs) - self.wait_for_request_responses(init_dut, init_req_keys[N - 1:], - init_aware_ifs) - - # determine whether all interfaces are identical (single NDP) - can't really - # test the IPv6 address since it is not part of the callback event - it is - # simply obtained from the system (so we'll always get the same for the same - # interface) - init_aware_ifs = list(set(init_aware_ifs)) - resp_aware_ifs = list(set(resp_aware_ifs)) - - self.log.info("Interface names: I=%s, R=%s", init_aware_ifs, resp_aware_ifs) - self.log.info("Initiator requests: %s", init_req_keys) - self.log.info("Responder requests: %s", resp_req_keys) - - asserts.assert_equal( - len(init_aware_ifs), 1, "Multiple initiator interfaces") - asserts.assert_equal( - len(resp_aware_ifs), 1, "Multiple responder interfaces") - - self.log.info("Interface IPv6 (using ifconfig): I=%s, R=%s", - autils.get_ipv6_addr(init_dut, init_aware_ifs[0]), - autils.get_ipv6_addr(resp_dut, resp_aware_ifs[0])) - - for i in range(init_dut.aware_capabilities[aconsts.CAP_MAX_NDI_INTERFACES]): - if_name = "%s%d" % (aconsts.AWARE_NDI_PREFIX, i) - init_ipv6 = autils.get_ipv6_addr(init_dut, if_name) - resp_ipv6 = autils.get_ipv6_addr(resp_dut, if_name) - - asserts.assert_equal( - init_ipv6 is None, if_name not in init_aware_ifs, - "Initiator interface %s in unexpected state" % if_name) - asserts.assert_equal( - resp_ipv6 is None, if_name not in resp_aware_ifs, - "Responder interface %s in unexpected state" % if_name) - - # release requests - for resp_req_key in resp_req_keys: - resp_dut.droid.connectivityUnregisterNetworkCallback(resp_req_key) - for init_req_key in init_req_keys: - init_dut.droid.connectivityUnregisterNetworkCallback(init_req_key) - - def test_identical_network_from_both_sides(self): - """Validate that requesting two identical NDPs (Open) each being initiated + init_dut = self.android_devices[0] + init_dut.pretty_name = "Initiator" + resp_dut = self.android_devices[1] + resp_dut.pretty_name = "Responder" + + N = 2 # first iteration (must be 2 to give us a chance to cancel the first) + M = 5 # second iteration + + init_ids = [] + resp_ids = [] + + # Initiator+Responder: attach and wait for confirmation & identity + # create N+M sessions to be used in the different (but identical) NDPs + for i in range(N + M): + id, init_mac = autils.attach_with_identity(init_dut) + init_ids.append(id) + id, resp_mac = autils.attach_with_identity(resp_dut) + resp_ids.append(id) + + # wait for for devices to synchronize with each other - there are no other + # mechanisms to make sure this happens for OOB discovery (except retrying + # to execute the data-path request) + time.sleep(autils.WAIT_FOR_CLUSTER) + + resp_req_keys = [] + init_req_keys = [] + resp_aware_ifs = [] + init_aware_ifs = [] + + # issue N quick requests for identical NDPs - without waiting for result + # tests whether pre-setup multiple NDP procedure + for i in range(N): + # Responder: request network + resp_req_keys.append( + autils.request_network( + resp_dut, + resp_dut.droid.wifiAwareCreateNetworkSpecifierOob( + resp_ids[i], aconsts.DATA_PATH_RESPONDER, init_mac, + None))) + + # Initiator: request network + init_req_keys.append( + autils.request_network( + init_dut, + init_dut.droid.wifiAwareCreateNetworkSpecifierOob( + init_ids[i], aconsts.DATA_PATH_INITIATOR, resp_mac, + None))) + + # remove the first request (hopefully before completed) testing that NDP + # is still created + resp_dut.droid.connectivityUnregisterNetworkCallback(resp_req_keys[0]) + resp_req_keys.remove(resp_req_keys[0]) + init_dut.droid.connectivityUnregisterNetworkCallback(init_req_keys[0]) + init_req_keys.remove(init_req_keys[0]) + + # wait for network formation for all initial requests + self.wait_for_request_responses(resp_dut, resp_req_keys, + resp_aware_ifs) + self.wait_for_request_responses(init_dut, init_req_keys, + init_aware_ifs) + + # issue M more requests for the same NDPs - tests post-setup multiple NDP + for i in range(M): + # Responder: request network + resp_req_keys.append( + autils.request_network( + resp_dut, + resp_dut.droid.wifiAwareCreateNetworkSpecifierOob( + resp_ids[N + i], aconsts.DATA_PATH_RESPONDER, init_mac, + None))) + + # Initiator: request network + init_req_keys.append( + autils.request_network( + init_dut, + init_dut.droid.wifiAwareCreateNetworkSpecifierOob( + init_ids[N + i], aconsts.DATA_PATH_INITIATOR, resp_mac, + None))) + + # wait for network formation for all subsequent requests + self.wait_for_request_responses(resp_dut, resp_req_keys[N - 1:], + resp_aware_ifs) + self.wait_for_request_responses(init_dut, init_req_keys[N - 1:], + init_aware_ifs) + + # determine whether all interfaces are identical (single NDP) - can't really + # test the IPv6 address since it is not part of the callback event - it is + # simply obtained from the system (so we'll always get the same for the same + # interface) + init_aware_ifs = list(set(init_aware_ifs)) + resp_aware_ifs = list(set(resp_aware_ifs)) + + self.log.info("Interface names: I=%s, R=%s", init_aware_ifs, + resp_aware_ifs) + self.log.info("Initiator requests: %s", init_req_keys) + self.log.info("Responder requests: %s", resp_req_keys) + + asserts.assert_equal( + len(init_aware_ifs), 1, "Multiple initiator interfaces") + asserts.assert_equal( + len(resp_aware_ifs), 1, "Multiple responder interfaces") + + self.log.info("Interface IPv6 (using ifconfig): I=%s, R=%s", + autils.get_ipv6_addr(init_dut, init_aware_ifs[0]), + autils.get_ipv6_addr(resp_dut, resp_aware_ifs[0])) + + for i in range( + init_dut.aware_capabilities[aconsts.CAP_MAX_NDI_INTERFACES]): + if_name = "%s%d" % (aconsts.AWARE_NDI_PREFIX, i) + init_ipv6 = autils.get_ipv6_addr(init_dut, if_name) + resp_ipv6 = autils.get_ipv6_addr(resp_dut, if_name) + + asserts.assert_equal( + init_ipv6 is None, if_name not in init_aware_ifs, + "Initiator interface %s in unexpected state" % if_name) + asserts.assert_equal( + resp_ipv6 is None, if_name not in resp_aware_ifs, + "Responder interface %s in unexpected state" % if_name) + + # release requests + for resp_req_key in resp_req_keys: + resp_dut.droid.connectivityUnregisterNetworkCallback(resp_req_key) + for init_req_key in init_req_keys: + init_dut.droid.connectivityUnregisterNetworkCallback(init_req_key) + + def test_identical_network_from_both_sides(self): + """Validate that requesting two identical NDPs (Open) each being initiated from a different side, results in the same/single NDP. Verify that the interface and IPv6 address is the same for all networks. """ - dut1 = self.android_devices[0] - dut2 = self.android_devices[1] - - id1, mac1 = autils.attach_with_identity(dut1) - id2, mac2 = autils.attach_with_identity(dut2) - - # wait for for devices to synchronize with each other - there are no other - # mechanisms to make sure this happens for OOB discovery (except retrying - # to execute the data-path request) - time.sleep(autils.WAIT_FOR_CLUSTER) - - # first NDP: DUT1 (Init) -> DUT2 (Resp) - req_a_resp = autils.request_network(dut2, - dut2.droid.wifiAwareCreateNetworkSpecifierOob( - id2, aconsts.DATA_PATH_RESPONDER, - mac1)) - - req_a_init = autils.request_network(dut1, - dut1.droid.wifiAwareCreateNetworkSpecifierOob( - id1, aconsts.DATA_PATH_INITIATOR, - mac2)) - - req_a_resp_event = autils.wait_for_event_with_keys( - dut2, cconsts.EVENT_NETWORK_CALLBACK, - autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, req_a_resp)) - req_a_init_event = autils.wait_for_event_with_keys( - dut1, cconsts.EVENT_NETWORK_CALLBACK, - autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, req_a_init)) - - req_a_if_resp = req_a_resp_event["data"][ - cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - req_a_if_init = req_a_init_event["data"][ - cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - self.log.info("Interface names for A: I=%s, R=%s", req_a_if_init, - req_a_if_resp) - - req_a_ipv6_resp = \ - dut2.droid.connectivityGetLinkLocalIpv6Address(req_a_if_resp).split("%")[0] - req_a_ipv6_init = \ - dut1.droid.connectivityGetLinkLocalIpv6Address(req_a_if_init).split("%")[0] - self.log.info("Interface addresses (IPv6) for A: I=%s, R=%s", - req_a_ipv6_init, req_a_ipv6_resp) - - # second NDP: DUT2 (Init) -> DUT1 (Resp) - req_b_resp = autils.request_network(dut1, - dut1.droid.wifiAwareCreateNetworkSpecifierOob( - id1, aconsts.DATA_PATH_RESPONDER, - mac2)) - - req_b_init = autils.request_network(dut2, - dut2.droid.wifiAwareCreateNetworkSpecifierOob( - id2, aconsts.DATA_PATH_INITIATOR, - mac1)) - - req_b_resp_event = autils.wait_for_event_with_keys( - dut1, cconsts.EVENT_NETWORK_CALLBACK, - autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, req_b_resp)) - req_b_init_event = autils.wait_for_event_with_keys( - dut2, cconsts.EVENT_NETWORK_CALLBACK, - autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, req_b_init)) - - req_b_if_resp = req_b_resp_event["data"][ - cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - req_b_if_init = req_b_init_event["data"][ - cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - self.log.info("Interface names for B: I=%s, R=%s", req_b_if_init, - req_b_if_resp) - - req_b_ipv6_resp = \ - dut1.droid.connectivityGetLinkLocalIpv6Address(req_b_if_resp).split("%")[0] - req_b_ipv6_init = \ - dut2.droid.connectivityGetLinkLocalIpv6Address(req_b_if_init).split("%")[0] - self.log.info("Interface addresses (IPv6) for B: I=%s, R=%s", - req_b_ipv6_init, req_b_ipv6_resp) - - # validate equality of NDPs (using interface names & ipv6) - asserts.assert_equal(req_a_if_init, req_b_if_resp, - "DUT1 NDPs are on different interfaces") - asserts.assert_equal(req_a_if_resp, req_b_if_init, - "DUT2 NDPs are on different interfaces") - asserts.assert_equal(req_a_ipv6_init, req_b_ipv6_resp, - "DUT1 NDPs are using different IPv6 addresses") - asserts.assert_equal(req_a_ipv6_resp, req_b_ipv6_init, - "DUT2 NDPs are using different IPv6 addresses") - - # release requests - dut1.droid.connectivityUnregisterNetworkCallback(req_a_init) - dut1.droid.connectivityUnregisterNetworkCallback(req_b_resp) - dut2.droid.connectivityUnregisterNetworkCallback(req_a_resp) - dut2.droid.connectivityUnregisterNetworkCallback(req_b_init) - - ######################################################################## - - def run_multiple_ndi(self, sec_configs, flip_init_resp=False): - """Validate that the device can create and use multiple NDIs. + dut1 = self.android_devices[0] + dut2 = self.android_devices[1] + + id1, mac1 = autils.attach_with_identity(dut1) + id2, mac2 = autils.attach_with_identity(dut2) + + # wait for for devices to synchronize with each other - there are no other + # mechanisms to make sure this happens for OOB discovery (except retrying + # to execute the data-path request) + time.sleep(autils.WAIT_FOR_CLUSTER) + + # first NDP: DUT1 (Init) -> DUT2 (Resp) + req_a_resp = autils.request_network( + dut2, + dut2.droid.wifiAwareCreateNetworkSpecifierOob( + id2, aconsts.DATA_PATH_RESPONDER, mac1)) + + req_a_init = autils.request_network( + dut1, + dut1.droid.wifiAwareCreateNetworkSpecifierOob( + id1, aconsts.DATA_PATH_INITIATOR, mac2)) + + req_a_resp_event = autils.wait_for_event_with_keys( + dut2, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT, + (cconsts.NETWORK_CB_KEY_EVENT, + cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), + (cconsts.NETWORK_CB_KEY_ID, req_a_resp)) + req_a_init_event = autils.wait_for_event_with_keys( + dut1, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT, + (cconsts.NETWORK_CB_KEY_EVENT, + cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), + (cconsts.NETWORK_CB_KEY_ID, req_a_init)) + + req_a_if_resp = req_a_resp_event["data"][ + cconsts.NETWORK_CB_KEY_INTERFACE_NAME] + req_a_if_init = req_a_init_event["data"][ + cconsts.NETWORK_CB_KEY_INTERFACE_NAME] + self.log.info("Interface names for A: I=%s, R=%s", req_a_if_init, + req_a_if_resp) + + req_a_ipv6_resp = \ + dut2.droid.connectivityGetLinkLocalIpv6Address(req_a_if_resp).split("%")[0] + req_a_ipv6_init = \ + dut1.droid.connectivityGetLinkLocalIpv6Address(req_a_if_init).split("%")[0] + self.log.info("Interface addresses (IPv6) for A: I=%s, R=%s", + req_a_ipv6_init, req_a_ipv6_resp) + + # second NDP: DUT2 (Init) -> DUT1 (Resp) + req_b_resp = autils.request_network( + dut1, + dut1.droid.wifiAwareCreateNetworkSpecifierOob( + id1, aconsts.DATA_PATH_RESPONDER, mac2)) + + req_b_init = autils.request_network( + dut2, + dut2.droid.wifiAwareCreateNetworkSpecifierOob( + id2, aconsts.DATA_PATH_INITIATOR, mac1)) + + req_b_resp_event = autils.wait_for_event_with_keys( + dut1, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT, + (cconsts.NETWORK_CB_KEY_EVENT, + cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), + (cconsts.NETWORK_CB_KEY_ID, req_b_resp)) + req_b_init_event = autils.wait_for_event_with_keys( + dut2, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT, + (cconsts.NETWORK_CB_KEY_EVENT, + cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), + (cconsts.NETWORK_CB_KEY_ID, req_b_init)) + + req_b_if_resp = req_b_resp_event["data"][ + cconsts.NETWORK_CB_KEY_INTERFACE_NAME] + req_b_if_init = req_b_init_event["data"][ + cconsts.NETWORK_CB_KEY_INTERFACE_NAME] + self.log.info("Interface names for B: I=%s, R=%s", req_b_if_init, + req_b_if_resp) + + req_b_ipv6_resp = \ + dut1.droid.connectivityGetLinkLocalIpv6Address(req_b_if_resp).split("%")[0] + req_b_ipv6_init = \ + dut2.droid.connectivityGetLinkLocalIpv6Address(req_b_if_init).split("%")[0] + self.log.info("Interface addresses (IPv6) for B: I=%s, R=%s", + req_b_ipv6_init, req_b_ipv6_resp) + + # validate equality of NDPs (using interface names & ipv6) + asserts.assert_equal(req_a_if_init, req_b_if_resp, + "DUT1 NDPs are on different interfaces") + asserts.assert_equal(req_a_if_resp, req_b_if_init, + "DUT2 NDPs are on different interfaces") + asserts.assert_equal(req_a_ipv6_init, req_b_ipv6_resp, + "DUT1 NDPs are using different IPv6 addresses") + asserts.assert_equal(req_a_ipv6_resp, req_b_ipv6_init, + "DUT2 NDPs are using different IPv6 addresses") + + # release requests + dut1.droid.connectivityUnregisterNetworkCallback(req_a_init) + dut1.droid.connectivityUnregisterNetworkCallback(req_b_resp) + dut2.droid.connectivityUnregisterNetworkCallback(req_a_resp) + dut2.droid.connectivityUnregisterNetworkCallback(req_b_init) + + ######################################################################## + + def run_multiple_ndi(self, sec_configs, flip_init_resp=False): + """Validate that the device can create and use multiple NDIs. The security configuration can be: - None: open @@ -1214,281 +1258,279 @@ class DataPathTest(AwareBaseTest): between the 2 devices, otherwise same devices are always configured in the same role. """ - dut1 = self.android_devices[0] - dut2 = self.android_devices[1] - - asserts.skip_if(dut1.aware_capabilities[aconsts.CAP_MAX_NDI_INTERFACES] - < len(sec_configs) or - dut2.aware_capabilities[aconsts.CAP_MAX_NDI_INTERFACES] - < len(sec_configs), - "DUTs do not support enough NDIs") - - id1, mac1 = autils.attach_with_identity(dut1) - id2, mac2 = autils.attach_with_identity(dut2) - - # wait for for devices to synchronize with each other - there are no other - # mechanisms to make sure this happens for OOB discovery (except retrying - # to execute the data-path request) - time.sleep(autils.WAIT_FOR_CLUSTER) - - dut2_req_keys = [] - dut1_req_keys = [] - dut2_aware_ifs = [] - dut1_aware_ifs = [] - dut2_aware_ipv6 = [] - dut1_aware_ipv6 = [] - - dut2_type = aconsts.DATA_PATH_RESPONDER - dut1_type = aconsts.DATA_PATH_INITIATOR - dut2_is_responder = True - for sec in sec_configs: - if dut2_is_responder: - # DUT2 (Responder): request network - dut2_req_key = autils.request_network(dut2, - autils.get_network_specifier( - dut2, id2, - dut2_type, - mac1, sec)) - dut2_req_keys.append(dut2_req_key) - - # DUT1 (Initiator): request network - dut1_req_key = autils.request_network(dut1, - autils.get_network_specifier( - dut1, id1, - dut1_type, - mac2, sec)) - dut1_req_keys.append(dut1_req_key) - else: - # DUT1 (Responder): request network - dut1_req_key = autils.request_network(dut1, - autils.get_network_specifier( - dut1, id1, - dut1_type, - mac2, sec)) - dut1_req_keys.append(dut1_req_key) - - # DUT2 (Initiator): request network - dut2_req_key = autils.request_network(dut2, - autils.get_network_specifier( - dut2, id2, - dut2_type, - mac1, sec)) - dut2_req_keys.append(dut2_req_key) - - # Wait for network - dut1_net_event = autils.wait_for_event_with_keys( - dut1, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, dut1_req_key)) - dut2_net_event = autils.wait_for_event_with_keys( - dut2, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, dut2_req_key)) - - dut2_aware_if = dut2_net_event["data"][ - cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - dut1_aware_if = dut1_net_event["data"][ - cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - dut2_aware_ifs.append(dut2_aware_if) - dut1_aware_ifs.append(dut1_aware_if) - dut2_aware_ipv6.append(autils.get_ipv6_addr(dut2, dut2_aware_if)) - dut1_aware_ipv6.append(autils.get_ipv6_addr(dut1, dut1_aware_if)) - - if flip_init_resp: - if dut2_is_responder: - dut2_type = aconsts.DATA_PATH_INITIATOR - dut1_type = aconsts.DATA_PATH_RESPONDER - else: - dut2_type = aconsts.DATA_PATH_RESPONDER - dut1_type = aconsts.DATA_PATH_INITIATOR - dut2_is_responder = not dut2_is_responder - - # check that we are using 2 NDIs & that they have unique IPv6 addresses - dut1_aware_ifs = list(set(dut1_aware_ifs)) - dut2_aware_ifs = list(set(dut2_aware_ifs)) - dut1_aware_ipv6 = list(set(dut1_aware_ipv6)) - dut2_aware_ipv6 = list(set(dut2_aware_ipv6)) - - self.log.info("Interface names: DUT1=%s, DUT2=%s", dut1_aware_ifs, - dut2_aware_ifs) - self.log.info("IPv6 addresses: DUT1=%s, DUT2=%s", dut1_aware_ipv6, - dut2_aware_ipv6) - self.log.info("DUT1 requests: %s", dut1_req_keys) - self.log.info("DUT2 requests: %s", dut2_req_keys) - - asserts.assert_equal( - len(dut1_aware_ifs), len(sec_configs), "Multiple DUT1 interfaces") - asserts.assert_equal( - len(dut2_aware_ifs), len(sec_configs), "Multiple DUT2 interfaces") - asserts.assert_equal( - len(dut1_aware_ipv6), len(sec_configs), "Multiple DUT1 IPv6 addresses") - asserts.assert_equal( - len(dut2_aware_ipv6), len(sec_configs), "Multiple DUT2 IPv6 addresses") - - for i in range(len(sec_configs)): - if_name = "%s%d" % (aconsts.AWARE_NDI_PREFIX, i) - dut1_ipv6 = autils.get_ipv6_addr(dut1, if_name) - dut2_ipv6 = autils.get_ipv6_addr(dut2, if_name) - - asserts.assert_equal( - dut1_ipv6 is None, if_name not in dut1_aware_ifs, - "DUT1 interface %s in unexpected state" % if_name) - asserts.assert_equal( - dut2_ipv6 is None, if_name not in dut2_aware_ifs, - "DUT2 interface %s in unexpected state" % if_name) - - # release requests - for dut2_req_key in dut2_req_keys: - dut2.droid.connectivityUnregisterNetworkCallback(dut2_req_key) - for dut1_req_key in dut1_req_keys: - dut1.droid.connectivityUnregisterNetworkCallback(dut1_req_key) - - @test_tracker_info(uuid="2d728163-11cc-46ba-a973-c8e1e71397fc") - def test_multiple_ndi_open_passphrase(self): - """Verify that between 2 DUTs can create 2 NDPs with different security + dut1 = self.android_devices[0] + dut2 = self.android_devices[1] + + asserts.skip_if( + dut1.aware_capabilities[aconsts.CAP_MAX_NDI_INTERFACES] < + len(sec_configs) + or dut2.aware_capabilities[aconsts.CAP_MAX_NDI_INTERFACES] < + len(sec_configs), "DUTs do not support enough NDIs") + + id1, mac1 = autils.attach_with_identity(dut1) + id2, mac2 = autils.attach_with_identity(dut2) + + # wait for for devices to synchronize with each other - there are no other + # mechanisms to make sure this happens for OOB discovery (except retrying + # to execute the data-path request) + time.sleep(autils.WAIT_FOR_CLUSTER) + + dut2_req_keys = [] + dut1_req_keys = [] + dut2_aware_ifs = [] + dut1_aware_ifs = [] + dut2_aware_ipv6 = [] + dut1_aware_ipv6 = [] + + dut2_type = aconsts.DATA_PATH_RESPONDER + dut1_type = aconsts.DATA_PATH_INITIATOR + dut2_is_responder = True + for sec in sec_configs: + if dut2_is_responder: + # DUT2 (Responder): request network + dut2_req_key = autils.request_network( + dut2, + autils.get_network_specifier(dut2, id2, dut2_type, mac1, + sec)) + dut2_req_keys.append(dut2_req_key) + + # DUT1 (Initiator): request network + dut1_req_key = autils.request_network( + dut1, + autils.get_network_specifier(dut1, id1, dut1_type, mac2, + sec)) + dut1_req_keys.append(dut1_req_key) + else: + # DUT1 (Responder): request network + dut1_req_key = autils.request_network( + dut1, + autils.get_network_specifier(dut1, id1, dut1_type, mac2, + sec)) + dut1_req_keys.append(dut1_req_key) + + # DUT2 (Initiator): request network + dut2_req_key = autils.request_network( + dut2, + autils.get_network_specifier(dut2, id2, dut2_type, mac1, + sec)) + dut2_req_keys.append(dut2_req_key) + + # Wait for network + dut1_net_event = autils.wait_for_event_with_keys( + dut1, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT, + (cconsts.NETWORK_CB_KEY_EVENT, + cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), + (cconsts.NETWORK_CB_KEY_ID, dut1_req_key)) + dut2_net_event = autils.wait_for_event_with_keys( + dut2, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT, + (cconsts.NETWORK_CB_KEY_EVENT, + cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), + (cconsts.NETWORK_CB_KEY_ID, dut2_req_key)) + + dut2_aware_if = dut2_net_event["data"][ + cconsts.NETWORK_CB_KEY_INTERFACE_NAME] + dut1_aware_if = dut1_net_event["data"][ + cconsts.NETWORK_CB_KEY_INTERFACE_NAME] + dut2_aware_ifs.append(dut2_aware_if) + dut1_aware_ifs.append(dut1_aware_if) + dut2_aware_ipv6.append(autils.get_ipv6_addr(dut2, dut2_aware_if)) + dut1_aware_ipv6.append(autils.get_ipv6_addr(dut1, dut1_aware_if)) + + if flip_init_resp: + if dut2_is_responder: + dut2_type = aconsts.DATA_PATH_INITIATOR + dut1_type = aconsts.DATA_PATH_RESPONDER + else: + dut2_type = aconsts.DATA_PATH_RESPONDER + dut1_type = aconsts.DATA_PATH_INITIATOR + dut2_is_responder = not dut2_is_responder + + # check that we are using 2 NDIs & that they have unique IPv6 addresses + dut1_aware_ifs = list(set(dut1_aware_ifs)) + dut2_aware_ifs = list(set(dut2_aware_ifs)) + dut1_aware_ipv6 = list(set(dut1_aware_ipv6)) + dut2_aware_ipv6 = list(set(dut2_aware_ipv6)) + + self.log.info("Interface names: DUT1=%s, DUT2=%s", dut1_aware_ifs, + dut2_aware_ifs) + self.log.info("IPv6 addresses: DUT1=%s, DUT2=%s", dut1_aware_ipv6, + dut2_aware_ipv6) + self.log.info("DUT1 requests: %s", dut1_req_keys) + self.log.info("DUT2 requests: %s", dut2_req_keys) + + asserts.assert_equal( + len(dut1_aware_ifs), len(sec_configs), "Multiple DUT1 interfaces") + asserts.assert_equal( + len(dut2_aware_ifs), len(sec_configs), "Multiple DUT2 interfaces") + asserts.assert_equal( + len(dut1_aware_ipv6), len(sec_configs), + "Multiple DUT1 IPv6 addresses") + asserts.assert_equal( + len(dut2_aware_ipv6), len(sec_configs), + "Multiple DUT2 IPv6 addresses") + + for i in range(len(sec_configs)): + if_name = "%s%d" % (aconsts.AWARE_NDI_PREFIX, i) + dut1_ipv6 = autils.get_ipv6_addr(dut1, if_name) + dut2_ipv6 = autils.get_ipv6_addr(dut2, if_name) + + asserts.assert_equal( + dut1_ipv6 is None, if_name not in dut1_aware_ifs, + "DUT1 interface %s in unexpected state" % if_name) + asserts.assert_equal( + dut2_ipv6 is None, if_name not in dut2_aware_ifs, + "DUT2 interface %s in unexpected state" % if_name) + + # release requests + for dut2_req_key in dut2_req_keys: + dut2.droid.connectivityUnregisterNetworkCallback(dut2_req_key) + for dut1_req_key in dut1_req_keys: + dut1.droid.connectivityUnregisterNetworkCallback(dut1_req_key) + + @test_tracker_info(uuid="2d728163-11cc-46ba-a973-c8e1e71397fc") + def test_multiple_ndi_open_passphrase(self): + """Verify that between 2 DUTs can create 2 NDPs with different security configuration (one open, one using passphrase). The result should use two different NDIs""" - self.run_multiple_ndi([None, self.PASSPHRASE]) + self.run_multiple_ndi([None, self.PASSPHRASE]) - @test_tracker_info(uuid="5f2c32aa-20b2-41f0-8b1e-d0b68df73ada") - def test_multiple_ndi_open_pmk(self): - """Verify that between 2 DUTs can create 2 NDPs with different security + @test_tracker_info(uuid="5f2c32aa-20b2-41f0-8b1e-d0b68df73ada") + def test_multiple_ndi_open_pmk(self): + """Verify that between 2 DUTs can create 2 NDPs with different security configuration (one open, one using pmk). The result should use two different NDIs""" - self.run_multiple_ndi([None, self.PMK]) + self.run_multiple_ndi([None, self.PMK]) - @test_tracker_info(uuid="34467659-bcfb-40cd-ba25-7e50560fca63") - def test_multiple_ndi_passphrase_pmk(self): - """Verify that between 2 DUTs can create 2 NDPs with different security + @test_tracker_info(uuid="34467659-bcfb-40cd-ba25-7e50560fca63") + def test_multiple_ndi_passphrase_pmk(self): + """Verify that between 2 DUTs can create 2 NDPs with different security configuration (one using passphrase, one using pmk). The result should use two different NDIs""" - self.run_multiple_ndi([self.PASSPHRASE, self.PMK]) + self.run_multiple_ndi([self.PASSPHRASE, self.PMK]) - @test_tracker_info(uuid="d9194ce6-45b6-41b1-9cc8-ada79968966d") - def test_multiple_ndi_passphrases(self): - """Verify that between 2 DUTs can create 2 NDPs with different security + @test_tracker_info(uuid="d9194ce6-45b6-41b1-9cc8-ada79968966d") + def test_multiple_ndi_passphrases(self): + """Verify that between 2 DUTs can create 2 NDPs with different security configuration (using different passphrases). The result should use two different NDIs""" - self.run_multiple_ndi([self.PASSPHRASE, self.PASSPHRASE2]) + self.run_multiple_ndi([self.PASSPHRASE, self.PASSPHRASE2]) - @test_tracker_info(uuid="879df795-62d2-40d4-a862-bd46d8f7e67f") - def test_multiple_ndi_pmks(self): - """Verify that between 2 DUTs can create 2 NDPs with different security + @test_tracker_info(uuid="879df795-62d2-40d4-a862-bd46d8f7e67f") + def test_multiple_ndi_pmks(self): + """Verify that between 2 DUTs can create 2 NDPs with different security configuration (using different PMKS). The result should use two different NDIs""" - self.run_multiple_ndi([self.PMK, self.PMK2]) + self.run_multiple_ndi([self.PMK, self.PMK2]) - @test_tracker_info(uuid="397d380a-8e41-466e-9ccb-cf8f413d83ba") - def test_multiple_ndi_open_passphrase_flip(self): - """Verify that between 2 DUTs can create 2 NDPs with different security + @test_tracker_info(uuid="397d380a-8e41-466e-9ccb-cf8f413d83ba") + def test_multiple_ndi_open_passphrase_flip(self): + """Verify that between 2 DUTs can create 2 NDPs with different security configuration (one open, one using passphrase). The result should use two different NDIs. Flip Initiator and Responder roles. """ - self.run_multiple_ndi([None, self.PASSPHRASE], flip_init_resp=True) + self.run_multiple_ndi([None, self.PASSPHRASE], flip_init_resp=True) - @test_tracker_info(uuid="b3a4300b-1514-4cb8-a814-9c2baa449700") - def test_multiple_ndi_open_pmk_flip(self): - """Verify that between 2 DUTs can create 2 NDPs with different security + @test_tracker_info(uuid="b3a4300b-1514-4cb8-a814-9c2baa449700") + def test_multiple_ndi_open_pmk_flip(self): + """Verify that between 2 DUTs can create 2 NDPs with different security configuration (one open, one using pmk). The result should use two different NDIs Flip Initiator and Responder roles. """ - self.run_multiple_ndi([None, self.PMK], flip_init_resp=True) + self.run_multiple_ndi([None, self.PMK], flip_init_resp=True) - @test_tracker_info(uuid="0bfea9e4-e57d-417f-8db4-245741e9bbd5") - def test_multiple_ndi_passphrase_pmk_flip(self): - """Verify that between 2 DUTs can create 2 NDPs with different security + @test_tracker_info(uuid="0bfea9e4-e57d-417f-8db4-245741e9bbd5") + def test_multiple_ndi_passphrase_pmk_flip(self): + """Verify that between 2 DUTs can create 2 NDPs with different security configuration (one using passphrase, one using pmk). The result should use two different NDIs Flip Initiator and Responder roles. """ - self.run_multiple_ndi([self.PASSPHRASE, self.PMK], flip_init_resp=True) + self.run_multiple_ndi([self.PASSPHRASE, self.PMK], flip_init_resp=True) - @test_tracker_info(uuid="74023483-5417-431b-a362-991ad4a03ab8") - def test_multiple_ndi_passphrases_flip(self): - """Verify that between 2 DUTs can create 2 NDPs with different security + @test_tracker_info(uuid="74023483-5417-431b-a362-991ad4a03ab8") + def test_multiple_ndi_passphrases_flip(self): + """Verify that between 2 DUTs can create 2 NDPs with different security configuration (using different passphrases). The result should use two different NDIs Flip Initiator and Responder roles. """ - self.run_multiple_ndi([self.PASSPHRASE, self.PASSPHRASE2], - flip_init_resp=True) + self.run_multiple_ndi( + [self.PASSPHRASE, self.PASSPHRASE2], flip_init_resp=True) - @test_tracker_info(uuid="873b2d91-28a1-403f-ae9c-d756bb2f59ee") - def test_multiple_ndi_pmks_flip(self): - """Verify that between 2 DUTs can create 2 NDPs with different security + @test_tracker_info(uuid="873b2d91-28a1-403f-ae9c-d756bb2f59ee") + def test_multiple_ndi_pmks_flip(self): + """Verify that between 2 DUTs can create 2 NDPs with different security configuration (using different PMKS). The result should use two different NDIs Flip Initiator and Responder roles. """ - self.run_multiple_ndi([self.PMK, self.PMK2], flip_init_resp=True) + self.run_multiple_ndi([self.PMK, self.PMK2], flip_init_resp=True) - ####################################### + ####################################### - @test_tracker_info(uuid="2f10a9df-7fbd-490d-a238-3523f47ab54c") - def test_ib_responder_any_usage(self): - """Verify that configuring an in-band (Aware discovery) Responder to receive + @test_tracker_info(uuid="2f10a9df-7fbd-490d-a238-3523f47ab54c") + def test_ib_responder_any_usage(self): + """Verify that configuring an in-band (Aware discovery) Responder to receive an NDP request from any peer is not permitted by current API level. Override API check to validate that possible (i.e. that failure at current API level is due to an API check and not some underlying failure). """ - # configure all devices to override API check and allow a Responder from ANY - for ad in self.android_devices: - autils.configure_ndp_allow_any_override(ad, True) - self.run_ib_data_path_test( - ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, - stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, - encr_type=self.ENCR_TYPE_OPEN, - use_peer_id=False) - - # configure all devices to respect API check - i.e. disallow a Responder - # from ANY - for ad in self.android_devices: - autils.configure_ndp_allow_any_override(ad, False) - self.run_ib_data_path_test( - ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, - stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, - encr_type=self.ENCR_TYPE_OPEN, - use_peer_id=False, - expect_failure=True) - - @test_tracker_info(uuid="5889cd41-0a72-4b7b-ab82-5b9168b9b5b8") - def test_oob_responder_any_usage(self): - """Verify that configuring an out-of-band (Aware discovery) Responder to + # configure all devices to override API check and allow a Responder from ANY + for ad in self.android_devices: + autils.configure_ndp_allow_any_override(ad, True) + self.run_ib_data_path_test( + ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, + stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, + encr_type=self.ENCR_TYPE_OPEN, + use_peer_id=False) + + # configure all devices to respect API check - i.e. disallow a Responder + # from ANY + for ad in self.android_devices: + autils.configure_ndp_allow_any_override(ad, False) + self.run_ib_data_path_test( + ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, + stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, + encr_type=self.ENCR_TYPE_OPEN, + use_peer_id=False, + expect_failure=True) + + @test_tracker_info(uuid="5889cd41-0a72-4b7b-ab82-5b9168b9b5b8") + def test_oob_responder_any_usage(self): + """Verify that configuring an out-of-band (Aware discovery) Responder to receive an NDP request from any peer is not permitted by current API level. Override API check to validate that possible (i.e. that failure at current API level is due to an API check and not some underlying failure). """ - # configure all devices to override API check and allow a Responder from ANY - for ad in self.android_devices: - autils.configure_ndp_allow_any_override(ad, True) - self.run_oob_data_path_test( - encr_type=self.ENCR_TYPE_OPEN, - use_peer_id=False) - - # configure all devices to respect API check - i.e. disallow a Responder - # from ANY - for ad in self.android_devices: - autils.configure_ndp_allow_any_override(ad, False) - self.run_oob_data_path_test( - encr_type=self.ENCR_TYPE_OPEN, - use_peer_id=False, - expect_failure=True) - - ####################################### - - def run_multiple_regulatory_domains(self, use_ib, init_domain, resp_domain): - """Verify that a data-path setup with two conflicting regulatory domains + # configure all devices to override API check and allow a Responder from ANY + for ad in self.android_devices: + autils.configure_ndp_allow_any_override(ad, True) + self.run_oob_data_path_test( + encr_type=self.ENCR_TYPE_OPEN, use_peer_id=False) + + # configure all devices to respect API check - i.e. disallow a Responder + # from ANY + for ad in self.android_devices: + autils.configure_ndp_allow_any_override(ad, False) + self.run_oob_data_path_test( + encr_type=self.ENCR_TYPE_OPEN, + use_peer_id=False, + expect_failure=True) + + ####################################### + + def run_multiple_regulatory_domains(self, use_ib, init_domain, + resp_domain): + """Verify that a data-path setup with two conflicting regulatory domains works (the result should be run in Channel 6 - but that is not tested). Args: @@ -1496,86 +1538,86 @@ class DataPathTest(AwareBaseTest): init_domain: The regulatory domain of the Initiator/Subscriber. resp_domain: The regulator domain of the Responder/Publisher. """ - init_dut = self.android_devices[0] - resp_dut = self.android_devices[1] - - init_dut.droid.wifiSetCountryCode(init_domain) - resp_dut.droid.wifiSetCountryCode(resp_domain) - - if use_ib: - (resp_req_key, init_req_key, resp_aware_if, init_aware_if, resp_ipv6, - init_ipv6) = autils.create_ib_ndp(resp_dut, init_dut, - autils.create_discovery_config( - "GoogleTestXyz", - aconsts.PUBLISH_TYPE_UNSOLICITED), - autils.create_discovery_config( - "GoogleTestXyz", - aconsts.SUBSCRIBE_TYPE_PASSIVE), - self.device_startup_offset) - else: - (init_req_key, resp_req_key, init_aware_if, resp_aware_if, init_ipv6, - resp_ipv6) = autils.create_oob_ndp(init_dut, resp_dut) - - self.log.info("Interface names: I=%s, R=%s", init_aware_if, resp_aware_if) - self.log.info("Interface addresses (IPv6): I=%s, R=%s", init_ipv6, - resp_ipv6) - - # clean-up - resp_dut.droid.connectivityUnregisterNetworkCallback(resp_req_key) - init_dut.droid.connectivityUnregisterNetworkCallback(init_req_key) - - @test_tracker_info(uuid="eff53739-35c5-47a6-81f0-d70b51d89c3b") - def test_multiple_regulator_domains_ib_us_jp(self): - """Verify data-path setup across multiple regulator domains. + init_dut = self.android_devices[0] + resp_dut = self.android_devices[1] + + init_dut.droid.wifiSetCountryCode(init_domain) + resp_dut.droid.wifiSetCountryCode(resp_domain) + + if use_ib: + (resp_req_key, init_req_key, resp_aware_if, init_aware_if, + resp_ipv6, init_ipv6) = autils.create_ib_ndp( + resp_dut, init_dut, + autils.create_discovery_config( + "GoogleTestXyz", aconsts.PUBLISH_TYPE_UNSOLICITED), + autils.create_discovery_config( + "GoogleTestXyz", aconsts.SUBSCRIBE_TYPE_PASSIVE), + self.device_startup_offset) + else: + (init_req_key, resp_req_key, init_aware_if, resp_aware_if, + init_ipv6, resp_ipv6) = autils.create_oob_ndp(init_dut, resp_dut) + + self.log.info("Interface names: I=%s, R=%s", init_aware_if, + resp_aware_if) + self.log.info("Interface addresses (IPv6): I=%s, R=%s", init_ipv6, + resp_ipv6) + + # clean-up + resp_dut.droid.connectivityUnregisterNetworkCallback(resp_req_key) + init_dut.droid.connectivityUnregisterNetworkCallback(init_req_key) + + @test_tracker_info(uuid="eff53739-35c5-47a6-81f0-d70b51d89c3b") + def test_multiple_regulator_domains_ib_us_jp(self): + """Verify data-path setup across multiple regulator domains. - Uses in-band discovery - Subscriber=US, Publisher=JP """ - self.run_multiple_regulatory_domains( - use_ib=True, - init_domain=wutils.WifiEnums.CountryCode.US, - resp_domain=wutils.WifiEnums.CountryCode.JAPAN) + self.run_multiple_regulatory_domains( + use_ib=True, + init_domain=wutils.WifiEnums.CountryCode.US, + resp_domain=wutils.WifiEnums.CountryCode.JAPAN) - @test_tracker_info(uuid="19af47cc-3204-40ef-b50f-14cf7b89cf4a") - def test_multiple_regulator_domains_ib_jp_us(self): - """Verify data-path setup across multiple regulator domains. + @test_tracker_info(uuid="19af47cc-3204-40ef-b50f-14cf7b89cf4a") + def test_multiple_regulator_domains_ib_jp_us(self): + """Verify data-path setup across multiple regulator domains. - Uses in-band discovery - Subscriber=JP, Publisher=US """ - self.run_multiple_regulatory_domains( - use_ib=True, - init_domain=wutils.WifiEnums.CountryCode.JAPAN, - resp_domain=wutils.WifiEnums.CountryCode.US) + self.run_multiple_regulatory_domains( + use_ib=True, + init_domain=wutils.WifiEnums.CountryCode.JAPAN, + resp_domain=wutils.WifiEnums.CountryCode.US) - @test_tracker_info(uuid="65285ab3-977f-4dbd-b663-d5a02f4fc663") - def test_multiple_regulator_domains_oob_us_jp(self): - """Verify data-path setup across multiple regulator domains. + @test_tracker_info(uuid="65285ab3-977f-4dbd-b663-d5a02f4fc663") + def test_multiple_regulator_domains_oob_us_jp(self): + """Verify data-path setup across multiple regulator domains. - Uses out-f-band discovery - Initiator=US, Responder=JP """ - self.run_multiple_regulatory_domains( - use_ib=False, - init_domain=wutils.WifiEnums.CountryCode.US, - resp_domain=wutils.WifiEnums.CountryCode.JAPAN) + self.run_multiple_regulatory_domains( + use_ib=False, + init_domain=wutils.WifiEnums.CountryCode.US, + resp_domain=wutils.WifiEnums.CountryCode.JAPAN) - @test_tracker_info(uuid="8a417e24-aaf6-44b9-a089-a07c3ba8d954") - def test_multiple_regulator_domains_oob_jp_us(self): - """Verify data-path setup across multiple regulator domains. + @test_tracker_info(uuid="8a417e24-aaf6-44b9-a089-a07c3ba8d954") + def test_multiple_regulator_domains_oob_jp_us(self): + """Verify data-path setup across multiple regulator domains. - Uses out-of-band discovery - Initiator=JP, Responder=US """ - self.run_multiple_regulatory_domains( - use_ib=False, - init_domain=wutils.WifiEnums.CountryCode.JAPAN, - resp_domain=wutils.WifiEnums.CountryCode.US) + self.run_multiple_regulatory_domains( + use_ib=False, + init_domain=wutils.WifiEnums.CountryCode.JAPAN, + resp_domain=wutils.WifiEnums.CountryCode.US) - ######################################################################## + ######################################################################## - def run_mix_ib_oob(self, same_request, ib_first, inits_on_same_dut): - """Validate that multiple network requests issued using both in-band and + def run_mix_ib_oob(self, same_request, ib_first, inits_on_same_dut): + """Validate that multiple network requests issued using both in-band and out-of-band discovery behave as expected. The same_request parameter controls whether identical single NDP is @@ -1591,275 +1633,273 @@ class DataPathTest(AwareBaseTest): otherwise (if False) then the Initiators are run on different devices. Note that Subscribe == Initiator. """ - if not same_request: - asserts.skip_if(self.android_devices[0].aware_capabilities[ - aconsts.CAP_MAX_NDI_INTERFACES] < 2 or - self.android_devices[1].aware_capabilities[ - aconsts.CAP_MAX_NDI_INTERFACES] < 2, - "DUTs do not support enough NDIs") - - (p_dut, s_dut, p_id, s_id, p_disc_id, s_disc_id, peer_id_on_sub, - peer_id_on_pub_null) = self.set_up_discovery( - aconsts.PUBLISH_TYPE_UNSOLICITED, aconsts.SUBSCRIBE_TYPE_PASSIVE, False) - - p_id2, p_mac = autils.attach_with_identity(p_dut) - s_id2, s_mac = autils.attach_with_identity(s_dut) - - if inits_on_same_dut: - resp_dut = p_dut - resp_id = p_id2 - resp_mac = p_mac - - init_dut = s_dut - init_id = s_id2 - init_mac = s_mac - else: - resp_dut = s_dut - resp_id = s_id2 - resp_mac = s_mac - - init_dut = p_dut - init_id = p_id2 - init_mac = p_mac - - passphrase = None if same_request else self.PASSPHRASE - - if ib_first: - # request in-band network (to completion) - p_req_key = self.request_network( - p_dut, - p_dut.droid.wifiAwareCreateNetworkSpecifier(p_disc_id, None)) - s_req_key = self.request_network( - s_dut, - s_dut.droid.wifiAwareCreateNetworkSpecifier(s_disc_id, - peer_id_on_sub)) - - # Publisher & Subscriber: wait for network formation - p_net_event = autils.wait_for_event_with_keys( - p_dut, cconsts.EVENT_NETWORK_CALLBACK, - autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, p_req_key)) - s_net_event = autils.wait_for_event_with_keys( - s_dut, cconsts.EVENT_NETWORK_CALLBACK, - autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, s_req_key)) - - # request out-of-band network - resp_req_key = autils.request_network(resp_dut, - resp_dut.droid.wifiAwareCreateNetworkSpecifierOob( - resp_id, aconsts.DATA_PATH_RESPONDER, init_mac, passphrase)) - init_req_key = autils.request_network(init_dut, - init_dut.droid.wifiAwareCreateNetworkSpecifierOob( - init_id, aconsts.DATA_PATH_INITIATOR, resp_mac, passphrase)) - - resp_net_event = autils.wait_for_event_with_keys( - resp_dut, cconsts.EVENT_NETWORK_CALLBACK, - autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, resp_req_key)) - init_net_event = autils.wait_for_event_with_keys( - init_dut, cconsts.EVENT_NETWORK_CALLBACK, - autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, init_req_key)) - - if not ib_first: - # request in-band network (to completion) - p_req_key = self.request_network( - p_dut, - p_dut.droid.wifiAwareCreateNetworkSpecifier(p_disc_id, None)) - s_req_key = self.request_network( - s_dut, - s_dut.droid.wifiAwareCreateNetworkSpecifier(s_disc_id, - peer_id_on_sub)) - - # Publisher & Subscriber: wait for network formation - p_net_event = autils.wait_for_event_with_keys( - p_dut, cconsts.EVENT_NETWORK_CALLBACK, - autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, p_req_key)) - s_net_event = autils.wait_for_event_with_keys( - s_dut, cconsts.EVENT_NETWORK_CALLBACK, - autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, s_req_key)) - - # extract net info - pub_interface = p_net_event["data"][cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - sub_interface = s_net_event["data"][cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - resp_interface = resp_net_event["data"][ - cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - init_interface = init_net_event["data"][ - cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - - self.log.info( - "Interface names: Pub=%s, Sub=%s, Resp=%s, Init=%s", pub_interface, - sub_interface, resp_interface, init_interface) - - pub_ipv6 = \ - p_dut.droid.connectivityGetLinkLocalIpv6Address(pub_interface).split("%")[0] - sub_ipv6 = \ - s_dut.droid.connectivityGetLinkLocalIpv6Address(sub_interface).split("%")[0] - resp_ipv6 = \ - resp_dut.droid.connectivityGetLinkLocalIpv6Address(resp_interface).split( - "%")[0] - init_ipv6 = \ - init_dut.droid.connectivityGetLinkLocalIpv6Address(init_interface).split( - "%")[0] - - self.log.info( - "Interface addresses (IPv6): Pub=%s, Sub=%s, Resp=%s, Init=%s", pub_ipv6, - sub_ipv6, resp_ipv6, init_ipv6) - - # validate NDP/NDI conditions (using interface names & ipv6) - if same_request: - asserts.assert_equal(pub_interface, - resp_interface if inits_on_same_dut else init_interface, - "NDP interfaces don't match on Pub/other") - asserts.assert_equal(sub_interface, - init_interface if inits_on_same_dut else resp_interface, - "NDP interfaces don't match on Sub/other") - - asserts.assert_equal(pub_ipv6, - resp_ipv6 if inits_on_same_dut else init_ipv6, - "NDP IPv6 don't match on Pub/other") - asserts.assert_equal(sub_ipv6, - init_ipv6 if inits_on_same_dut else resp_ipv6, - "NDP IPv6 don't match on Sub/other") - else: - asserts.assert_false(pub_interface == ( - resp_interface if inits_on_same_dut else init_interface), - "NDP interfaces match on Pub/other") - asserts.assert_false(sub_interface == ( - init_interface if inits_on_same_dut else resp_interface), - "NDP interfaces match on Sub/other") - - asserts.assert_false(pub_ipv6 == - (resp_ipv6 if inits_on_same_dut else init_ipv6), - "NDP IPv6 match on Pub/other") - asserts.assert_false(sub_ipv6 == - (init_ipv6 if inits_on_same_dut else resp_ipv6), - "NDP IPv6 match on Sub/other") - - # release requests - p_dut.droid.connectivityUnregisterNetworkCallback(p_req_key) - s_dut.droid.connectivityUnregisterNetworkCallback(s_req_key) - resp_dut.droid.connectivityUnregisterNetworkCallback(resp_req_key) - init_dut.droid.connectivityUnregisterNetworkCallback(init_req_key) - - @test_tracker_info(uuid="d8a0839d-4ba0-43f2-af93-3cf1382f9f16") - def test_identical_ndps_mix_ib_oob_ib_first_same_polarity(self): - """Validate that a single NDP is created for multiple identical requests + if not same_request: + asserts.skip_if( + self.android_devices[0] + .aware_capabilities[aconsts.CAP_MAX_NDI_INTERFACES] < 2 + or self.android_devices[1] + .aware_capabilities[aconsts.CAP_MAX_NDI_INTERFACES] < 2, + "DUTs do not support enough NDIs") + + (p_dut, s_dut, p_id, s_id, p_disc_id, s_disc_id, peer_id_on_sub, + peer_id_on_pub_null) = self.set_up_discovery( + aconsts.PUBLISH_TYPE_UNSOLICITED, aconsts.SUBSCRIBE_TYPE_PASSIVE, + False) + + p_id2, p_mac = autils.attach_with_identity(p_dut) + s_id2, s_mac = autils.attach_with_identity(s_dut) + + if inits_on_same_dut: + resp_dut = p_dut + resp_id = p_id2 + resp_mac = p_mac + + init_dut = s_dut + init_id = s_id2 + init_mac = s_mac + else: + resp_dut = s_dut + resp_id = s_id2 + resp_mac = s_mac + + init_dut = p_dut + init_id = p_id2 + init_mac = p_mac + + passphrase = None if same_request else self.PASSPHRASE + + if ib_first: + # request in-band network (to completion) + p_req_key = self.request_network( + p_dut, + p_dut.droid.wifiAwareCreateNetworkSpecifier(p_disc_id, None)) + s_req_key = self.request_network( + s_dut, + s_dut.droid.wifiAwareCreateNetworkSpecifier( + s_disc_id, peer_id_on_sub)) + + # Publisher & Subscriber: wait for network formation + p_net_event = autils.wait_for_event_with_keys( + p_dut, cconsts.EVENT_NETWORK_CALLBACK, + autils.EVENT_NDP_TIMEOUT, + (cconsts.NETWORK_CB_KEY_EVENT, + cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), + (cconsts.NETWORK_CB_KEY_ID, p_req_key)) + s_net_event = autils.wait_for_event_with_keys( + s_dut, cconsts.EVENT_NETWORK_CALLBACK, + autils.EVENT_NDP_TIMEOUT, + (cconsts.NETWORK_CB_KEY_EVENT, + cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), + (cconsts.NETWORK_CB_KEY_ID, s_req_key)) + + # request out-of-band network + resp_req_key = autils.request_network( + resp_dut, + resp_dut.droid.wifiAwareCreateNetworkSpecifierOob( + resp_id, aconsts.DATA_PATH_RESPONDER, init_mac, passphrase)) + init_req_key = autils.request_network( + init_dut, + init_dut.droid.wifiAwareCreateNetworkSpecifierOob( + init_id, aconsts.DATA_PATH_INITIATOR, resp_mac, passphrase)) + + resp_net_event = autils.wait_for_event_with_keys( + resp_dut, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT, + (cconsts.NETWORK_CB_KEY_EVENT, + cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), + (cconsts.NETWORK_CB_KEY_ID, resp_req_key)) + init_net_event = autils.wait_for_event_with_keys( + init_dut, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT, + (cconsts.NETWORK_CB_KEY_EVENT, + cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), + (cconsts.NETWORK_CB_KEY_ID, init_req_key)) + + if not ib_first: + # request in-band network (to completion) + p_req_key = self.request_network( + p_dut, + p_dut.droid.wifiAwareCreateNetworkSpecifier(p_disc_id, None)) + s_req_key = self.request_network( + s_dut, + s_dut.droid.wifiAwareCreateNetworkSpecifier( + s_disc_id, peer_id_on_sub)) + + # Publisher & Subscriber: wait for network formation + p_net_event = autils.wait_for_event_with_keys( + p_dut, cconsts.EVENT_NETWORK_CALLBACK, + autils.EVENT_NDP_TIMEOUT, + (cconsts.NETWORK_CB_KEY_EVENT, + cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), + (cconsts.NETWORK_CB_KEY_ID, p_req_key)) + s_net_event = autils.wait_for_event_with_keys( + s_dut, cconsts.EVENT_NETWORK_CALLBACK, + autils.EVENT_NDP_TIMEOUT, + (cconsts.NETWORK_CB_KEY_EVENT, + cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), + (cconsts.NETWORK_CB_KEY_ID, s_req_key)) + + # extract net info + pub_interface = p_net_event["data"][ + cconsts.NETWORK_CB_KEY_INTERFACE_NAME] + sub_interface = s_net_event["data"][ + cconsts.NETWORK_CB_KEY_INTERFACE_NAME] + resp_interface = resp_net_event["data"][ + cconsts.NETWORK_CB_KEY_INTERFACE_NAME] + init_interface = init_net_event["data"][ + cconsts.NETWORK_CB_KEY_INTERFACE_NAME] + + self.log.info("Interface names: Pub=%s, Sub=%s, Resp=%s, Init=%s", + pub_interface, sub_interface, resp_interface, + init_interface) + + pub_ipv6 = \ + p_dut.droid.connectivityGetLinkLocalIpv6Address(pub_interface).split("%")[0] + sub_ipv6 = \ + s_dut.droid.connectivityGetLinkLocalIpv6Address(sub_interface).split("%")[0] + resp_ipv6 = \ + resp_dut.droid.connectivityGetLinkLocalIpv6Address(resp_interface).split( + "%")[0] + init_ipv6 = \ + init_dut.droid.connectivityGetLinkLocalIpv6Address(init_interface).split( + "%")[0] + + self.log.info( + "Interface addresses (IPv6): Pub=%s, Sub=%s, Resp=%s, Init=%s", + pub_ipv6, sub_ipv6, resp_ipv6, init_ipv6) + + # validate NDP/NDI conditions (using interface names & ipv6) + if same_request: + asserts.assert_equal( + pub_interface, resp_interface if inits_on_same_dut else + init_interface, "NDP interfaces don't match on Pub/other") + asserts.assert_equal( + sub_interface, init_interface if inits_on_same_dut else + resp_interface, "NDP interfaces don't match on Sub/other") + + asserts.assert_equal(pub_ipv6, resp_ipv6 + if inits_on_same_dut else init_ipv6, + "NDP IPv6 don't match on Pub/other") + asserts.assert_equal(sub_ipv6, init_ipv6 + if inits_on_same_dut else resp_ipv6, + "NDP IPv6 don't match on Sub/other") + else: + asserts.assert_false( + pub_interface == (resp_interface + if inits_on_same_dut else init_interface), + "NDP interfaces match on Pub/other") + asserts.assert_false( + sub_interface == (init_interface + if inits_on_same_dut else resp_interface), + "NDP interfaces match on Sub/other") + + asserts.assert_false( + pub_ipv6 == (resp_ipv6 if inits_on_same_dut else init_ipv6), + "NDP IPv6 match on Pub/other") + asserts.assert_false( + sub_ipv6 == (init_ipv6 if inits_on_same_dut else resp_ipv6), + "NDP IPv6 match on Sub/other") + + # release requests + p_dut.droid.connectivityUnregisterNetworkCallback(p_req_key) + s_dut.droid.connectivityUnregisterNetworkCallback(s_req_key) + resp_dut.droid.connectivityUnregisterNetworkCallback(resp_req_key) + init_dut.droid.connectivityUnregisterNetworkCallback(init_req_key) + + @test_tracker_info(uuid="d8a0839d-4ba0-43f2-af93-3cf1382f9f16") + def test_identical_ndps_mix_ib_oob_ib_first_same_polarity(self): + """Validate that a single NDP is created for multiple identical requests which are issued through either in-band (ib) or out-of-band (oob) APIs. The in-band request is issued first. Both Initiators (Sub == Initiator) are run on the same device. """ - self.run_mix_ib_oob(same_request=True, - ib_first=True, - inits_on_same_dut=True) + self.run_mix_ib_oob( + same_request=True, ib_first=True, inits_on_same_dut=True) - @test_tracker_info(uuid="70bbb811-0bed-4a19-96b3-f2446e777c8a") - def test_identical_ndps_mix_ib_oob_oob_first_same_polarity(self): - """Validate that a single NDP is created for multiple identical requests + @test_tracker_info(uuid="70bbb811-0bed-4a19-96b3-f2446e777c8a") + def test_identical_ndps_mix_ib_oob_oob_first_same_polarity(self): + """Validate that a single NDP is created for multiple identical requests which are issued through either in-band (ib) or out-of-band (oob) APIs. The out-of-band request is issued first. Both Initiators (Sub == Initiator) are run on the same device. """ - self.run_mix_ib_oob(same_request=True, - ib_first=False, - inits_on_same_dut=True) + self.run_mix_ib_oob( + same_request=True, ib_first=False, inits_on_same_dut=True) - @test_tracker_info(uuid="d9796da5-f96a-4a51-be0f-89d6f5bfe3ad") - def test_identical_ndps_mix_ib_oob_ib_first_diff_polarity(self): - """Validate that a single NDP is created for multiple identical requests + @test_tracker_info(uuid="d9796da5-f96a-4a51-be0f-89d6f5bfe3ad") + def test_identical_ndps_mix_ib_oob_ib_first_diff_polarity(self): + """Validate that a single NDP is created for multiple identical requests which are issued through either in-band (ib) or out-of-band (oob) APIs. The in-band request is issued first. Initiators (Sub == Initiator) are run on different devices. """ - self.run_mix_ib_oob(same_request=True, - ib_first=True, - inits_on_same_dut=False) + self.run_mix_ib_oob( + same_request=True, ib_first=True, inits_on_same_dut=False) - @test_tracker_info(uuid="72b16cbf-53ad-4f98-8dcf-a8cc5fa812e3") - def test_identical_ndps_mix_ib_oob_oob_first_diff_polarity(self): - """Validate that a single NDP is created for multiple identical requests + @test_tracker_info(uuid="72b16cbf-53ad-4f98-8dcf-a8cc5fa812e3") + def test_identical_ndps_mix_ib_oob_oob_first_diff_polarity(self): + """Validate that a single NDP is created for multiple identical requests which are issued through either in-band (ib) or out-of-band (oob) APIs. The out-of-band request is issued first. Initiators (Sub == Initiator) are run on different devices. """ - self.run_mix_ib_oob(same_request=True, - ib_first=False, - inits_on_same_dut=False) + self.run_mix_ib_oob( + same_request=True, ib_first=False, inits_on_same_dut=False) - @test_tracker_info(uuid="51f9581e-c5ee-48a7-84d2-adff4876c3d7") - def test_multiple_ndis_mix_ib_oob_ib_first_same_polarity(self): - """Validate that multiple NDIs are created for NDPs which are requested with + @test_tracker_info(uuid="51f9581e-c5ee-48a7-84d2-adff4876c3d7") + def test_multiple_ndis_mix_ib_oob_ib_first_same_polarity(self): + """Validate that multiple NDIs are created for NDPs which are requested with different security configurations. Use a mix of in-band and out-of-band APIs to request the different NDPs. The in-band request is issued first. Initiators (Sub == Initiator) are run on the same device. """ - self.run_mix_ib_oob(same_request=False, - ib_first=True, - inits_on_same_dut=True) + self.run_mix_ib_oob( + same_request=False, ib_first=True, inits_on_same_dut=True) - @test_tracker_info(uuid="b1e3070e-4d38-4b31-862d-39b82e0f2853") - def test_multiple_ndis_mix_ib_oob_oob_first_same_polarity(self): - """Validate that multiple NDIs are created for NDPs which are requested with + @test_tracker_info(uuid="b1e3070e-4d38-4b31-862d-39b82e0f2853") + def test_multiple_ndis_mix_ib_oob_oob_first_same_polarity(self): + """Validate that multiple NDIs are created for NDPs which are requested with different security configurations. Use a mix of in-band and out-of-band APIs to request the different NDPs. The out-of-band request is issued first. Initiators (Sub == Initiator) are run on the same device. """ - self.run_mix_ib_oob(same_request=False, - ib_first=False, - inits_on_same_dut=True) + self.run_mix_ib_oob( + same_request=False, ib_first=False, inits_on_same_dut=True) - @test_tracker_info(uuid="b1e3070e-4d38-4b31-862d-39b82e0f2853") - def test_multiple_ndis_mix_ib_oob_ib_first_diff_polarity(self): - """Validate that multiple NDIs are created for NDPs which are requested with + @test_tracker_info(uuid="b1e3070e-4d38-4b31-862d-39b82e0f2853") + def test_multiple_ndis_mix_ib_oob_ib_first_diff_polarity(self): + """Validate that multiple NDIs are created for NDPs which are requested with different security configurations. Use a mix of in-band and out-of-band APIs to request the different NDPs. The in-band request is issued first. Initiators (Sub == Initiator) are run on different devices. """ - self.run_mix_ib_oob(same_request=False, - ib_first=True, - inits_on_same_dut=False) + self.run_mix_ib_oob( + same_request=False, ib_first=True, inits_on_same_dut=False) - @test_tracker_info(uuid="596caadf-028e-494b-bbce-8304ccec2cbb") - def test_multiple_ndis_mix_ib_oob_oob_first_diff_polarity(self): - """Validate that multiple NDIs are created for NDPs which are requested with + @test_tracker_info(uuid="596caadf-028e-494b-bbce-8304ccec2cbb") + def test_multiple_ndis_mix_ib_oob_oob_first_diff_polarity(self): + """Validate that multiple NDIs are created for NDPs which are requested with different security configurations. Use a mix of in-band and out-of-band APIs to request the different NDPs. The out-of-band request is issued first. Initiators (Sub == Initiator) are run on different devices. """ - self.run_mix_ib_oob(same_request=False, - ib_first=False, - inits_on_same_dut=False) + self.run_mix_ib_oob( + same_request=False, ib_first=False, inits_on_same_dut=False) - ######################################################################## + ######################################################################## - def test_ndp_loop(self): - """Validate that can create a loop (chain) of N NDPs between N devices, + def test_ndp_loop(self): + """Validate that can create a loop (chain) of N NDPs between N devices, where N >= 3, e.g. A - B @@ -1868,58 +1908,63 @@ class DataPathTest(AwareBaseTest): The NDPs are all OPEN (no encryption). """ - asserts.assert_true(len(self.android_devices) >= 3, - 'A minimum of 3 devices is needed to run the test, have %d' % - len(self.android_devices)) - - duts = self.android_devices - loop_len = len(duts) - ids = [] - macs = [] - reqs = [[], [], []] - ifs = [[], [], []] - ipv6s = [[], [], []] - - for i in range(loop_len): - duts[i].pretty_name = chr(ord("A") + i) - - # start-up 3 devices (attach w/ identity) - for i in range(loop_len): - ids.append(duts[i].droid.wifiAwareAttach(True)) - autils.wait_for_event(duts[i], aconsts.EVENT_CB_ON_ATTACHED) - ident_event = autils.wait_for_event(duts[i], - aconsts.EVENT_CB_ON_IDENTITY_CHANGED) - macs.append(ident_event['data']['mac']) - - # wait for for devices to synchronize with each other - there are no other - # mechanisms to make sure this happens for OOB discovery (except retrying - # to execute the data-path request) - time.sleep(autils.WAIT_FOR_CLUSTER) - - # create the N NDPs: i to (i+1) % N - for i in range(loop_len): - peer_device = (i + 1) % loop_len - - (init_req_key, resp_req_key, init_aware_if, - resp_aware_if, init_ipv6, resp_ipv6) = autils.create_oob_ndp_on_sessions( - duts[i], duts[peer_device], - ids[i], macs[i], ids[peer_device], macs[peer_device]) - - reqs[i].append(init_req_key) - reqs[peer_device].append(resp_req_key) - ifs[i].append(init_aware_if) - ifs[peer_device].append(resp_aware_if) - ipv6s[i].append(init_ipv6) - ipv6s[peer_device].append(resp_ipv6) - - # clean-up - for i in range(loop_len): - for req in reqs[i]: - duts[i].droid.connectivityUnregisterNetworkCallback(req) - - # info - self.log.info("MACs: %s", macs) - self.log.info("Interface names: %s", ifs) - self.log.info("IPv6 addresses: %s", ipv6s) - asserts.explicit_pass("NDP loop test", - extras={"macs": macs, "ifs": ifs, "ipv6s": ipv6s}) + asserts.assert_true( + len(self.android_devices) >= 3, + 'A minimum of 3 devices is needed to run the test, have %d' % len( + self.android_devices)) + + duts = self.android_devices + loop_len = len(duts) + ids = [] + macs = [] + reqs = [[], [], []] + ifs = [[], [], []] + ipv6s = [[], [], []] + + for i in range(loop_len): + duts[i].pretty_name = chr(ord("A") + i) + + # start-up 3 devices (attach w/ identity) + for i in range(loop_len): + ids.append(duts[i].droid.wifiAwareAttach(True)) + autils.wait_for_event(duts[i], aconsts.EVENT_CB_ON_ATTACHED) + ident_event = autils.wait_for_event( + duts[i], aconsts.EVENT_CB_ON_IDENTITY_CHANGED) + macs.append(ident_event['data']['mac']) + + # wait for for devices to synchronize with each other - there are no other + # mechanisms to make sure this happens for OOB discovery (except retrying + # to execute the data-path request) + time.sleep(autils.WAIT_FOR_CLUSTER) + + # create the N NDPs: i to (i+1) % N + for i in range(loop_len): + peer_device = (i + 1) % loop_len + + (init_req_key, resp_req_key, init_aware_if, resp_aware_if, + init_ipv6, resp_ipv6) = autils.create_oob_ndp_on_sessions( + duts[i], duts[peer_device], ids[i], macs[i], ids[peer_device], + macs[peer_device]) + + reqs[i].append(init_req_key) + reqs[peer_device].append(resp_req_key) + ifs[i].append(init_aware_if) + ifs[peer_device].append(resp_aware_if) + ipv6s[i].append(init_ipv6) + ipv6s[peer_device].append(resp_ipv6) + + # clean-up + for i in range(loop_len): + for req in reqs[i]: + duts[i].droid.connectivityUnregisterNetworkCallback(req) + + # info + self.log.info("MACs: %s", macs) + self.log.info("Interface names: %s", ifs) + self.log.info("IPv6 addresses: %s", ipv6s) + asserts.explicit_pass( + "NDP loop test", extras={ + "macs": macs, + "ifs": ifs, + "ipv6s": ipv6s + }) diff --git a/acts/tests/google/wifi/aware/functional/DiscoveryTest.py b/acts/tests/google/wifi/aware/functional/DiscoveryTest.py index c6f75b0ba2..0de6d123fb 100644 --- a/acts/tests/google/wifi/aware/functional/DiscoveryTest.py +++ b/acts/tests/google/wifi/aware/functional/DiscoveryTest.py @@ -25,27 +25,27 @@ from acts.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest class DiscoveryTest(AwareBaseTest): - """Set of tests for Wi-Fi Aware discovery.""" + """Set of tests for Wi-Fi Aware discovery.""" - # configuration parameters used by tests - PAYLOAD_SIZE_MIN = 0 - PAYLOAD_SIZE_TYPICAL = 1 - PAYLOAD_SIZE_MAX = 2 + # configuration parameters used by tests + PAYLOAD_SIZE_MIN = 0 + PAYLOAD_SIZE_TYPICAL = 1 + PAYLOAD_SIZE_MAX = 2 - # message strings - query_msg = "How are you doing? 你好嗎?" - response_msg = "Doing ok - thanks! 做的不錯 - 謝謝!" + # message strings + query_msg = "How are you doing? 你好嗎?" + response_msg = "Doing ok - thanks! 做的不錯 - 謝謝!" - # message re-transmit counter (increases reliability in open-environment) - # Note: reliability of message transmission is tested elsewhere - msg_retx_count = 5 # hard-coded max value, internal API + # message re-transmit counter (increases reliability in open-environment) + # Note: reliability of message transmission is tested elsewhere + msg_retx_count = 5 # hard-coded max value, internal API - def __init__(self, controllers): - AwareBaseTest.__init__(self, controllers) + def __init__(self, controllers): + AwareBaseTest.__init__(self, controllers) - def create_base_config(self, caps, is_publish, ptype, stype, payload_size, - ttl, term_ind_on, null_match): - """Create a base configuration based on input parameters. + def create_base_config(self, caps, is_publish, ptype, stype, payload_size, + ttl, term_ind_on, null_match): + """Create a base configuration based on input parameters. Args: caps: device capability dictionary @@ -59,44 +59,48 @@ class DiscoveryTest(AwareBaseTest): Returns: publish discovery configuration object. """ - config = {} - if is_publish: - config[aconsts.DISCOVERY_KEY_DISCOVERY_TYPE] = ptype - else: - config[aconsts.DISCOVERY_KEY_DISCOVERY_TYPE] = stype - config[aconsts.DISCOVERY_KEY_TTL] = ttl - config[aconsts.DISCOVERY_KEY_TERM_CB_ENABLED] = term_ind_on - if payload_size == self.PAYLOAD_SIZE_MIN: - config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = "a" - config[aconsts.DISCOVERY_KEY_SSI] = None - config[aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST] = [] - elif payload_size == self.PAYLOAD_SIZE_TYPICAL: - config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = "GoogleTestServiceX" - if is_publish: - config[aconsts.DISCOVERY_KEY_SSI] = string.ascii_letters - else: - config[aconsts.DISCOVERY_KEY_SSI] = string.ascii_letters[:: + config = {} + if is_publish: + config[aconsts.DISCOVERY_KEY_DISCOVERY_TYPE] = ptype + else: + config[aconsts.DISCOVERY_KEY_DISCOVERY_TYPE] = stype + config[aconsts.DISCOVERY_KEY_TTL] = ttl + config[aconsts.DISCOVERY_KEY_TERM_CB_ENABLED] = term_ind_on + if payload_size == self.PAYLOAD_SIZE_MIN: + config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = "a" + config[aconsts.DISCOVERY_KEY_SSI] = None + config[aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST] = [] + elif payload_size == self.PAYLOAD_SIZE_TYPICAL: + config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = "GoogleTestServiceX" + if is_publish: + config[aconsts.DISCOVERY_KEY_SSI] = string.ascii_letters + else: + config[aconsts. + DISCOVERY_KEY_SSI] = string.ascii_letters[:: -1] # reverse - config[aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST] = autils.encode_list( - [(10).to_bytes(1, byteorder="big"), "hello there string" - if not null_match else None, - bytes(range(40))]) - else: # PAYLOAD_SIZE_MAX - config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = "VeryLong" + "X" * ( - caps[aconsts.CAP_MAX_SERVICE_NAME_LEN] - 8) - config[aconsts.DISCOVERY_KEY_SSI] = ("P" if is_publish else "S") * caps[ - aconsts.CAP_MAX_SERVICE_SPECIFIC_INFO_LEN] - mf = autils.construct_max_match_filter( - caps[aconsts.CAP_MAX_MATCH_FILTER_LEN]) - if null_match: - mf[2] = None - config[aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST] = autils.encode_list(mf) - - return config - - def create_publish_config(self, caps, ptype, payload_size, ttl, term_ind_on, - null_match): - """Create a publish configuration based on input parameters. + config[ + aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST] = autils.encode_list( + [(10).to_bytes(1, byteorder="big"), "hello there string" + if not null_match else None, + bytes(range(40))]) + else: # PAYLOAD_SIZE_MAX + config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = "VeryLong" + "X" * ( + caps[aconsts.CAP_MAX_SERVICE_NAME_LEN] - 8) + config[aconsts.DISCOVERY_KEY_SSI] = ( + "P" if is_publish else + "S") * caps[aconsts.CAP_MAX_SERVICE_SPECIFIC_INFO_LEN] + mf = autils.construct_max_match_filter( + caps[aconsts.CAP_MAX_MATCH_FILTER_LEN]) + if null_match: + mf[2] = None + config[aconsts. + DISCOVERY_KEY_MATCH_FILTER_LIST] = autils.encode_list(mf) + + return config + + def create_publish_config(self, caps, ptype, payload_size, ttl, + term_ind_on, null_match): + """Create a publish configuration based on input parameters. Args: caps: device capability dictionary @@ -108,12 +112,12 @@ class DiscoveryTest(AwareBaseTest): Returns: publish discovery configuration object. """ - return self.create_base_config(caps, True, ptype, None, payload_size, ttl, - term_ind_on, null_match) + return self.create_base_config(caps, True, ptype, None, payload_size, + ttl, term_ind_on, null_match) - def create_subscribe_config(self, caps, stype, payload_size, ttl, term_ind_on, - null_match): - """Create a subscribe configuration based on input parameters. + def create_subscribe_config(self, caps, stype, payload_size, ttl, + term_ind_on, null_match): + """Create a subscribe configuration based on input parameters. Args: caps: device capability dictionary @@ -125,11 +129,11 @@ class DiscoveryTest(AwareBaseTest): Returns: subscribe discovery configuration object. """ - return self.create_base_config(caps, False, None, stype, payload_size, ttl, - term_ind_on, null_match) + return self.create_base_config(caps, False, None, stype, payload_size, + ttl, term_ind_on, null_match) - def positive_discovery_test_utility(self, ptype, stype, payload_size): - """Utility which runs a positive discovery test: + def positive_discovery_test_utility(self, ptype, stype, payload_size): + """Utility which runs a positive discovery test: - Discovery (publish/subscribe) with TTL=0 (non-self-terminating) - Exchange messages - Update publish/subscribe @@ -140,150 +144,159 @@ class DiscoveryTest(AwareBaseTest): stype: Subscribe discovery type payload_size: One of PAYLOAD_SIZE_* constants - MIN, TYPICAL, MAX """ - p_dut = self.android_devices[0] - p_dut.pretty_name = "Publisher" - s_dut = self.android_devices[1] - s_dut.pretty_name = "Subscriber" - - # Publisher+Subscriber: attach and wait for confirmation - p_id = p_dut.droid.wifiAwareAttach(False) - autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED) - time.sleep(self.device_startup_offset) - s_id = s_dut.droid.wifiAwareAttach(False) - autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED) - - # Publisher: start publish and wait for confirmation - p_config = self.create_publish_config( - p_dut.aware_capabilities, - ptype, - payload_size, - ttl=0, - term_ind_on=False, - null_match=False) - p_disc_id = p_dut.droid.wifiAwarePublish(p_id, p_config) - autils.wait_for_event(p_dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED) - - # Subscriber: start subscribe and wait for confirmation - s_config = self.create_subscribe_config( - s_dut.aware_capabilities, - stype, - payload_size, - ttl=0, - term_ind_on=False, - null_match=True) - s_disc_id = s_dut.droid.wifiAwareSubscribe(s_id, s_config) - autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED) - - # Subscriber: wait for service discovery - discovery_event = autils.wait_for_event( - s_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) - peer_id_on_sub = discovery_event["data"][aconsts.SESSION_CB_KEY_PEER_ID] - - # Subscriber: validate contents of discovery: - # - SSI: publisher's - # - Match filter: UNSOLICITED - publisher, SOLICITED - subscriber - autils.assert_equal_strings( - bytes(discovery_event["data"][ - aconsts.SESSION_CB_KEY_SERVICE_SPECIFIC_INFO]).decode("utf-8"), - p_config[aconsts.DISCOVERY_KEY_SSI], - "Discovery mismatch: service specific info (SSI)") - asserts.assert_equal( - autils.decode_list( - discovery_event["data"][aconsts.SESSION_CB_KEY_MATCH_FILTER_LIST]), - autils.decode_list(p_config[aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST] - if ptype == aconsts.PUBLISH_TYPE_UNSOLICITED else - s_config[aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST]), - "Discovery mismatch: match filter") - - # Subscriber: send message to peer (Publisher) - s_dut.droid.wifiAwareSendMessage(s_disc_id, peer_id_on_sub, - self.get_next_msg_id(), self.query_msg, - self.msg_retx_count) - autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_MESSAGE_SENT) - - # Publisher: wait for received message - pub_rx_msg_event = autils.wait_for_event( - p_dut, aconsts.SESSION_CB_ON_MESSAGE_RECEIVED) - peer_id_on_pub = pub_rx_msg_event["data"][aconsts.SESSION_CB_KEY_PEER_ID] - - # Publisher: validate contents of message - asserts.assert_equal( - pub_rx_msg_event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING], - self.query_msg, "Subscriber -> Publisher message corrupted") - - # Publisher: send message to peer (Subscriber) - p_dut.droid.wifiAwareSendMessage(p_disc_id, peer_id_on_pub, - self.get_next_msg_id(), self.response_msg, - self.msg_retx_count) - autils.wait_for_event(p_dut, aconsts.SESSION_CB_ON_MESSAGE_SENT) - - # Subscriber: wait for received message - sub_rx_msg_event = autils.wait_for_event( - s_dut, aconsts.SESSION_CB_ON_MESSAGE_RECEIVED) - - # Subscriber: validate contents of message - asserts.assert_equal( - sub_rx_msg_event["data"][aconsts.SESSION_CB_KEY_PEER_ID], - peer_id_on_sub, - "Subscriber received message from different peer ID then discovery!?") - autils.assert_equal_strings( - sub_rx_msg_event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING], - self.response_msg, "Publisher -> Subscriber message corrupted") - - # Subscriber: validate that we're not getting another Service Discovery - autils.fail_on_event(s_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) - - # Publisher: update publish and wait for confirmation - p_config[aconsts.DISCOVERY_KEY_SSI] = "something else" - p_dut.droid.wifiAwareUpdatePublish(p_disc_id, p_config) - autils.wait_for_event(p_dut, aconsts.SESSION_CB_ON_SESSION_CONFIG_UPDATED) - - # Subscriber: expect a new service discovery - discovery_event = autils.wait_for_event( - s_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) - - # Subscriber: validate contents of discovery - autils.assert_equal_strings( - bytes(discovery_event["data"][ - aconsts.SESSION_CB_KEY_SERVICE_SPECIFIC_INFO]).decode("utf-8"), - p_config[aconsts.DISCOVERY_KEY_SSI], - "Discovery mismatch (after pub update): service specific info (SSI)") - asserts.assert_equal( - autils.decode_list( - discovery_event["data"][aconsts.SESSION_CB_KEY_MATCH_FILTER_LIST]), - autils.decode_list(p_config[aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST] - if ptype == aconsts.PUBLISH_TYPE_UNSOLICITED else - s_config[aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST]), - "Discovery mismatch: match filter") - - # Subscribe: update subscribe and wait for confirmation - s_config = self.create_subscribe_config( - s_dut.aware_capabilities, - stype, - payload_size, - ttl=0, - term_ind_on=False, - null_match=False) - s_dut.droid.wifiAwareUpdateSubscribe(s_disc_id, s_config) - autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_SESSION_CONFIG_UPDATED) - - # Publisher+Subscriber: Terminate sessions - p_dut.droid.wifiAwareDestroyDiscoverySession(p_disc_id) - s_dut.droid.wifiAwareDestroyDiscoverySession(s_disc_id) - - # sleep for timeout period and then verify all 'fail_on_event' together - time.sleep(autils.EVENT_TIMEOUT) - - # verify that there were no other events - autils.verify_no_more_events(p_dut, timeout=0) - autils.verify_no_more_events(s_dut, timeout=0) - - # verify that forbidden callbacks aren't called - autils.validate_forbidden_callbacks(p_dut, {aconsts.CB_EV_MATCH: 0}) - - def verify_discovery_session_term(self, dut, disc_id, config, is_publish, - term_ind_on): - """Utility to verify that the specified discovery session has terminated (by + p_dut = self.android_devices[0] + p_dut.pretty_name = "Publisher" + s_dut = self.android_devices[1] + s_dut.pretty_name = "Subscriber" + + # Publisher+Subscriber: attach and wait for confirmation + p_id = p_dut.droid.wifiAwareAttach(False) + autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED) + time.sleep(self.device_startup_offset) + s_id = s_dut.droid.wifiAwareAttach(False) + autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED) + + # Publisher: start publish and wait for confirmation + p_config = self.create_publish_config( + p_dut.aware_capabilities, + ptype, + payload_size, + ttl=0, + term_ind_on=False, + null_match=False) + p_disc_id = p_dut.droid.wifiAwarePublish(p_id, p_config) + autils.wait_for_event(p_dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED) + + # Subscriber: start subscribe and wait for confirmation + s_config = self.create_subscribe_config( + s_dut.aware_capabilities, + stype, + payload_size, + ttl=0, + term_ind_on=False, + null_match=True) + s_disc_id = s_dut.droid.wifiAwareSubscribe(s_id, s_config) + autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED) + + # Subscriber: wait for service discovery + discovery_event = autils.wait_for_event( + s_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) + peer_id_on_sub = discovery_event["data"][ + aconsts.SESSION_CB_KEY_PEER_ID] + + # Subscriber: validate contents of discovery: + # - SSI: publisher's + # - Match filter: UNSOLICITED - publisher, SOLICITED - subscriber + autils.assert_equal_strings( + bytes(discovery_event["data"][ + aconsts.SESSION_CB_KEY_SERVICE_SPECIFIC_INFO]).decode("utf-8"), + p_config[aconsts.DISCOVERY_KEY_SSI], + "Discovery mismatch: service specific info (SSI)") + asserts.assert_equal( + autils.decode_list(discovery_event["data"][ + aconsts.SESSION_CB_KEY_MATCH_FILTER_LIST]), + autils.decode_list( + p_config[aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST] + if ptype == aconsts.PUBLISH_TYPE_UNSOLICITED else s_config[ + aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST]), + "Discovery mismatch: match filter") + + # Subscriber: send message to peer (Publisher) + s_dut.droid.wifiAwareSendMessage(s_disc_id, peer_id_on_sub, + self.get_next_msg_id(), + self.query_msg, self.msg_retx_count) + autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_MESSAGE_SENT) + + # Publisher: wait for received message + pub_rx_msg_event = autils.wait_for_event( + p_dut, aconsts.SESSION_CB_ON_MESSAGE_RECEIVED) + peer_id_on_pub = pub_rx_msg_event["data"][ + aconsts.SESSION_CB_KEY_PEER_ID] + + # Publisher: validate contents of message + asserts.assert_equal( + pub_rx_msg_event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING], + self.query_msg, "Subscriber -> Publisher message corrupted") + + # Publisher: send message to peer (Subscriber) + p_dut.droid.wifiAwareSendMessage(p_disc_id, peer_id_on_pub, + self.get_next_msg_id(), + self.response_msg, + self.msg_retx_count) + autils.wait_for_event(p_dut, aconsts.SESSION_CB_ON_MESSAGE_SENT) + + # Subscriber: wait for received message + sub_rx_msg_event = autils.wait_for_event( + s_dut, aconsts.SESSION_CB_ON_MESSAGE_RECEIVED) + + # Subscriber: validate contents of message + asserts.assert_equal( + sub_rx_msg_event["data"][aconsts.SESSION_CB_KEY_PEER_ID], + peer_id_on_sub, + "Subscriber received message from different peer ID then discovery!?" + ) + autils.assert_equal_strings( + sub_rx_msg_event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING], + self.response_msg, "Publisher -> Subscriber message corrupted") + + # Subscriber: validate that we're not getting another Service Discovery + autils.fail_on_event(s_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) + + # Publisher: update publish and wait for confirmation + p_config[aconsts.DISCOVERY_KEY_SSI] = "something else" + p_dut.droid.wifiAwareUpdatePublish(p_disc_id, p_config) + autils.wait_for_event(p_dut, + aconsts.SESSION_CB_ON_SESSION_CONFIG_UPDATED) + + # Subscriber: expect a new service discovery + discovery_event = autils.wait_for_event( + s_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) + + # Subscriber: validate contents of discovery + autils.assert_equal_strings( + bytes(discovery_event["data"][ + aconsts.SESSION_CB_KEY_SERVICE_SPECIFIC_INFO]).decode("utf-8"), + p_config[aconsts.DISCOVERY_KEY_SSI], + "Discovery mismatch (after pub update): service specific info (SSI)" + ) + asserts.assert_equal( + autils.decode_list(discovery_event["data"][ + aconsts.SESSION_CB_KEY_MATCH_FILTER_LIST]), + autils.decode_list( + p_config[aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST] + if ptype == aconsts.PUBLISH_TYPE_UNSOLICITED else s_config[ + aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST]), + "Discovery mismatch: match filter") + + # Subscribe: update subscribe and wait for confirmation + s_config = self.create_subscribe_config( + s_dut.aware_capabilities, + stype, + payload_size, + ttl=0, + term_ind_on=False, + null_match=False) + s_dut.droid.wifiAwareUpdateSubscribe(s_disc_id, s_config) + autils.wait_for_event(s_dut, + aconsts.SESSION_CB_ON_SESSION_CONFIG_UPDATED) + + # Publisher+Subscriber: Terminate sessions + p_dut.droid.wifiAwareDestroyDiscoverySession(p_disc_id) + s_dut.droid.wifiAwareDestroyDiscoverySession(s_disc_id) + + # sleep for timeout period and then verify all 'fail_on_event' together + time.sleep(autils.EVENT_TIMEOUT) + + # verify that there were no other events + autils.verify_no_more_events(p_dut, timeout=0) + autils.verify_no_more_events(s_dut, timeout=0) + + # verify that forbidden callbacks aren't called + autils.validate_forbidden_callbacks(p_dut, {aconsts.CB_EV_MATCH: 0}) + + def verify_discovery_session_term(self, dut, disc_id, config, is_publish, + term_ind_on): + """Utility to verify that the specified discovery session has terminated (by waiting for the TTL and then attempting to reconfigure). Args: @@ -293,41 +306,41 @@ class DiscoveryTest(AwareBaseTest): is_publish: True if the configuration was publish, False if subscribe term_ind_on: True if a termination indication is expected, False otherwise """ - # Wait for session termination - if term_ind_on: - autils.wait_for_event( - dut, - autils.decorate_event(aconsts.SESSION_CB_ON_SESSION_TERMINATED, - disc_id)) - else: - # can't defer wait to end since in any case have to wait for session to - # expire - autils.fail_on_event( - dut, - autils.decorate_event(aconsts.SESSION_CB_ON_SESSION_TERMINATED, - disc_id)) - - # Validate that session expired by trying to configure it (expect failure) - config[aconsts.DISCOVERY_KEY_SSI] = "something else" - if is_publish: - dut.droid.wifiAwareUpdatePublish(disc_id, config) - else: - dut.droid.wifiAwareUpdateSubscribe(disc_id, config) - - # The response to update discovery session is: - # term_ind_on=True: session was cleaned-up so won't get an explicit failure, but won't get a - # success either. Can check for no SESSION_CB_ON_SESSION_CONFIG_UPDATED but - # will defer to the end of the test (no events on queue). - # term_ind_on=False: session was not cleaned-up (yet). So expect - # SESSION_CB_ON_SESSION_CONFIG_FAILED. - if not term_ind_on: - autils.wait_for_event( - dut, - autils.decorate_event(aconsts.SESSION_CB_ON_SESSION_CONFIG_FAILED, - disc_id)) - - def positive_ttl_test_utility(self, is_publish, ptype, stype, term_ind_on): - """Utility which runs a positive discovery session TTL configuration test + # Wait for session termination + if term_ind_on: + autils.wait_for_event( + dut, + autils.decorate_event(aconsts.SESSION_CB_ON_SESSION_TERMINATED, + disc_id)) + else: + # can't defer wait to end since in any case have to wait for session to + # expire + autils.fail_on_event( + dut, + autils.decorate_event(aconsts.SESSION_CB_ON_SESSION_TERMINATED, + disc_id)) + + # Validate that session expired by trying to configure it (expect failure) + config[aconsts.DISCOVERY_KEY_SSI] = "something else" + if is_publish: + dut.droid.wifiAwareUpdatePublish(disc_id, config) + else: + dut.droid.wifiAwareUpdateSubscribe(disc_id, config) + + # The response to update discovery session is: + # term_ind_on=True: session was cleaned-up so won't get an explicit failure, but won't get a + # success either. Can check for no SESSION_CB_ON_SESSION_CONFIG_UPDATED but + # will defer to the end of the test (no events on queue). + # term_ind_on=False: session was not cleaned-up (yet). So expect + # SESSION_CB_ON_SESSION_CONFIG_FAILED. + if not term_ind_on: + autils.wait_for_event( + dut, + autils.decorate_event( + aconsts.SESSION_CB_ON_SESSION_CONFIG_FAILED, disc_id)) + + def positive_ttl_test_utility(self, is_publish, ptype, stype, term_ind_on): + """Utility which runs a positive discovery session TTL configuration test Iteration 1: Verify session started with TTL Iteration 2: Verify session started without TTL and reconfigured with TTL @@ -340,119 +353,123 @@ class DiscoveryTest(AwareBaseTest): stype: Subscribe discovery type (used if is_publish is False) term_ind_on: Configuration of termination indication """ - SHORT_TTL = 5 # 5 seconds - LONG_TTL = 100 # 100 seconds - dut = self.android_devices[0] - - # Attach and wait for confirmation - id = dut.droid.wifiAwareAttach(False) - autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) - - # Iteration 1: Start discovery session with TTL - config = self.create_base_config(dut.aware_capabilities, is_publish, ptype, - stype, self.PAYLOAD_SIZE_TYPICAL, - SHORT_TTL, term_ind_on, False) - if is_publish: - disc_id = dut.droid.wifiAwarePublish(id, config, True) - autils.wait_for_event(dut, - autils.decorate_event( - aconsts.SESSION_CB_ON_PUBLISH_STARTED, disc_id)) - else: - disc_id = dut.droid.wifiAwareSubscribe(id, config, True) - autils.wait_for_event( - dut, - autils.decorate_event(aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, - disc_id)) - - # Wait for session termination & verify - self.verify_discovery_session_term(dut, disc_id, config, is_publish, - term_ind_on) - - # Iteration 2: Start a discovery session without TTL - config = self.create_base_config(dut.aware_capabilities, is_publish, ptype, - stype, self.PAYLOAD_SIZE_TYPICAL, 0, - term_ind_on, False) - if is_publish: - disc_id = dut.droid.wifiAwarePublish(id, config, True) - autils.wait_for_event(dut, - autils.decorate_event( - aconsts.SESSION_CB_ON_PUBLISH_STARTED, disc_id)) - else: - disc_id = dut.droid.wifiAwareSubscribe(id, config, True) - autils.wait_for_event( - dut, - autils.decorate_event(aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, - disc_id)) - - # Update with a TTL - config = self.create_base_config(dut.aware_capabilities, is_publish, ptype, - stype, self.PAYLOAD_SIZE_TYPICAL, - SHORT_TTL, term_ind_on, False) - if is_publish: - dut.droid.wifiAwareUpdatePublish(disc_id, config) - else: - dut.droid.wifiAwareUpdateSubscribe(disc_id, config) - autils.wait_for_event( - dut, - autils.decorate_event(aconsts.SESSION_CB_ON_SESSION_CONFIG_UPDATED, - disc_id)) - - # Wait for session termination & verify - self.verify_discovery_session_term(dut, disc_id, config, is_publish, - term_ind_on) - - # Iteration 3: Start a discovery session with (long) TTL - config = self.create_base_config(dut.aware_capabilities, is_publish, ptype, - stype, self.PAYLOAD_SIZE_TYPICAL, LONG_TTL, - term_ind_on, False) - if is_publish: - disc_id = dut.droid.wifiAwarePublish(id, config, True) - autils.wait_for_event(dut, - autils.decorate_event( - aconsts.SESSION_CB_ON_PUBLISH_STARTED, disc_id)) - else: - disc_id = dut.droid.wifiAwareSubscribe(id, config, True) - autils.wait_for_event( - dut, - autils.decorate_event(aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, - disc_id)) - - # Update with a TTL - config = self.create_base_config(dut.aware_capabilities, is_publish, ptype, - stype, self.PAYLOAD_SIZE_TYPICAL, - SHORT_TTL, term_ind_on, False) - if is_publish: - dut.droid.wifiAwareUpdatePublish(disc_id, config) - else: - dut.droid.wifiAwareUpdateSubscribe(disc_id, config) - autils.wait_for_event( - dut, - autils.decorate_event(aconsts.SESSION_CB_ON_SESSION_CONFIG_UPDATED, - disc_id)) - - # Wait for session termination & verify - self.verify_discovery_session_term(dut, disc_id, config, is_publish, - term_ind_on) - - # verify that there were no other events - autils.verify_no_more_events(dut) - - # verify that forbidden callbacks aren't called - if not term_ind_on: - autils.validate_forbidden_callbacks(dut, { - aconsts.CB_EV_PUBLISH_TERMINATED: 0, - aconsts.CB_EV_SUBSCRIBE_TERMINATED: 0 - }) - - def discovery_mismatch_test_utility(self, - is_expected_to_pass, - p_type, - s_type, - p_service_name=None, - s_service_name=None, - p_mf_1=None, - s_mf_1=None): - """Utility which runs the negative discovery test for mismatched service + SHORT_TTL = 5 # 5 seconds + LONG_TTL = 100 # 100 seconds + dut = self.android_devices[0] + + # Attach and wait for confirmation + id = dut.droid.wifiAwareAttach(False) + autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) + + # Iteration 1: Start discovery session with TTL + config = self.create_base_config( + dut.aware_capabilities, is_publish, ptype, stype, + self.PAYLOAD_SIZE_TYPICAL, SHORT_TTL, term_ind_on, False) + if is_publish: + disc_id = dut.droid.wifiAwarePublish(id, config, True) + autils.wait_for_event( + dut, + autils.decorate_event(aconsts.SESSION_CB_ON_PUBLISH_STARTED, + disc_id)) + else: + disc_id = dut.droid.wifiAwareSubscribe(id, config, True) + autils.wait_for_event( + dut, + autils.decorate_event(aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, + disc_id)) + + # Wait for session termination & verify + self.verify_discovery_session_term(dut, disc_id, config, is_publish, + term_ind_on) + + # Iteration 2: Start a discovery session without TTL + config = self.create_base_config( + dut.aware_capabilities, is_publish, ptype, stype, + self.PAYLOAD_SIZE_TYPICAL, 0, term_ind_on, False) + if is_publish: + disc_id = dut.droid.wifiAwarePublish(id, config, True) + autils.wait_for_event( + dut, + autils.decorate_event(aconsts.SESSION_CB_ON_PUBLISH_STARTED, + disc_id)) + else: + disc_id = dut.droid.wifiAwareSubscribe(id, config, True) + autils.wait_for_event( + dut, + autils.decorate_event(aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, + disc_id)) + + # Update with a TTL + config = self.create_base_config( + dut.aware_capabilities, is_publish, ptype, stype, + self.PAYLOAD_SIZE_TYPICAL, SHORT_TTL, term_ind_on, False) + if is_publish: + dut.droid.wifiAwareUpdatePublish(disc_id, config) + else: + dut.droid.wifiAwareUpdateSubscribe(disc_id, config) + autils.wait_for_event( + dut, + autils.decorate_event(aconsts.SESSION_CB_ON_SESSION_CONFIG_UPDATED, + disc_id)) + + # Wait for session termination & verify + self.verify_discovery_session_term(dut, disc_id, config, is_publish, + term_ind_on) + + # Iteration 3: Start a discovery session with (long) TTL + config = self.create_base_config( + dut.aware_capabilities, is_publish, ptype, stype, + self.PAYLOAD_SIZE_TYPICAL, LONG_TTL, term_ind_on, False) + if is_publish: + disc_id = dut.droid.wifiAwarePublish(id, config, True) + autils.wait_for_event( + dut, + autils.decorate_event(aconsts.SESSION_CB_ON_PUBLISH_STARTED, + disc_id)) + else: + disc_id = dut.droid.wifiAwareSubscribe(id, config, True) + autils.wait_for_event( + dut, + autils.decorate_event(aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, + disc_id)) + + # Update with a TTL + config = self.create_base_config( + dut.aware_capabilities, is_publish, ptype, stype, + self.PAYLOAD_SIZE_TYPICAL, SHORT_TTL, term_ind_on, False) + if is_publish: + dut.droid.wifiAwareUpdatePublish(disc_id, config) + else: + dut.droid.wifiAwareUpdateSubscribe(disc_id, config) + autils.wait_for_event( + dut, + autils.decorate_event(aconsts.SESSION_CB_ON_SESSION_CONFIG_UPDATED, + disc_id)) + + # Wait for session termination & verify + self.verify_discovery_session_term(dut, disc_id, config, is_publish, + term_ind_on) + + # verify that there were no other events + autils.verify_no_more_events(dut) + + # verify that forbidden callbacks aren't called + if not term_ind_on: + autils.validate_forbidden_callbacks( + dut, { + aconsts.CB_EV_PUBLISH_TERMINATED: 0, + aconsts.CB_EV_SUBSCRIBE_TERMINATED: 0 + }) + + def discovery_mismatch_test_utility(self, + is_expected_to_pass, + p_type, + s_type, + p_service_name=None, + s_service_name=None, + p_mf_1=None, + s_mf_1=None): + """Utility which runs the negative discovery test for mismatched service configs. Args: @@ -464,378 +481,379 @@ class DiscoveryTest(AwareBaseTest): p_mf_1: Publish match filter element [1] (or None to leave unchanged) s_mf_1: Subscribe match filter element [1] (or None to leave unchanged) """ - p_dut = self.android_devices[0] - p_dut.pretty_name = "Publisher" - s_dut = self.android_devices[1] - s_dut.pretty_name = "Subscriber" - - # create configurations - p_config = self.create_publish_config( - p_dut.aware_capabilities, - p_type, - self.PAYLOAD_SIZE_TYPICAL, - ttl=0, - term_ind_on=False, - null_match=False) - if p_service_name is not None: - p_config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = p_service_name - if p_mf_1 is not None: - p_config[aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST] = autils.encode_list( - [(10).to_bytes(1, byteorder="big"), - p_mf_1, - bytes(range(40))]) - s_config = self.create_publish_config( - s_dut.aware_capabilities, - s_type, - self.PAYLOAD_SIZE_TYPICAL, - ttl=0, - term_ind_on=False, - null_match=False) - if s_service_name is not None: - s_config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = s_service_name - if s_mf_1 is not None: - s_config[aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST] = autils.encode_list( - [(10).to_bytes(1, byteorder="big"), - s_mf_1, - bytes(range(40))]) - - p_id = p_dut.droid.wifiAwareAttach(False) - autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED) - time.sleep(self.device_startup_offset) - s_id = s_dut.droid.wifiAwareAttach(False) - autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED) - - # Publisher: start publish and wait for confirmation - p_disc_id = p_dut.droid.wifiAwarePublish(p_id, p_config) - autils.wait_for_event(p_dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED) - - # Subscriber: start subscribe and wait for confirmation - s_disc_id = s_dut.droid.wifiAwareSubscribe(s_id, s_config) - autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED) - - # Subscriber: fail on service discovery - if is_expected_to_pass: - autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) - else: - autils.fail_on_event(s_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) - - # Publisher+Subscriber: Terminate sessions - p_dut.droid.wifiAwareDestroyDiscoverySession(p_disc_id) - s_dut.droid.wifiAwareDestroyDiscoverySession(s_disc_id) - - # verify that there were no other events (including terminations) - time.sleep(autils.EVENT_TIMEOUT) - autils.verify_no_more_events(p_dut, timeout=0) - autils.verify_no_more_events(s_dut, timeout=0) - - - ####################################### - # Positive tests key: - # - # names is: test_<pub_type>_<sub_type>_<size> - # where: - # - # pub_type: Type of publish discovery session: unsolicited or solicited. - # sub_type: Type of subscribe discovery session: passive or active. - # size: Size of payload fields (service name, service specific info, and match - # filter: typical, max, or min. - ####################################### - - @test_tracker_info(uuid="954ebbde-ed2b-4f04-9e68-88239187d69d") - def test_positive_unsolicited_passive_typical(self): - """Functional test case / Discovery test cases / positive test case: + p_dut = self.android_devices[0] + p_dut.pretty_name = "Publisher" + s_dut = self.android_devices[1] + s_dut.pretty_name = "Subscriber" + + # create configurations + p_config = self.create_publish_config( + p_dut.aware_capabilities, + p_type, + self.PAYLOAD_SIZE_TYPICAL, + ttl=0, + term_ind_on=False, + null_match=False) + if p_service_name is not None: + p_config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = p_service_name + if p_mf_1 is not None: + p_config[ + aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST] = autils.encode_list( + [(10).to_bytes(1, byteorder="big"), p_mf_1, + bytes(range(40))]) + s_config = self.create_publish_config( + s_dut.aware_capabilities, + s_type, + self.PAYLOAD_SIZE_TYPICAL, + ttl=0, + term_ind_on=False, + null_match=False) + if s_service_name is not None: + s_config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = s_service_name + if s_mf_1 is not None: + s_config[ + aconsts.DISCOVERY_KEY_MATCH_FILTER_LIST] = autils.encode_list( + [(10).to_bytes(1, byteorder="big"), s_mf_1, + bytes(range(40))]) + + p_id = p_dut.droid.wifiAwareAttach(False) + autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED) + time.sleep(self.device_startup_offset) + s_id = s_dut.droid.wifiAwareAttach(False) + autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED) + + # Publisher: start publish and wait for confirmation + p_disc_id = p_dut.droid.wifiAwarePublish(p_id, p_config) + autils.wait_for_event(p_dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED) + + # Subscriber: start subscribe and wait for confirmation + s_disc_id = s_dut.droid.wifiAwareSubscribe(s_id, s_config) + autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED) + + # Subscriber: fail on service discovery + if is_expected_to_pass: + autils.wait_for_event(s_dut, + aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) + else: + autils.fail_on_event(s_dut, + aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) + + # Publisher+Subscriber: Terminate sessions + p_dut.droid.wifiAwareDestroyDiscoverySession(p_disc_id) + s_dut.droid.wifiAwareDestroyDiscoverySession(s_disc_id) + + # verify that there were no other events (including terminations) + time.sleep(autils.EVENT_TIMEOUT) + autils.verify_no_more_events(p_dut, timeout=0) + autils.verify_no_more_events(s_dut, timeout=0) + + ####################################### + # Positive tests key: + # + # names is: test_<pub_type>_<sub_type>_<size> + # where: + # + # pub_type: Type of publish discovery session: unsolicited or solicited. + # sub_type: Type of subscribe discovery session: passive or active. + # size: Size of payload fields (service name, service specific info, and match + # filter: typical, max, or min. + ####################################### + + @test_tracker_info(uuid="954ebbde-ed2b-4f04-9e68-88239187d69d") + def test_positive_unsolicited_passive_typical(self): + """Functional test case / Discovery test cases / positive test case: - Solicited publish + passive subscribe - Typical payload fields size Verifies that discovery and message exchange succeeds. """ - self.positive_discovery_test_utility( - ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, - stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, - payload_size=self.PAYLOAD_SIZE_TYPICAL) - - @test_tracker_info(uuid="67fb22bb-6985-4345-95a4-90b76681a58b") - def test_positive_unsolicited_passive_min(self): - """Functional test case / Discovery test cases / positive test case: + self.positive_discovery_test_utility( + ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, + stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, + payload_size=self.PAYLOAD_SIZE_TYPICAL) + + @test_tracker_info(uuid="67fb22bb-6985-4345-95a4-90b76681a58b") + def test_positive_unsolicited_passive_min(self): + """Functional test case / Discovery test cases / positive test case: - Solicited publish + passive subscribe - Minimal payload fields size Verifies that discovery and message exchange succeeds. """ - self.positive_discovery_test_utility( - ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, - stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, - payload_size=self.PAYLOAD_SIZE_MIN) - - @test_tracker_info(uuid="a02a47b9-41bb-47bb-883b-921024a2c30d") - def test_positive_unsolicited_passive_max(self): - """Functional test case / Discovery test cases / positive test case: + self.positive_discovery_test_utility( + ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, + stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, + payload_size=self.PAYLOAD_SIZE_MIN) + + @test_tracker_info(uuid="a02a47b9-41bb-47bb-883b-921024a2c30d") + def test_positive_unsolicited_passive_max(self): + """Functional test case / Discovery test cases / positive test case: - Solicited publish + passive subscribe - Maximal payload fields size Verifies that discovery and message exchange succeeds. """ - self.positive_discovery_test_utility( - ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, - stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, - payload_size=self.PAYLOAD_SIZE_MAX) - - @test_tracker_info(uuid="586c657f-2388-4e7a-baee-9bce2f3d1a16") - def test_positive_solicited_active_typical(self): - """Functional test case / Discovery test cases / positive test case: + self.positive_discovery_test_utility( + ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, + stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, + payload_size=self.PAYLOAD_SIZE_MAX) + + @test_tracker_info(uuid="586c657f-2388-4e7a-baee-9bce2f3d1a16") + def test_positive_solicited_active_typical(self): + """Functional test case / Discovery test cases / positive test case: - Unsolicited publish + active subscribe - Typical payload fields size Verifies that discovery and message exchange succeeds. """ - self.positive_discovery_test_utility( - ptype=aconsts.PUBLISH_TYPE_SOLICITED, - stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, - payload_size=self.PAYLOAD_SIZE_TYPICAL) - - @test_tracker_info(uuid="5369e4ff-f406-48c5-b41a-df38ec340146") - def test_positive_solicited_active_min(self): - """Functional test case / Discovery test cases / positive test case: + self.positive_discovery_test_utility( + ptype=aconsts.PUBLISH_TYPE_SOLICITED, + stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, + payload_size=self.PAYLOAD_SIZE_TYPICAL) + + @test_tracker_info(uuid="5369e4ff-f406-48c5-b41a-df38ec340146") + def test_positive_solicited_active_min(self): + """Functional test case / Discovery test cases / positive test case: - Unsolicited publish + active subscribe - Minimal payload fields size Verifies that discovery and message exchange succeeds. """ - self.positive_discovery_test_utility( - ptype=aconsts.PUBLISH_TYPE_SOLICITED, - stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, - payload_size=self.PAYLOAD_SIZE_MIN) - - @test_tracker_info(uuid="634c6eb8-2c4f-42bd-9bbb-d874d0ec22f3") - def test_positive_solicited_active_max(self): - """Functional test case / Discovery test cases / positive test case: + self.positive_discovery_test_utility( + ptype=aconsts.PUBLISH_TYPE_SOLICITED, + stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, + payload_size=self.PAYLOAD_SIZE_MIN) + + @test_tracker_info(uuid="634c6eb8-2c4f-42bd-9bbb-d874d0ec22f3") + def test_positive_solicited_active_max(self): + """Functional test case / Discovery test cases / positive test case: - Unsolicited publish + active subscribe - Maximal payload fields size Verifies that discovery and message exchange succeeds. """ - self.positive_discovery_test_utility( - ptype=aconsts.PUBLISH_TYPE_SOLICITED, - stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, - payload_size=self.PAYLOAD_SIZE_MAX) - - ####################################### - # TTL tests key: - # - # names is: test_ttl_<pub_type|sub_type>_<term_ind> - # where: - # - # pub_type: Type of publish discovery session: unsolicited or solicited. - # sub_type: Type of subscribe discovery session: passive or active. - # term_ind: ind_on or ind_off - ####################################### - - @test_tracker_info(uuid="9d7e758e-e0e2-4550-bcee-bfb6a2bff63e") - def test_ttl_unsolicited_ind_on(self): - """Functional test case / Discovery test cases / TTL test case: + self.positive_discovery_test_utility( + ptype=aconsts.PUBLISH_TYPE_SOLICITED, + stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, + payload_size=self.PAYLOAD_SIZE_MAX) + + ####################################### + # TTL tests key: + # + # names is: test_ttl_<pub_type|sub_type>_<term_ind> + # where: + # + # pub_type: Type of publish discovery session: unsolicited or solicited. + # sub_type: Type of subscribe discovery session: passive or active. + # term_ind: ind_on or ind_off + ####################################### + + @test_tracker_info(uuid="9d7e758e-e0e2-4550-bcee-bfb6a2bff63e") + def test_ttl_unsolicited_ind_on(self): + """Functional test case / Discovery test cases / TTL test case: - Unsolicited publish - Termination indication enabled """ - self.positive_ttl_test_utility( - is_publish=True, - ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, - stype=None, - term_ind_on=True) - - @test_tracker_info(uuid="48fd69bc-cc2a-4f65-a0a1-63d7c1720702") - def test_ttl_unsolicited_ind_off(self): - """Functional test case / Discovery test cases / TTL test case: + self.positive_ttl_test_utility( + is_publish=True, + ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, + stype=None, + term_ind_on=True) + + @test_tracker_info(uuid="48fd69bc-cc2a-4f65-a0a1-63d7c1720702") + def test_ttl_unsolicited_ind_off(self): + """Functional test case / Discovery test cases / TTL test case: - Unsolicited publish - Termination indication disabled """ - self.positive_ttl_test_utility( - is_publish=True, - ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, - stype=None, - term_ind_on=False) - - @test_tracker_info(uuid="afb75fc1-9ba7-446a-b5ed-7cd37ab51b1c") - def test_ttl_solicited_ind_on(self): - """Functional test case / Discovery test cases / TTL test case: + self.positive_ttl_test_utility( + is_publish=True, + ptype=aconsts.PUBLISH_TYPE_UNSOLICITED, + stype=None, + term_ind_on=False) + + @test_tracker_info(uuid="afb75fc1-9ba7-446a-b5ed-7cd37ab51b1c") + def test_ttl_solicited_ind_on(self): + """Functional test case / Discovery test cases / TTL test case: - Solicited publish - Termination indication enabled """ - self.positive_ttl_test_utility( - is_publish=True, - ptype=aconsts.PUBLISH_TYPE_SOLICITED, - stype=None, - term_ind_on=True) - - @test_tracker_info(uuid="703311a6-e444-4055-94ee-ea9b9b71799e") - def test_ttl_solicited_ind_off(self): - """Functional test case / Discovery test cases / TTL test case: + self.positive_ttl_test_utility( + is_publish=True, + ptype=aconsts.PUBLISH_TYPE_SOLICITED, + stype=None, + term_ind_on=True) + + @test_tracker_info(uuid="703311a6-e444-4055-94ee-ea9b9b71799e") + def test_ttl_solicited_ind_off(self): + """Functional test case / Discovery test cases / TTL test case: - Solicited publish - Termination indication disabled """ - self.positive_ttl_test_utility( - is_publish=True, - ptype=aconsts.PUBLISH_TYPE_SOLICITED, - stype=None, - term_ind_on=False) - - @test_tracker_info(uuid="38a541c4-ff55-4387-87b7-4d940489da9d") - def test_ttl_passive_ind_on(self): - """Functional test case / Discovery test cases / TTL test case: + self.positive_ttl_test_utility( + is_publish=True, + ptype=aconsts.PUBLISH_TYPE_SOLICITED, + stype=None, + term_ind_on=False) + + @test_tracker_info(uuid="38a541c4-ff55-4387-87b7-4d940489da9d") + def test_ttl_passive_ind_on(self): + """Functional test case / Discovery test cases / TTL test case: - Passive subscribe - Termination indication enabled """ - self.positive_ttl_test_utility( - is_publish=False, - ptype=None, - stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, - term_ind_on=True) - - @test_tracker_info(uuid="ba971e12-b0ca-417c-a1b5-9451598de47d") - def test_ttl_passive_ind_off(self): - """Functional test case / Discovery test cases / TTL test case: + self.positive_ttl_test_utility( + is_publish=False, + ptype=None, + stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, + term_ind_on=True) + + @test_tracker_info(uuid="ba971e12-b0ca-417c-a1b5-9451598de47d") + def test_ttl_passive_ind_off(self): + """Functional test case / Discovery test cases / TTL test case: - Passive subscribe - Termination indication disabled """ - self.positive_ttl_test_utility( - is_publish=False, - ptype=None, - stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, - term_ind_on=False) - - @test_tracker_info(uuid="7b5d96f2-2415-4b98-9a51-32957f0679a0") - def test_ttl_active_ind_on(self): - """Functional test case / Discovery test cases / TTL test case: + self.positive_ttl_test_utility( + is_publish=False, + ptype=None, + stype=aconsts.SUBSCRIBE_TYPE_PASSIVE, + term_ind_on=False) + + @test_tracker_info(uuid="7b5d96f2-2415-4b98-9a51-32957f0679a0") + def test_ttl_active_ind_on(self): + """Functional test case / Discovery test cases / TTL test case: - Active subscribe - Termination indication enabled """ - self.positive_ttl_test_utility( - is_publish=False, - ptype=None, - stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, - term_ind_on=True) - - @test_tracker_info(uuid="c9268eca-0a30-42dd-8e6c-b8b0b84697fb") - def test_ttl_active_ind_off(self): - """Functional test case / Discovery test cases / TTL test case: + self.positive_ttl_test_utility( + is_publish=False, + ptype=None, + stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, + term_ind_on=True) + + @test_tracker_info(uuid="c9268eca-0a30-42dd-8e6c-b8b0b84697fb") + def test_ttl_active_ind_off(self): + """Functional test case / Discovery test cases / TTL test case: - Active subscribe - Termination indication disabled """ - self.positive_ttl_test_utility( - is_publish=False, - ptype=None, - stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, - term_ind_on=False) - - ####################################### - # Mismatched service name tests key: - # - # names is: test_mismatch_service_name_<pub_type>_<sub_type> - # where: - # - # pub_type: Type of publish discovery session: unsolicited or solicited. - # sub_type: Type of subscribe discovery session: passive or active. - ####################################### - - @test_tracker_info(uuid="175415e9-7d07-40d0-95f0-3a5f91ea4711") - def test_mismatch_service_name_unsolicited_passive(self): - """Functional test case / Discovery test cases / Mismatch service name + self.positive_ttl_test_utility( + is_publish=False, + ptype=None, + stype=aconsts.SUBSCRIBE_TYPE_ACTIVE, + term_ind_on=False) + + ####################################### + # Mismatched service name tests key: + # + # names is: test_mismatch_service_name_<pub_type>_<sub_type> + # where: + # + # pub_type: Type of publish discovery session: unsolicited or solicited. + # sub_type: Type of subscribe discovery session: passive or active. + ####################################### + + @test_tracker_info(uuid="175415e9-7d07-40d0-95f0-3a5f91ea4711") + def test_mismatch_service_name_unsolicited_passive(self): + """Functional test case / Discovery test cases / Mismatch service name - Unsolicited publish - Passive subscribe """ - self.discovery_mismatch_test_utility( - is_expected_to_pass=False, - p_type=aconsts.PUBLISH_TYPE_UNSOLICITED, - s_type=aconsts.SUBSCRIBE_TYPE_PASSIVE, - p_service_name="GoogleTestServiceXXX", - s_service_name="GoogleTestServiceYYY") - - @test_tracker_info(uuid="c22a54ce-9e46-47a5-ac44-831faf93d317") - def test_mismatch_service_name_solicited_active(self): - """Functional test case / Discovery test cases / Mismatch service name + self.discovery_mismatch_test_utility( + is_expected_to_pass=False, + p_type=aconsts.PUBLISH_TYPE_UNSOLICITED, + s_type=aconsts.SUBSCRIBE_TYPE_PASSIVE, + p_service_name="GoogleTestServiceXXX", + s_service_name="GoogleTestServiceYYY") + + @test_tracker_info(uuid="c22a54ce-9e46-47a5-ac44-831faf93d317") + def test_mismatch_service_name_solicited_active(self): + """Functional test case / Discovery test cases / Mismatch service name - Solicited publish - Active subscribe """ - self.discovery_mismatch_test_utility( - is_expected_to_pass=False, - p_type=aconsts.PUBLISH_TYPE_SOLICITED, - s_type=aconsts.SUBSCRIBE_TYPE_ACTIVE, - p_service_name="GoogleTestServiceXXX", - s_service_name="GoogleTestServiceYYY") - - ####################################### - # Mismatched discovery session type tests key: - # - # names is: test_mismatch_service_type_<pub_type>_<sub_type> - # where: - # - # pub_type: Type of publish discovery session: unsolicited or solicited. - # sub_type: Type of subscribe discovery session: passive or active. - ####################################### - - @test_tracker_info(uuid="4806f631-d9eb-45fd-9e75-24674962770f") - def test_mismatch_service_type_unsolicited_active(self): - """Functional test case / Discovery test cases / Mismatch service name + self.discovery_mismatch_test_utility( + is_expected_to_pass=False, + p_type=aconsts.PUBLISH_TYPE_SOLICITED, + s_type=aconsts.SUBSCRIBE_TYPE_ACTIVE, + p_service_name="GoogleTestServiceXXX", + s_service_name="GoogleTestServiceYYY") + + ####################################### + # Mismatched discovery session type tests key: + # + # names is: test_mismatch_service_type_<pub_type>_<sub_type> + # where: + # + # pub_type: Type of publish discovery session: unsolicited or solicited. + # sub_type: Type of subscribe discovery session: passive or active. + ####################################### + + @test_tracker_info(uuid="4806f631-d9eb-45fd-9e75-24674962770f") + def test_mismatch_service_type_unsolicited_active(self): + """Functional test case / Discovery test cases / Mismatch service name - Unsolicited publish - Active subscribe """ - self.discovery_mismatch_test_utility( - is_expected_to_pass=True, - p_type=aconsts.PUBLISH_TYPE_UNSOLICITED, - s_type=aconsts.SUBSCRIBE_TYPE_ACTIVE) - - @test_tracker_info(uuid="12d648fd-b8fa-4c0f-9467-95e2366047de") - def test_mismatch_service_type_solicited_passive(self): - """Functional test case / Discovery test cases / Mismatch service name + self.discovery_mismatch_test_utility( + is_expected_to_pass=True, + p_type=aconsts.PUBLISH_TYPE_UNSOLICITED, + s_type=aconsts.SUBSCRIBE_TYPE_ACTIVE) + + @test_tracker_info(uuid="12d648fd-b8fa-4c0f-9467-95e2366047de") + def test_mismatch_service_type_solicited_passive(self): + """Functional test case / Discovery test cases / Mismatch service name - Unsolicited publish - Active subscribe """ - self.discovery_mismatch_test_utility( - is_expected_to_pass=False, - p_type=aconsts.PUBLISH_TYPE_SOLICITED, - s_type=aconsts.SUBSCRIBE_TYPE_PASSIVE) - - ####################################### - # Mismatched discovery match filter tests key: - # - # names is: test_mismatch_match_filter_<pub_type>_<sub_type> - # where: - # - # pub_type: Type of publish discovery session: unsolicited or solicited. - # sub_type: Type of subscribe discovery session: passive or active. - ####################################### - - @test_tracker_info(uuid="d98454cb-64af-4266-8fed-f0b545a2d7c4") - def test_mismatch_match_filter_unsolicited_passive(self): - """Functional test case / Discovery test cases / Mismatch match filter + self.discovery_mismatch_test_utility( + is_expected_to_pass=False, + p_type=aconsts.PUBLISH_TYPE_SOLICITED, + s_type=aconsts.SUBSCRIBE_TYPE_PASSIVE) + + ####################################### + # Mismatched discovery match filter tests key: + # + # names is: test_mismatch_match_filter_<pub_type>_<sub_type> + # where: + # + # pub_type: Type of publish discovery session: unsolicited or solicited. + # sub_type: Type of subscribe discovery session: passive or active. + ####################################### + + @test_tracker_info(uuid="d98454cb-64af-4266-8fed-f0b545a2d7c4") + def test_mismatch_match_filter_unsolicited_passive(self): + """Functional test case / Discovery test cases / Mismatch match filter - Unsolicited publish - Passive subscribe """ - self.discovery_mismatch_test_utility( - is_expected_to_pass=False, - p_type=aconsts.PUBLISH_TYPE_UNSOLICITED, - s_type=aconsts.SUBSCRIBE_TYPE_PASSIVE, - p_mf_1="hello there string", - s_mf_1="goodbye there string") - - @test_tracker_info(uuid="663c1008-ae11-4e1a-87c7-c311d83f481c") - def test_mismatch_match_filter_solicited_active(self): - """Functional test case / Discovery test cases / Mismatch match filter + self.discovery_mismatch_test_utility( + is_expected_to_pass=False, + p_type=aconsts.PUBLISH_TYPE_UNSOLICITED, + s_type=aconsts.SUBSCRIBE_TYPE_PASSIVE, + p_mf_1="hello there string", + s_mf_1="goodbye there string") + + @test_tracker_info(uuid="663c1008-ae11-4e1a-87c7-c311d83f481c") + def test_mismatch_match_filter_solicited_active(self): + """Functional test case / Discovery test cases / Mismatch match filter - Solicited publish - Active subscribe """ - self.discovery_mismatch_test_utility( - is_expected_to_pass=False, - p_type=aconsts.PUBLISH_TYPE_SOLICITED, - s_type=aconsts.SUBSCRIBE_TYPE_ACTIVE, - p_mf_1="hello there string", - s_mf_1="goodbye there string") - - ####################################### - # Multiple concurrent services - ####################################### - - def run_multiple_concurrent_services(self, type_x, type_y): - """Validate multiple identical discovery services running on both devices: + self.discovery_mismatch_test_utility( + is_expected_to_pass=False, + p_type=aconsts.PUBLISH_TYPE_SOLICITED, + s_type=aconsts.SUBSCRIBE_TYPE_ACTIVE, + p_mf_1="hello there string", + s_mf_1="goodbye there string") + + ####################################### + # Multiple concurrent services + ####################################### + + def run_multiple_concurrent_services(self, type_x, type_y): + """Validate multiple identical discovery services running on both devices: - DUT1 & DUT2 running Publish for X - DUT1 & DUT2 running Publish for Y - DUT1 Subscribes for X @@ -849,117 +867,118 @@ class DiscoveryTest(AwareBaseTest): type_x, type_y: A list of [ptype, stype] of the publish and subscribe types for services X and Y respectively. """ - dut1 = self.android_devices[0] - dut2 = self.android_devices[1] - - X_SERVICE_NAME = "ServiceXXX" - Y_SERVICE_NAME = "ServiceYYY" - - asserts.skip_if(dut1.aware_capabilities[aconsts.CAP_MAX_PUBLISHES] < 2 or - dut2.aware_capabilities[aconsts.CAP_MAX_PUBLISHES] < 2, - "Devices do not support 2 publish sessions") - - # attach and wait for confirmation - id1 = dut1.droid.wifiAwareAttach(False) - autils.wait_for_event(dut1, aconsts.EVENT_CB_ON_ATTACHED) - time.sleep(self.device_startup_offset) - id2 = dut2.droid.wifiAwareAttach(False) - autils.wait_for_event(dut2, aconsts.EVENT_CB_ON_ATTACHED) - - # DUT1 & DUT2: start publishing both X & Y services and wait for - # confirmations - dut1_x_pid = dut1.droid.wifiAwarePublish(id1, - autils.create_discovery_config( - X_SERVICE_NAME, type_x[0])) - event = autils.wait_for_event(dut1, aconsts.SESSION_CB_ON_PUBLISH_STARTED) - asserts.assert_equal(event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], - dut1_x_pid, - "Unexpected DUT1 X publish session discovery ID") - - dut1_y_pid = dut1.droid.wifiAwarePublish(id1, - autils.create_discovery_config( - Y_SERVICE_NAME, type_y[0])) - event = autils.wait_for_event(dut1, aconsts.SESSION_CB_ON_PUBLISH_STARTED) - asserts.assert_equal(event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], - dut1_y_pid, - "Unexpected DUT1 Y publish session discovery ID") - - dut2_x_pid = dut2.droid.wifiAwarePublish(id2, - autils.create_discovery_config( - X_SERVICE_NAME, type_x[0])) - event = autils.wait_for_event(dut2, aconsts.SESSION_CB_ON_PUBLISH_STARTED) - asserts.assert_equal(event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], - dut2_x_pid, - "Unexpected DUT2 X publish session discovery ID") - - dut2_y_pid = dut2.droid.wifiAwarePublish(id2, - autils.create_discovery_config( - Y_SERVICE_NAME, type_y[0])) - event = autils.wait_for_event(dut2, aconsts.SESSION_CB_ON_PUBLISH_STARTED) - asserts.assert_equal(event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], - dut2_y_pid, - "Unexpected DUT2 Y publish session discovery ID") - - # DUT1: start subscribing for X - dut1_x_sid = dut1.droid.wifiAwareSubscribe(id1, - autils.create_discovery_config( - X_SERVICE_NAME, type_x[1])) - autils.wait_for_event(dut1, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED) - - # DUT2: start subscribing for Y - dut2_y_sid = dut2.droid.wifiAwareSubscribe(id2, - autils.create_discovery_config( - Y_SERVICE_NAME, type_y[1])) - autils.wait_for_event(dut2, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED) - - # DUT1 & DUT2: wait for service discovery - event = autils.wait_for_event(dut1, - aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) - asserts.assert_equal(event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], - dut1_x_sid, - "Unexpected DUT1 X subscribe session discovery ID") - dut1_peer_id_for_dut2_x = event["data"][aconsts.SESSION_CB_KEY_PEER_ID] - - event = autils.wait_for_event(dut2, - aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) - asserts.assert_equal(event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], - dut2_y_sid, - "Unexpected DUT2 Y subscribe session discovery ID") - dut2_peer_id_for_dut1_y = event["data"][aconsts.SESSION_CB_KEY_PEER_ID] - - # DUT1.X send message to DUT2 - x_msg = "Hello X on DUT2!" - dut1.droid.wifiAwareSendMessage(dut1_x_sid, dut1_peer_id_for_dut2_x, - self.get_next_msg_id(), x_msg, - self.msg_retx_count) - autils.wait_for_event(dut1, aconsts.SESSION_CB_ON_MESSAGE_SENT) - event = autils.wait_for_event(dut2, aconsts.SESSION_CB_ON_MESSAGE_RECEIVED) - asserts.assert_equal(event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], - dut2_x_pid, - "Unexpected publish session ID on DUT2 for meesage " - "received on service X") - asserts.assert_equal( - event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING], x_msg, - "Message on service X from DUT1 to DUT2 not received correctly") - - # DUT2.Y send message to DUT1 - y_msg = "Hello Y on DUT1!" - dut2.droid.wifiAwareSendMessage(dut2_y_sid, dut2_peer_id_for_dut1_y, - self.get_next_msg_id(), y_msg, - self.msg_retx_count) - autils.wait_for_event(dut2, aconsts.SESSION_CB_ON_MESSAGE_SENT) - event = autils.wait_for_event(dut1, aconsts.SESSION_CB_ON_MESSAGE_RECEIVED) - asserts.assert_equal(event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], - dut1_y_pid, - "Unexpected publish session ID on DUT1 for meesage " - "received on service Y") - asserts.assert_equal( - event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING], y_msg, - "Message on service Y from DUT2 to DUT1 not received correctly") - - @test_tracker_info(uuid="eef80cf3-1fd2-4526-969b-6af2dce785d7") - def test_multiple_concurrent_services_both_unsolicited_passive(self): - """Validate multiple concurrent discovery sessions running on both devices. + dut1 = self.android_devices[0] + dut2 = self.android_devices[1] + + X_SERVICE_NAME = "ServiceXXX" + Y_SERVICE_NAME = "ServiceYYY" + + asserts.skip_if( + dut1.aware_capabilities[aconsts.CAP_MAX_PUBLISHES] < 2 + or dut2.aware_capabilities[aconsts.CAP_MAX_PUBLISHES] < 2, + "Devices do not support 2 publish sessions") + + # attach and wait for confirmation + id1 = dut1.droid.wifiAwareAttach(False) + autils.wait_for_event(dut1, aconsts.EVENT_CB_ON_ATTACHED) + time.sleep(self.device_startup_offset) + id2 = dut2.droid.wifiAwareAttach(False) + autils.wait_for_event(dut2, aconsts.EVENT_CB_ON_ATTACHED) + + # DUT1 & DUT2: start publishing both X & Y services and wait for + # confirmations + dut1_x_pid = dut1.droid.wifiAwarePublish( + id1, autils.create_discovery_config(X_SERVICE_NAME, type_x[0])) + event = autils.wait_for_event(dut1, + aconsts.SESSION_CB_ON_PUBLISH_STARTED) + asserts.assert_equal(event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], + dut1_x_pid, + "Unexpected DUT1 X publish session discovery ID") + + dut1_y_pid = dut1.droid.wifiAwarePublish( + id1, autils.create_discovery_config(Y_SERVICE_NAME, type_y[0])) + event = autils.wait_for_event(dut1, + aconsts.SESSION_CB_ON_PUBLISH_STARTED) + asserts.assert_equal(event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], + dut1_y_pid, + "Unexpected DUT1 Y publish session discovery ID") + + dut2_x_pid = dut2.droid.wifiAwarePublish( + id2, autils.create_discovery_config(X_SERVICE_NAME, type_x[0])) + event = autils.wait_for_event(dut2, + aconsts.SESSION_CB_ON_PUBLISH_STARTED) + asserts.assert_equal(event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], + dut2_x_pid, + "Unexpected DUT2 X publish session discovery ID") + + dut2_y_pid = dut2.droid.wifiAwarePublish( + id2, autils.create_discovery_config(Y_SERVICE_NAME, type_y[0])) + event = autils.wait_for_event(dut2, + aconsts.SESSION_CB_ON_PUBLISH_STARTED) + asserts.assert_equal(event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], + dut2_y_pid, + "Unexpected DUT2 Y publish session discovery ID") + + # DUT1: start subscribing for X + dut1_x_sid = dut1.droid.wifiAwareSubscribe( + id1, autils.create_discovery_config(X_SERVICE_NAME, type_x[1])) + autils.wait_for_event(dut1, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED) + + # DUT2: start subscribing for Y + dut2_y_sid = dut2.droid.wifiAwareSubscribe( + id2, autils.create_discovery_config(Y_SERVICE_NAME, type_y[1])) + autils.wait_for_event(dut2, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED) + + # DUT1 & DUT2: wait for service discovery + event = autils.wait_for_event(dut1, + aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) + asserts.assert_equal( + event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], dut1_x_sid, + "Unexpected DUT1 X subscribe session discovery ID") + dut1_peer_id_for_dut2_x = event["data"][aconsts.SESSION_CB_KEY_PEER_ID] + + event = autils.wait_for_event(dut2, + aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) + asserts.assert_equal( + event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], dut2_y_sid, + "Unexpected DUT2 Y subscribe session discovery ID") + dut2_peer_id_for_dut1_y = event["data"][aconsts.SESSION_CB_KEY_PEER_ID] + + # DUT1.X send message to DUT2 + x_msg = "Hello X on DUT2!" + dut1.droid.wifiAwareSendMessage(dut1_x_sid, dut1_peer_id_for_dut2_x, + self.get_next_msg_id(), x_msg, + self.msg_retx_count) + autils.wait_for_event(dut1, aconsts.SESSION_CB_ON_MESSAGE_SENT) + event = autils.wait_for_event(dut2, + aconsts.SESSION_CB_ON_MESSAGE_RECEIVED) + asserts.assert_equal( + event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], dut2_x_pid, + "Unexpected publish session ID on DUT2 for meesage " + "received on service X") + asserts.assert_equal( + event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING], x_msg, + "Message on service X from DUT1 to DUT2 not received correctly") + + # DUT2.Y send message to DUT1 + y_msg = "Hello Y on DUT1!" + dut2.droid.wifiAwareSendMessage(dut2_y_sid, dut2_peer_id_for_dut1_y, + self.get_next_msg_id(), y_msg, + self.msg_retx_count) + autils.wait_for_event(dut2, aconsts.SESSION_CB_ON_MESSAGE_SENT) + event = autils.wait_for_event(dut1, + aconsts.SESSION_CB_ON_MESSAGE_RECEIVED) + asserts.assert_equal( + event["data"][aconsts.SESSION_CB_KEY_SESSION_ID], dut1_y_pid, + "Unexpected publish session ID on DUT1 for meesage " + "received on service Y") + asserts.assert_equal( + event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING], y_msg, + "Message on service Y from DUT2 to DUT1 not received correctly") + + @test_tracker_info(uuid="eef80cf3-1fd2-4526-969b-6af2dce785d7") + def test_multiple_concurrent_services_both_unsolicited_passive(self): + """Validate multiple concurrent discovery sessions running on both devices. - DUT1 & DUT2 running Publish for X - DUT1 & DUT2 running Publish for Y - DUT1 Subscribes for X @@ -971,13 +990,19 @@ class DiscoveryTest(AwareBaseTest): Note: test requires that devices support 2 publish sessions concurrently. The test will be skipped if the devices are not capable. """ - self.run_multiple_concurrent_services( - type_x=[aconsts.PUBLISH_TYPE_UNSOLICITED, aconsts.SUBSCRIBE_TYPE_PASSIVE], - type_y=[aconsts.PUBLISH_TYPE_UNSOLICITED, aconsts.SUBSCRIBE_TYPE_PASSIVE]) - - @test_tracker_info(uuid="46739f04-ab2b-4556-b1a4-9aa2774869b5") - def test_multiple_concurrent_services_both_solicited_active(self): - """Validate multiple concurrent discovery sessions running on both devices. + self.run_multiple_concurrent_services( + type_x=[ + aconsts.PUBLISH_TYPE_UNSOLICITED, + aconsts.SUBSCRIBE_TYPE_PASSIVE + ], + type_y=[ + aconsts.PUBLISH_TYPE_UNSOLICITED, + aconsts.SUBSCRIBE_TYPE_PASSIVE + ]) + + @test_tracker_info(uuid="46739f04-ab2b-4556-b1a4-9aa2774869b5") + def test_multiple_concurrent_services_both_solicited_active(self): + """Validate multiple concurrent discovery sessions running on both devices. - DUT1 & DUT2 running Publish for X - DUT1 & DUT2 running Publish for Y - DUT1 Subscribes for X @@ -989,13 +1014,17 @@ class DiscoveryTest(AwareBaseTest): Note: test requires that devices support 2 publish sessions concurrently. The test will be skipped if the devices are not capable. """ - self.run_multiple_concurrent_services( - type_x=[aconsts.PUBLISH_TYPE_SOLICITED, aconsts.SUBSCRIBE_TYPE_ACTIVE], - type_y=[aconsts.PUBLISH_TYPE_SOLICITED, aconsts.SUBSCRIBE_TYPE_ACTIVE]) - - @test_tracker_info(uuid="5f8f7fd2-4a0e-4cca-8cbb-6d54353f2baa") - def test_multiple_concurrent_services_mix_unsolicited_solicited(self): - """Validate multiple concurrent discovery sessions running on both devices. + self.run_multiple_concurrent_services( + type_x=[ + aconsts.PUBLISH_TYPE_SOLICITED, aconsts.SUBSCRIBE_TYPE_ACTIVE + ], + type_y=[ + aconsts.PUBLISH_TYPE_SOLICITED, aconsts.SUBSCRIBE_TYPE_ACTIVE + ]) + + @test_tracker_info(uuid="5f8f7fd2-4a0e-4cca-8cbb-6d54353f2baa") + def test_multiple_concurrent_services_mix_unsolicited_solicited(self): + """Validate multiple concurrent discovery sessions running on both devices. - DUT1 & DUT2 running Publish for X - DUT1 & DUT2 running Publish for Y - DUT1 Subscribes for X @@ -1008,28 +1037,33 @@ class DiscoveryTest(AwareBaseTest): Note: test requires that devices support 2 publish sessions concurrently. The test will be skipped if the devices are not capable. """ - self.run_multiple_concurrent_services( - type_x=[aconsts.PUBLISH_TYPE_UNSOLICITED, aconsts.SUBSCRIBE_TYPE_PASSIVE], - type_y=[aconsts.PUBLISH_TYPE_SOLICITED, aconsts.SUBSCRIBE_TYPE_ACTIVE]) - - ######################################################### - - @test_tracker_info(uuid="908ec896-fc7a-4ee4-b633-a2f042b74448") - def test_upper_lower_service_name_equivalence(self): - """Validate that Service Name is case-insensitive. Publish a service name + self.run_multiple_concurrent_services( + type_x=[ + aconsts.PUBLISH_TYPE_UNSOLICITED, + aconsts.SUBSCRIBE_TYPE_PASSIVE + ], + type_y=[ + aconsts.PUBLISH_TYPE_SOLICITED, aconsts.SUBSCRIBE_TYPE_ACTIVE + ]) + + ######################################################### + + @test_tracker_info(uuid="908ec896-fc7a-4ee4-b633-a2f042b74448") + def test_upper_lower_service_name_equivalence(self): + """Validate that Service Name is case-insensitive. Publish a service name with mixed case, subscribe to the same service name with alternative case and verify that discovery happens.""" - p_dut = self.android_devices[0] - s_dut = self.android_devices[1] - - pub_service_name = "GoogleAbCdEf" - sub_service_name = "GoogleaBcDeF" - - autils.create_discovery_pair(p_dut, s_dut, - p_config=autils.create_discovery_config( - pub_service_name, - aconsts.PUBLISH_TYPE_UNSOLICITED), - s_config=autils.create_discovery_config( - sub_service_name, - aconsts.SUBSCRIBE_TYPE_PASSIVE), - device_startup_offset=self.device_startup_offset) + p_dut = self.android_devices[0] + s_dut = self.android_devices[1] + + pub_service_name = "GoogleAbCdEf" + sub_service_name = "GoogleaBcDeF" + + autils.create_discovery_pair( + p_dut, + s_dut, + p_config=autils.create_discovery_config( + pub_service_name, aconsts.PUBLISH_TYPE_UNSOLICITED), + s_config=autils.create_discovery_config( + sub_service_name, aconsts.SUBSCRIBE_TYPE_PASSIVE), + device_startup_offset=self.device_startup_offset) diff --git a/acts/tests/google/wifi/aware/functional/MacRandomTest.py b/acts/tests/google/wifi/aware/functional/MacRandomTest.py index af1503b005..0278d6dbf5 100644 --- a/acts/tests/google/wifi/aware/functional/MacRandomTest.py +++ b/acts/tests/google/wifi/aware/functional/MacRandomTest.py @@ -25,115 +25,118 @@ from acts.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest class MacRandomTest(AwareBaseTest): - """Set of tests for Wi-Fi Aware MAC address randomization of NMI (NAN + """Set of tests for Wi-Fi Aware MAC address randomization of NMI (NAN management interface) and NDI (NAN data interface).""" - NUM_ITERATIONS = 10 + NUM_ITERATIONS = 10 - # number of second to 'reasonably' wait to make sure that devices synchronize - # with each other - useful for OOB test cases, where the OOB discovery would - # take some time - WAIT_FOR_CLUSTER = 5 + # number of second to 'reasonably' wait to make sure that devices synchronize + # with each other - useful for OOB test cases, where the OOB discovery would + # take some time + WAIT_FOR_CLUSTER = 5 - def __init__(self, controllers): - AwareBaseTest.__init__(self, controllers) + def __init__(self, controllers): + AwareBaseTest.__init__(self, controllers) - def request_network(self, dut, ns): - """Request a Wi-Fi Aware network. + def request_network(self, dut, ns): + """Request a Wi-Fi Aware network. Args: dut: Device ns: Network specifier Returns: the request key """ - network_req = {"TransportType": 5, "NetworkSpecifier": ns} - return dut.droid.connectivityRequestWifiAwareNetwork(network_req) + network_req = {"TransportType": 5, "NetworkSpecifier": ns} + return dut.droid.connectivityRequestWifiAwareNetwork(network_req) - ########################################################################## + ########################################################################## - @test_tracker_info(uuid="09964368-146a-48e4-9f33-6a319f9eeadc") - def test_nmi_ndi_randomization_on_enable(self): - """Validate randomization of the NMI (NAN management interface) and all NDIs + @test_tracker_info(uuid="09964368-146a-48e4-9f33-6a319f9eeadc") + def test_nmi_ndi_randomization_on_enable(self): + """Validate randomization of the NMI (NAN management interface) and all NDIs (NAN data-interface) on each enable/disable cycle""" - dut = self.android_devices[0] - - # re-enable randomization interval (since if disabled it may also disable - # the 'randomize on enable' feature). - autils.configure_mac_random_interval(dut, 1800) - - # DUT: attach and wait for confirmation & identity 10 times - mac_addresses = {} - for i in range(self.NUM_ITERATIONS): - id = dut.droid.wifiAwareAttach(True) - autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) - ident_event = autils.wait_for_event(dut, - aconsts.EVENT_CB_ON_IDENTITY_CHANGED) - - # process NMI - mac = ident_event["data"]["mac"] - dut.log.info("NMI=%s", mac) - if mac in mac_addresses: - mac_addresses[mac] = mac_addresses[mac] + 1 - else: - mac_addresses[mac] = 1 - - # process NDIs - time.sleep(5) # wait for NDI creation to complete - for j in range(dut.aware_capabilities[aconsts.CAP_MAX_NDI_INTERFACES]): - ndi_interface = "%s%d" % (aconsts.AWARE_NDI_PREFIX, j) - ndi_mac = autils.get_mac_addr(dut, ndi_interface) - dut.log.info("NDI %s=%s", ndi_interface, ndi_mac) - if ndi_mac in mac_addresses: - mac_addresses[ndi_mac] = mac_addresses[ndi_mac] + 1 - else: - mac_addresses[ndi_mac] = 1 - - dut.droid.wifiAwareDestroy(id) - - # Test for uniqueness - for mac in mac_addresses.keys(): - if mac_addresses[mac] != 1: - asserts.fail("MAC address %s repeated %d times (all=%s)" % (mac, - mac_addresses[mac], mac_addresses)) - - # Verify that infra interface (e.g. wlan0) MAC address is not used for NMI - infra_mac = autils.get_wifi_mac_address(dut) - asserts.assert_false( - infra_mac in mac_addresses, - "Infrastructure MAC address (%s) is used for Aware NMI (all=%s)" % - (infra_mac, mac_addresses)) - - @test_tracker_info(uuid="0fb0b5d8-d9cb-4e37-b9af-51811be5670d") - def test_nmi_randomization_on_interval(self): - """Validate randomization of the NMI (NAN management interface) on a set + dut = self.android_devices[0] + + # re-enable randomization interval (since if disabled it may also disable + # the 'randomize on enable' feature). + autils.configure_mac_random_interval(dut, 1800) + + # DUT: attach and wait for confirmation & identity 10 times + mac_addresses = {} + for i in range(self.NUM_ITERATIONS): + id = dut.droid.wifiAwareAttach(True) + autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) + ident_event = autils.wait_for_event( + dut, aconsts.EVENT_CB_ON_IDENTITY_CHANGED) + + # process NMI + mac = ident_event["data"]["mac"] + dut.log.info("NMI=%s", mac) + if mac in mac_addresses: + mac_addresses[mac] = mac_addresses[mac] + 1 + else: + mac_addresses[mac] = 1 + + # process NDIs + time.sleep(5) # wait for NDI creation to complete + for j in range( + dut.aware_capabilities[aconsts.CAP_MAX_NDI_INTERFACES]): + ndi_interface = "%s%d" % (aconsts.AWARE_NDI_PREFIX, j) + ndi_mac = autils.get_mac_addr(dut, ndi_interface) + dut.log.info("NDI %s=%s", ndi_interface, ndi_mac) + if ndi_mac in mac_addresses: + mac_addresses[ndi_mac] = mac_addresses[ndi_mac] + 1 + else: + mac_addresses[ndi_mac] = 1 + + dut.droid.wifiAwareDestroy(id) + + # Test for uniqueness + for mac in mac_addresses.keys(): + if mac_addresses[mac] != 1: + asserts.fail("MAC address %s repeated %d times (all=%s)" % + (mac, mac_addresses[mac], mac_addresses)) + + # Verify that infra interface (e.g. wlan0) MAC address is not used for NMI + infra_mac = autils.get_wifi_mac_address(dut) + asserts.assert_false( + infra_mac in mac_addresses, + "Infrastructure MAC address (%s) is used for Aware NMI (all=%s)" % + (infra_mac, mac_addresses)) + + @test_tracker_info(uuid="0fb0b5d8-d9cb-4e37-b9af-51811be5670d") + def test_nmi_randomization_on_interval(self): + """Validate randomization of the NMI (NAN management interface) on a set interval. Default value is 30 minutes - change to a small value to allow testing in real-time""" - RANDOM_INTERVAL = 120 # minimal value in current implementation - - dut = self.android_devices[0] - - # set randomization interval to 120 seconds - autils.configure_mac_random_interval(dut, RANDOM_INTERVAL) - - # attach and wait for first identity - id = dut.droid.wifiAwareAttach(True) - autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) - ident_event = autils.wait_for_event(dut, - aconsts.EVENT_CB_ON_IDENTITY_CHANGED) - mac1 = ident_event["data"]["mac"] - - # wait for second identity callback - # Note: exact randomization interval is not critical, just approximate, - # hence giving a few more seconds. - ident_event = autils.wait_for_event(dut, - aconsts.EVENT_CB_ON_IDENTITY_CHANGED, - timeout=RANDOM_INTERVAL + 5) - mac2 = ident_event["data"]["mac"] - - # validate MAC address is randomized - asserts.assert_false( - mac1 == mac2, - "Randomized MAC addresses (%s, %s) should be different" % (mac1, mac2)) - - # clean-up - dut.droid.wifiAwareDestroy(id) + RANDOM_INTERVAL = 120 # minimal value in current implementation + + dut = self.android_devices[0] + + # set randomization interval to 120 seconds + autils.configure_mac_random_interval(dut, RANDOM_INTERVAL) + + # attach and wait for first identity + id = dut.droid.wifiAwareAttach(True) + autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) + ident_event = autils.wait_for_event( + dut, aconsts.EVENT_CB_ON_IDENTITY_CHANGED) + mac1 = ident_event["data"]["mac"] + + # wait for second identity callback + # Note: exact randomization interval is not critical, just approximate, + # hence giving a few more seconds. + ident_event = autils.wait_for_event( + dut, + aconsts.EVENT_CB_ON_IDENTITY_CHANGED, + timeout=RANDOM_INTERVAL + 5) + mac2 = ident_event["data"]["mac"] + + # validate MAC address is randomized + asserts.assert_false( + mac1 == mac2, + "Randomized MAC addresses (%s, %s) should be different" % (mac1, + mac2)) + + # clean-up + dut.droid.wifiAwareDestroy(id) diff --git a/acts/tests/google/wifi/aware/functional/MatchFilterTest.py b/acts/tests/google/wifi/aware/functional/MatchFilterTest.py index 170b31b97a..acfedbd47a 100644 --- a/acts/tests/google/wifi/aware/functional/MatchFilterTest.py +++ b/acts/tests/google/wifi/aware/functional/MatchFilterTest.py @@ -26,49 +26,43 @@ from acts.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest class MatchFilterTest(AwareBaseTest): - """Set of tests for Wi-Fi Aware Discovery Match Filter behavior. These all + """Set of tests for Wi-Fi Aware Discovery Match Filter behavior. These all use examples from Appendix H of the Wi-Fi Aware standard.""" - SERVICE_NAME = "GoogleTestServiceMFMFMF" - - MF_NNNNN = bytes([0x0, 0x0, 0x0, 0x0, 0x0]) - MF_12345 = bytes([0x1, 0x1, 0x1, 0x2, 0x1, 0x3, 0x1, 0x4, 0x1, 0x5]) - MF_12145 = bytes([0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x1, 0x4, 0x1, 0x5]) - MF_1N3N5 = bytes([0x1, 0x1, 0x0, 0x1, 0x3, 0x0, 0x1, 0x5]) - MF_N23N5 = bytes([0x0, 0x1, 0x2, 0x1, 0x3, 0x0, 0x1, 0x5]) - MF_N2N4 = bytes([0x0, 0x1, 0x2, 0x0, 0x1, 0x4]) - MF_1N3N = bytes([0x1, 0x1, 0x0, 0x1, 0x3, 0x0]) - - # Set of sample match filters from the spec. There is a set of matched - # filters: - # - Filter 1 - # - Filter 2 - # - Expected to match if the Subscriber uses Filter 1 as Tx and the Publisher - # uses Filter 2 as Rx (implies Solicited/Active) - # - (the reverse) Expected to match if the Publisher uses Filter 1 as Tx and - # the Subscriber uses Filter 2 as Rx (implies Unsolicited/Passive) - match_filters = [ - [None, None, True, True], - [None, MF_NNNNN, True, True], - [MF_NNNNN, None, True, True], - [None, MF_12345, True, False], - [MF_12345, None, False, True], - [MF_NNNNN, MF_12345, True, True], - [MF_12345, MF_NNNNN, True, True], - [MF_12345, MF_12345, True, True], - [MF_12345, MF_12145, False, False], - [MF_1N3N5, MF_12345, True,True], - [MF_12345, MF_N23N5, True, True], - [MF_N2N4, MF_12345, True, False], - [MF_12345, MF_1N3N, False, True] - ] - - def __init__(self, controllers): - AwareBaseTest.__init__(self, controllers) - - def run_discovery(self, p_dut, s_dut, p_mf, s_mf, do_unsolicited_passive, - expect_discovery): - """Creates a discovery session (publish and subscribe) with the specified + SERVICE_NAME = "GoogleTestServiceMFMFMF" + + MF_NNNNN = bytes([0x0, 0x0, 0x0, 0x0, 0x0]) + MF_12345 = bytes([0x1, 0x1, 0x1, 0x2, 0x1, 0x3, 0x1, 0x4, 0x1, 0x5]) + MF_12145 = bytes([0x1, 0x1, 0x1, 0x2, 0x1, 0x1, 0x1, 0x4, 0x1, 0x5]) + MF_1N3N5 = bytes([0x1, 0x1, 0x0, 0x1, 0x3, 0x0, 0x1, 0x5]) + MF_N23N5 = bytes([0x0, 0x1, 0x2, 0x1, 0x3, 0x0, 0x1, 0x5]) + MF_N2N4 = bytes([0x0, 0x1, 0x2, 0x0, 0x1, 0x4]) + MF_1N3N = bytes([0x1, 0x1, 0x0, 0x1, 0x3, 0x0]) + + # Set of sample match filters from the spec. There is a set of matched + # filters: + # - Filter 1 + # - Filter 2 + # - Expected to match if the Subscriber uses Filter 1 as Tx and the Publisher + # uses Filter 2 as Rx (implies Solicited/Active) + # - (the reverse) Expected to match if the Publisher uses Filter 1 as Tx and + # the Subscriber uses Filter 2 as Rx (implies Unsolicited/Passive) + match_filters = [[None, None, True, True], [None, MF_NNNNN, True, True], [ + MF_NNNNN, None, True, True + ], [None, MF_12345, True, False], [MF_12345, None, False, True], [ + MF_NNNNN, MF_12345, True, True + ], [MF_12345, MF_NNNNN, True, True], [MF_12345, MF_12345, True, True], [ + MF_12345, MF_12145, False, False + ], [MF_1N3N5, MF_12345, True, True], [MF_12345, MF_N23N5, True, True], + [MF_N2N4, MF_12345, True, + False], [MF_12345, MF_1N3N, False, True]] + + def __init__(self, controllers): + AwareBaseTest.__init__(self, controllers) + + def run_discovery(self, p_dut, s_dut, p_mf, s_mf, do_unsolicited_passive, + expect_discovery): + """Creates a discovery session (publish and subscribe) with the specified configuration. Args: @@ -81,114 +75,119 @@ class MatchFilterTest(AwareBaseTest): expect_discovery: True if service should be discovered, False otherwise. Returns: True on success, False on failure (based on expect_discovery arg) """ - # Encode the match filters - p_mf = base64.b64encode(p_mf).decode("utf-8") if p_mf is not None else None - s_mf = base64.b64encode(s_mf).decode("utf-8") if s_mf is not None else None - - # Publisher+Subscriber: attach and wait for confirmation - p_id = p_dut.droid.wifiAwareAttach() - autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED) - time.sleep(self.device_startup_offset) - s_id = s_dut.droid.wifiAwareAttach() - autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED) - - # Publisher: start publish and wait for confirmation - p_dut.droid.wifiAwarePublish(p_id, - autils.create_discovery_config( - self.SERVICE_NAME, - d_type=aconsts.PUBLISH_TYPE_UNSOLICITED - if do_unsolicited_passive else - aconsts.PUBLISH_TYPE_SOLICITED, - match_filter=p_mf)) - autils.wait_for_event(p_dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED) - - # Subscriber: start subscribe and wait for confirmation - s_dut.droid.wifiAwareSubscribe(s_id, - autils.create_discovery_config( - self.SERVICE_NAME, - d_type=aconsts.SUBSCRIBE_TYPE_PASSIVE - if do_unsolicited_passive else - aconsts.SUBSCRIBE_TYPE_ACTIVE, - match_filter=s_mf)) - autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED) - - # Subscriber: wait or fail on service discovery - event = None - try: - event = s_dut.ed.pop_event(aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, - autils.EVENT_TIMEOUT) - s_dut.log.info("[Subscriber] SESSION_CB_ON_SERVICE_DISCOVERED: %s", event) - except queue.Empty: - s_dut.log.info("[Subscriber] No SESSION_CB_ON_SERVICE_DISCOVERED") - - # clean-up - p_dut.droid.wifiAwareDestroy(p_id) - s_dut.droid.wifiAwareDestroy(s_id) - - if expect_discovery: - return event is not None - else: - return event is None - - def run_match_filters_per_spec(self, do_unsolicited_passive): - """Validate all the match filter combinations in the Wi-Fi Aware spec, + # Encode the match filters + p_mf = base64.b64encode(p_mf).decode( + "utf-8") if p_mf is not None else None + s_mf = base64.b64encode(s_mf).decode( + "utf-8") if s_mf is not None else None + + # Publisher+Subscriber: attach and wait for confirmation + p_id = p_dut.droid.wifiAwareAttach() + autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED) + time.sleep(self.device_startup_offset) + s_id = s_dut.droid.wifiAwareAttach() + autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED) + + # Publisher: start publish and wait for confirmation + p_dut.droid.wifiAwarePublish( + p_id, + autils.create_discovery_config( + self.SERVICE_NAME, + d_type=aconsts.PUBLISH_TYPE_UNSOLICITED + if do_unsolicited_passive else aconsts.PUBLISH_TYPE_SOLICITED, + match_filter=p_mf)) + autils.wait_for_event(p_dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED) + + # Subscriber: start subscribe and wait for confirmation + s_dut.droid.wifiAwareSubscribe( + s_id, + autils.create_discovery_config( + self.SERVICE_NAME, + d_type=aconsts.SUBSCRIBE_TYPE_PASSIVE + if do_unsolicited_passive else aconsts.SUBSCRIBE_TYPE_ACTIVE, + match_filter=s_mf)) + autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED) + + # Subscriber: wait or fail on service discovery + event = None + try: + event = s_dut.ed.pop_event( + aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, autils.EVENT_TIMEOUT) + s_dut.log.info("[Subscriber] SESSION_CB_ON_SERVICE_DISCOVERED: %s", + event) + except queue.Empty: + s_dut.log.info("[Subscriber] No SESSION_CB_ON_SERVICE_DISCOVERED") + + # clean-up + p_dut.droid.wifiAwareDestroy(p_id) + s_dut.droid.wifiAwareDestroy(s_id) + + if expect_discovery: + return event is not None + else: + return event is None + + def run_match_filters_per_spec(self, do_unsolicited_passive): + """Validate all the match filter combinations in the Wi-Fi Aware spec, Appendix H. Args: do_unsolicited_passive: True to run the Unsolicited/Passive tests, False to run the Solicited/Active tests. """ - p_dut = self.android_devices[0] - p_dut.pretty_name = "Publisher" - s_dut = self.android_devices[1] - s_dut.pretty_name = "Subscriber" - - fails = [] - for i in range(len(self.match_filters)): - test_info = self.match_filters[i] - if do_unsolicited_passive: - pub_type = "Unsolicited" - sub_type = "Passive" - pub_mf = test_info[0] - sub_mf = test_info[1] - expect_discovery = test_info[3] - else: - pub_type = "Solicited" - sub_type = "Active" - pub_mf = test_info[1] - sub_mf = test_info[0] - expect_discovery = test_info[2] - - self.log.info("Test #%d: %s Pub MF=%s, %s Sub MF=%s: Discovery %s", i, - pub_type, pub_mf, sub_type, sub_mf, "EXPECTED" - if test_info[2] else "UNEXPECTED") - result = self.run_discovery( - p_dut, - s_dut, - p_mf=pub_mf, - s_mf=sub_mf, - do_unsolicited_passive=do_unsolicited_passive, - expect_discovery=expect_discovery) - self.log.info("Test #%d %s Pub/%s Sub %s", i, pub_type, sub_type, "PASS" - if result else "FAIL") - if not result: - fails.append(i) - - asserts.assert_true( - len(fails) == 0, "Some match filter tests are failing", extras=fails) - - ############################################################### - - @test_tracker_info(uuid="bd734f8c-895a-4cf9-820f-ec5060517fe9") - def test_match_filters_per_spec_unsolicited_passive(self): - """Validate all the match filter combinations in the Wi-Fi Aware spec, + p_dut = self.android_devices[0] + p_dut.pretty_name = "Publisher" + s_dut = self.android_devices[1] + s_dut.pretty_name = "Subscriber" + + fails = [] + for i in range(len(self.match_filters)): + test_info = self.match_filters[i] + if do_unsolicited_passive: + pub_type = "Unsolicited" + sub_type = "Passive" + pub_mf = test_info[0] + sub_mf = test_info[1] + expect_discovery = test_info[3] + else: + pub_type = "Solicited" + sub_type = "Active" + pub_mf = test_info[1] + sub_mf = test_info[0] + expect_discovery = test_info[2] + + self.log.info("Test #%d: %s Pub MF=%s, %s Sub MF=%s: Discovery %s", + i, pub_type, pub_mf, sub_type, sub_mf, "EXPECTED" + if test_info[2] else "UNEXPECTED") + result = self.run_discovery( + p_dut, + s_dut, + p_mf=pub_mf, + s_mf=sub_mf, + do_unsolicited_passive=do_unsolicited_passive, + expect_discovery=expect_discovery) + self.log.info("Test #%d %s Pub/%s Sub %s", i, pub_type, sub_type, + "PASS" if result else "FAIL") + if not result: + fails.append(i) + + asserts.assert_true( + len(fails) == 0, + "Some match filter tests are failing", + extras=fails) + + ############################################################### + + @test_tracker_info(uuid="bd734f8c-895a-4cf9-820f-ec5060517fe9") + def test_match_filters_per_spec_unsolicited_passive(self): + """Validate all the match filter combinations in the Wi-Fi Aware spec, Appendix H for Unsolicited Publish (tx filter) Passive Subscribe (rx filter)""" - self.run_match_filters_per_spec(do_unsolicited_passive=True) + self.run_match_filters_per_spec(do_unsolicited_passive=True) - @test_tracker_info(uuid="6560124d-69e5-49ff-a7e5-3cb305983723") - def test_match_filters_per_spec_solicited_active(self): - """Validate all the match filter combinations in the Wi-Fi Aware spec, + @test_tracker_info(uuid="6560124d-69e5-49ff-a7e5-3cb305983723") + def test_match_filters_per_spec_solicited_active(self): + """Validate all the match filter combinations in the Wi-Fi Aware spec, Appendix H for Solicited Publish (rx filter) Active Subscribe (tx filter)""" - self.run_match_filters_per_spec(do_unsolicited_passive=False) + self.run_match_filters_per_spec(do_unsolicited_passive=False) diff --git a/acts/tests/google/wifi/aware/functional/MessageTest.py b/acts/tests/google/wifi/aware/functional/MessageTest.py index 194ed6db21..7fb3e8eeef 100644 --- a/acts/tests/google/wifi/aware/functional/MessageTest.py +++ b/acts/tests/google/wifi/aware/functional/MessageTest.py @@ -25,21 +25,21 @@ from acts.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest class MessageTest(AwareBaseTest): - """Set of tests for Wi-Fi Aware L2 (layer 2) message exchanges.""" + """Set of tests for Wi-Fi Aware L2 (layer 2) message exchanges.""" - # configuration parameters used by tests - PAYLOAD_SIZE_MIN = 0 - PAYLOAD_SIZE_TYPICAL = 1 - PAYLOAD_SIZE_MAX = 2 + # configuration parameters used by tests + PAYLOAD_SIZE_MIN = 0 + PAYLOAD_SIZE_TYPICAL = 1 + PAYLOAD_SIZE_MAX = 2 - NUM_MSGS_NO_QUEUE = 10 - NUM_MSGS_QUEUE_DEPTH_MULT = 2 # number of messages = mult * queue depth + NUM_MSGS_NO_QUEUE = 10 + NUM_MSGS_QUEUE_DEPTH_MULT = 2 # number of messages = mult * queue depth - def __init__(self, controllers): - AwareBaseTest.__init__(self, controllers) + def __init__(self, controllers): + AwareBaseTest.__init__(self, controllers) - def create_msg(self, caps, payload_size, id): - """Creates a message string of the specified size containing the input id. + def create_msg(self, caps, payload_size, id): + """Creates a message string of the specified size containing the input id. Args: caps: Device capabilities. @@ -50,17 +50,17 @@ class MessageTest(AwareBaseTest): Returns: A string of the requested size, optionally containing the id. """ - if payload_size == self.PAYLOAD_SIZE_MIN: - # arbitrarily return a None or an empty string (equivalent messages) - return None if id % 2 == 0 else "" - elif payload_size == self.PAYLOAD_SIZE_TYPICAL: - return "*** ID=%d ***" % id + string.ascii_uppercase - else: # PAYLOAD_SIZE_MAX - return "*** ID=%4d ***" % id + "M" * ( - caps[aconsts.CAP_MAX_SERVICE_SPECIFIC_INFO_LEN] - 15) - - def create_config(self, is_publish, extra_diff=None): - """Create a base configuration based on input parameters. + if payload_size == self.PAYLOAD_SIZE_MIN: + # arbitrarily return a None or an empty string (equivalent messages) + return None if id % 2 == 0 else "" + elif payload_size == self.PAYLOAD_SIZE_TYPICAL: + return "*** ID=%d ***" % id + string.ascii_uppercase + else: # PAYLOAD_SIZE_MAX + return "*** ID=%4d ***" % id + "M" * ( + caps[aconsts.CAP_MAX_SERVICE_SPECIFIC_INFO_LEN] - 15) + + def create_config(self, is_publish, extra_diff=None): + """Create a base configuration based on input parameters. Args: is_publish: True for publish, False for subscribe sessions. @@ -70,19 +70,21 @@ class MessageTest(AwareBaseTest): Returns: publish discovery configuration object. """ - config = {} - if is_publish: - config[aconsts. - DISCOVERY_KEY_DISCOVERY_TYPE] = aconsts.PUBLISH_TYPE_UNSOLICITED - else: - config[ - aconsts.DISCOVERY_KEY_DISCOVERY_TYPE] = aconsts.SUBSCRIBE_TYPE_PASSIVE - config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = "GoogleTestServiceX" + ( - extra_diff if extra_diff is not None else "") - return config - - def prep_message_exchange(self, extra_diff=None): - """Creates a discovery session (publish and subscribe), and waits for + config = {} + if is_publish: + config[ + aconsts. + DISCOVERY_KEY_DISCOVERY_TYPE] = aconsts.PUBLISH_TYPE_UNSOLICITED + else: + config[ + aconsts. + DISCOVERY_KEY_DISCOVERY_TYPE] = aconsts.SUBSCRIBE_TYPE_PASSIVE + config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = "GoogleTestServiceX" + ( + extra_diff if extra_diff is not None else "") + return config + + def prep_message_exchange(self, extra_diff=None): + """Creates a discovery session (publish and subscribe), and waits for service discovery - at that point the sessions are ready for message exchange. @@ -90,115 +92,126 @@ class MessageTest(AwareBaseTest): extra_diff: String to add to service name: allows differentiating discovery sessions. """ - p_dut = self.android_devices[0] - p_dut.pretty_name = "Publisher" - s_dut = self.android_devices[1] - s_dut.pretty_name = "Subscriber" - - # if differentiating (multiple) sessions then should decorate events with id - use_id = extra_diff is not None - - # Publisher+Subscriber: attach and wait for confirmation - p_id = p_dut.droid.wifiAwareAttach(False, None, use_id) - autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED - if not use_id else autils.decorate_event( - aconsts.EVENT_CB_ON_ATTACHED, p_id)) - time.sleep(self.device_startup_offset) - s_id = s_dut.droid.wifiAwareAttach(False, None, use_id) - autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED - if not use_id else autils.decorate_event( - aconsts.EVENT_CB_ON_ATTACHED, s_id)) - - # Publisher: start publish and wait for confirmation - p_disc_id = p_dut.droid.wifiAwarePublish(p_id, - self.create_config( - True, extra_diff=extra_diff), - use_id) - autils.wait_for_event(p_dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED - if not use_id else autils.decorate_event( - aconsts.SESSION_CB_ON_PUBLISH_STARTED, p_disc_id)) - - # Subscriber: start subscribe and wait for confirmation - s_disc_id = s_dut.droid.wifiAwareSubscribe( - s_id, self.create_config(False, extra_diff=extra_diff), use_id) - autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED - if not use_id else autils.decorate_event( - aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, - s_disc_id)) - - # Subscriber: wait for service discovery - discovery_event = autils.wait_for_event( - s_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED - if not use_id else autils.decorate_event( - aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, s_disc_id)) - peer_id_on_sub = discovery_event["data"][aconsts.SESSION_CB_KEY_PEER_ID] - - return { - "p_dut": p_dut, - "s_dut": s_dut, - "p_id": p_id, - "s_id": s_id, - "p_disc_id": p_disc_id, - "s_disc_id": s_disc_id, - "peer_id_on_sub": peer_id_on_sub - } - - def run_message_no_queue(self, payload_size): - """Validate L2 message exchange between publisher & subscriber with no + p_dut = self.android_devices[0] + p_dut.pretty_name = "Publisher" + s_dut = self.android_devices[1] + s_dut.pretty_name = "Subscriber" + + # if differentiating (multiple) sessions then should decorate events with id + use_id = extra_diff is not None + + # Publisher+Subscriber: attach and wait for confirmation + p_id = p_dut.droid.wifiAwareAttach(False, None, use_id) + autils.wait_for_event( + p_dut, aconsts.EVENT_CB_ON_ATTACHED + if not use_id else autils.decorate_event( + aconsts.EVENT_CB_ON_ATTACHED, p_id)) + time.sleep(self.device_startup_offset) + s_id = s_dut.droid.wifiAwareAttach(False, None, use_id) + autils.wait_for_event( + s_dut, aconsts.EVENT_CB_ON_ATTACHED + if not use_id else autils.decorate_event( + aconsts.EVENT_CB_ON_ATTACHED, s_id)) + + # Publisher: start publish and wait for confirmation + p_disc_id = p_dut.droid.wifiAwarePublish( + p_id, self.create_config(True, extra_diff=extra_diff), use_id) + autils.wait_for_event( + p_dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED + if not use_id else autils.decorate_event( + aconsts.SESSION_CB_ON_PUBLISH_STARTED, p_disc_id)) + + # Subscriber: start subscribe and wait for confirmation + s_disc_id = s_dut.droid.wifiAwareSubscribe( + s_id, self.create_config(False, extra_diff=extra_diff), use_id) + autils.wait_for_event( + s_dut, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED + if not use_id else autils.decorate_event( + aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, s_disc_id)) + + # Subscriber: wait for service discovery + discovery_event = autils.wait_for_event( + s_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED + if not use_id else autils.decorate_event( + aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, s_disc_id)) + peer_id_on_sub = discovery_event["data"][ + aconsts.SESSION_CB_KEY_PEER_ID] + + return { + "p_dut": p_dut, + "s_dut": s_dut, + "p_id": p_id, + "s_id": s_id, + "p_disc_id": p_disc_id, + "s_disc_id": s_disc_id, + "peer_id_on_sub": peer_id_on_sub + } + + def run_message_no_queue(self, payload_size): + """Validate L2 message exchange between publisher & subscriber with no queueing - i.e. wait for an ACK on each message before sending the next message. Args: payload_size: min, typical, or max (PAYLOAD_SIZE_xx). """ - discovery_info = self.prep_message_exchange() - p_dut = discovery_info["p_dut"] - s_dut = discovery_info["s_dut"] - p_disc_id = discovery_info["p_disc_id"] - s_disc_id = discovery_info["s_disc_id"] - peer_id_on_sub = discovery_info["peer_id_on_sub"] - - for i in range(self.NUM_MSGS_NO_QUEUE): - msg = self.create_msg(s_dut.aware_capabilities, payload_size, i) - msg_id = self.get_next_msg_id() - s_dut.droid.wifiAwareSendMessage(s_disc_id, peer_id_on_sub, msg_id, msg, - 0) - tx_event = autils.wait_for_event(s_dut, - aconsts.SESSION_CB_ON_MESSAGE_SENT) - rx_event = autils.wait_for_event(p_dut, - aconsts.SESSION_CB_ON_MESSAGE_RECEIVED) - asserts.assert_equal(msg_id, - tx_event["data"][aconsts.SESSION_CB_KEY_MESSAGE_ID], - "Subscriber -> Publisher message ID corrupted") - autils.assert_equal_strings( - msg, rx_event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING], - "Subscriber -> Publisher message %d corrupted" % i) - - peer_id_on_pub = rx_event["data"][aconsts.SESSION_CB_KEY_PEER_ID] - for i in range(self.NUM_MSGS_NO_QUEUE): - msg = self.create_msg(s_dut.aware_capabilities, payload_size, 1000 + i) - msg_id = self.get_next_msg_id() - p_dut.droid.wifiAwareSendMessage(p_disc_id, peer_id_on_pub, msg_id, msg, - 0) - tx_event = autils.wait_for_event(p_dut, - aconsts.SESSION_CB_ON_MESSAGE_SENT) - rx_event = autils.wait_for_event(s_dut, - aconsts.SESSION_CB_ON_MESSAGE_RECEIVED) - asserts.assert_equal(msg_id, - tx_event["data"][aconsts.SESSION_CB_KEY_MESSAGE_ID], - "Publisher -> Subscriber message ID corrupted") - autils.assert_equal_strings( - msg, rx_event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING], - "Publisher -> Subscriber message %d corrupted" % i) - - # verify there are no more events - time.sleep(autils.EVENT_TIMEOUT) - autils.verify_no_more_events(p_dut, timeout=0) - autils.verify_no_more_events(s_dut, timeout=0) - - def wait_for_messages(self, tx_msgs, tx_msg_ids, tx_disc_id, rx_disc_id, - tx_dut, rx_dut, are_msgs_empty=False): - """Validate that all expected messages are transmitted correctly and + discovery_info = self.prep_message_exchange() + p_dut = discovery_info["p_dut"] + s_dut = discovery_info["s_dut"] + p_disc_id = discovery_info["p_disc_id"] + s_disc_id = discovery_info["s_disc_id"] + peer_id_on_sub = discovery_info["peer_id_on_sub"] + + for i in range(self.NUM_MSGS_NO_QUEUE): + msg = self.create_msg(s_dut.aware_capabilities, payload_size, i) + msg_id = self.get_next_msg_id() + s_dut.droid.wifiAwareSendMessage(s_disc_id, peer_id_on_sub, msg_id, + msg, 0) + tx_event = autils.wait_for_event( + s_dut, aconsts.SESSION_CB_ON_MESSAGE_SENT) + rx_event = autils.wait_for_event( + p_dut, aconsts.SESSION_CB_ON_MESSAGE_RECEIVED) + asserts.assert_equal( + msg_id, tx_event["data"][aconsts.SESSION_CB_KEY_MESSAGE_ID], + "Subscriber -> Publisher message ID corrupted") + autils.assert_equal_strings( + msg, + rx_event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING], + "Subscriber -> Publisher message %d corrupted" % i) + + peer_id_on_pub = rx_event["data"][aconsts.SESSION_CB_KEY_PEER_ID] + for i in range(self.NUM_MSGS_NO_QUEUE): + msg = self.create_msg(s_dut.aware_capabilities, payload_size, + 1000 + i) + msg_id = self.get_next_msg_id() + p_dut.droid.wifiAwareSendMessage(p_disc_id, peer_id_on_pub, msg_id, + msg, 0) + tx_event = autils.wait_for_event( + p_dut, aconsts.SESSION_CB_ON_MESSAGE_SENT) + rx_event = autils.wait_for_event( + s_dut, aconsts.SESSION_CB_ON_MESSAGE_RECEIVED) + asserts.assert_equal( + msg_id, tx_event["data"][aconsts.SESSION_CB_KEY_MESSAGE_ID], + "Publisher -> Subscriber message ID corrupted") + autils.assert_equal_strings( + msg, + rx_event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING], + "Publisher -> Subscriber message %d corrupted" % i) + + # verify there are no more events + time.sleep(autils.EVENT_TIMEOUT) + autils.verify_no_more_events(p_dut, timeout=0) + autils.verify_no_more_events(s_dut, timeout=0) + + def wait_for_messages(self, + tx_msgs, + tx_msg_ids, + tx_disc_id, + rx_disc_id, + tx_dut, + rx_dut, + are_msgs_empty=False): + """Validate that all expected messages are transmitted correctly and received as expected. Method is called after the messages are sent into the transmission queue. @@ -216,104 +229,105 @@ class MessageTest(AwareBaseTest): Returns: the peer ID from any of the received messages """ - # peer id on receiver - peer_id_on_rx = None - - # wait for all messages to be transmitted - still_to_be_tx = len(tx_msg_ids) - while still_to_be_tx != 0: - tx_event = autils.wait_for_event( - tx_dut, aconsts.SESSION_CB_ON_MESSAGE_SENT - if tx_disc_id is None else autils.decorate_event( - aconsts.SESSION_CB_ON_MESSAGE_SENT, tx_disc_id)) - tx_msg_id = tx_event["data"][aconsts.SESSION_CB_KEY_MESSAGE_ID] - tx_msg_ids[tx_msg_id] = tx_msg_ids[tx_msg_id] + 1 - if tx_msg_ids[tx_msg_id] == 1: - still_to_be_tx = still_to_be_tx - 1 - - # check for any duplicate transmit notifications - asserts.assert_equal( - len(tx_msg_ids), - sum(tx_msg_ids.values()), - "Duplicate transmit message IDs: %s" % tx_msg_ids) - - # wait for all messages to be received - still_to_be_rx = len(tx_msg_ids) - while still_to_be_rx != 0: - rx_event = autils.wait_for_event( - rx_dut, aconsts.SESSION_CB_ON_MESSAGE_RECEIVED - if rx_disc_id is None else autils.decorate_event( - aconsts.SESSION_CB_ON_MESSAGE_RECEIVED, rx_disc_id)) - peer_id_on_rx = rx_event["data"][aconsts.SESSION_CB_KEY_PEER_ID] - if are_msgs_empty: - still_to_be_rx = still_to_be_rx - 1 - else: - rx_msg = rx_event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING] - asserts.assert_true( - rx_msg in tx_msgs, - "Received a message we did not send!? -- '%s'" % rx_msg) - tx_msgs[rx_msg] = tx_msgs[rx_msg] + 1 - if tx_msgs[rx_msg] == 1: - still_to_be_rx = still_to_be_rx - 1 - - # check for any duplicate received messages - if not are_msgs_empty: - asserts.assert_equal( - len(tx_msgs), - sum(tx_msgs.values()), "Duplicate transmit messages: %s" % tx_msgs) - - return peer_id_on_rx - - def run_message_with_queue(self, payload_size): - """Validate L2 message exchange between publisher & subscriber with + # peer id on receiver + peer_id_on_rx = None + + # wait for all messages to be transmitted + still_to_be_tx = len(tx_msg_ids) + while still_to_be_tx != 0: + tx_event = autils.wait_for_event( + tx_dut, aconsts.SESSION_CB_ON_MESSAGE_SENT + if tx_disc_id is None else autils.decorate_event( + aconsts.SESSION_CB_ON_MESSAGE_SENT, tx_disc_id)) + tx_msg_id = tx_event["data"][aconsts.SESSION_CB_KEY_MESSAGE_ID] + tx_msg_ids[tx_msg_id] = tx_msg_ids[tx_msg_id] + 1 + if tx_msg_ids[tx_msg_id] == 1: + still_to_be_tx = still_to_be_tx - 1 + + # check for any duplicate transmit notifications + asserts.assert_equal( + len(tx_msg_ids), sum(tx_msg_ids.values()), + "Duplicate transmit message IDs: %s" % tx_msg_ids) + + # wait for all messages to be received + still_to_be_rx = len(tx_msg_ids) + while still_to_be_rx != 0: + rx_event = autils.wait_for_event( + rx_dut, aconsts.SESSION_CB_ON_MESSAGE_RECEIVED + if rx_disc_id is None else autils.decorate_event( + aconsts.SESSION_CB_ON_MESSAGE_RECEIVED, rx_disc_id)) + peer_id_on_rx = rx_event["data"][aconsts.SESSION_CB_KEY_PEER_ID] + if are_msgs_empty: + still_to_be_rx = still_to_be_rx - 1 + else: + rx_msg = rx_event["data"][ + aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING] + asserts.assert_true( + rx_msg in tx_msgs, + "Received a message we did not send!? -- '%s'" % rx_msg) + tx_msgs[rx_msg] = tx_msgs[rx_msg] + 1 + if tx_msgs[rx_msg] == 1: + still_to_be_rx = still_to_be_rx - 1 + + # check for any duplicate received messages + if not are_msgs_empty: + asserts.assert_equal( + len(tx_msgs), sum(tx_msgs.values()), + "Duplicate transmit messages: %s" % tx_msgs) + + return peer_id_on_rx + + def run_message_with_queue(self, payload_size): + """Validate L2 message exchange between publisher & subscriber with queueing - i.e. transmit all messages and then wait for ACKs. Args: payload_size: min, typical, or max (PAYLOAD_SIZE_xx). """ - discovery_info = self.prep_message_exchange() - p_dut = discovery_info["p_dut"] - s_dut = discovery_info["s_dut"] - p_disc_id = discovery_info["p_disc_id"] - s_disc_id = discovery_info["s_disc_id"] - peer_id_on_sub = discovery_info["peer_id_on_sub"] - - msgs = {} - msg_ids = {} - for i in range( - self.NUM_MSGS_QUEUE_DEPTH_MULT * - s_dut.aware_capabilities[aconsts.CAP_MAX_QUEUED_TRANSMIT_MESSAGES]): - msg = self.create_msg(s_dut.aware_capabilities, payload_size, i) - msg_id = self.get_next_msg_id() - msgs[msg] = 0 - msg_ids[msg_id] = 0 - s_dut.droid.wifiAwareSendMessage(s_disc_id, peer_id_on_sub, msg_id, msg, - 0) - peer_id_on_pub = self.wait_for_messages( - msgs, msg_ids, None, None, s_dut, p_dut, - payload_size == self.PAYLOAD_SIZE_MIN) - - msgs = {} - msg_ids = {} - for i in range( - self.NUM_MSGS_QUEUE_DEPTH_MULT * - p_dut.aware_capabilities[aconsts.CAP_MAX_QUEUED_TRANSMIT_MESSAGES]): - msg = self.create_msg(p_dut.aware_capabilities, payload_size, 1000 + i) - msg_id = self.get_next_msg_id() - msgs[msg] = 0 - msg_ids[msg_id] = 0 - p_dut.droid.wifiAwareSendMessage(p_disc_id, peer_id_on_pub, msg_id, msg, - 0) - self.wait_for_messages(msgs, msg_ids, None, None, p_dut, s_dut, - payload_size == self.PAYLOAD_SIZE_MIN) - - # verify there are no more events - time.sleep(autils.EVENT_TIMEOUT) - autils.verify_no_more_events(p_dut, timeout=0) - autils.verify_no_more_events(s_dut, timeout=0) - - def run_message_multi_session_with_queue(self, payload_size): - """Validate L2 message exchange between publishers & subscribers with + discovery_info = self.prep_message_exchange() + p_dut = discovery_info["p_dut"] + s_dut = discovery_info["s_dut"] + p_disc_id = discovery_info["p_disc_id"] + s_disc_id = discovery_info["s_disc_id"] + peer_id_on_sub = discovery_info["peer_id_on_sub"] + + msgs = {} + msg_ids = {} + for i in range( + self.NUM_MSGS_QUEUE_DEPTH_MULT * s_dut. + aware_capabilities[aconsts.CAP_MAX_QUEUED_TRANSMIT_MESSAGES]): + msg = self.create_msg(s_dut.aware_capabilities, payload_size, i) + msg_id = self.get_next_msg_id() + msgs[msg] = 0 + msg_ids[msg_id] = 0 + s_dut.droid.wifiAwareSendMessage(s_disc_id, peer_id_on_sub, msg_id, + msg, 0) + peer_id_on_pub = self.wait_for_messages( + msgs, msg_ids, None, None, s_dut, p_dut, + payload_size == self.PAYLOAD_SIZE_MIN) + + msgs = {} + msg_ids = {} + for i in range( + self.NUM_MSGS_QUEUE_DEPTH_MULT * p_dut. + aware_capabilities[aconsts.CAP_MAX_QUEUED_TRANSMIT_MESSAGES]): + msg = self.create_msg(p_dut.aware_capabilities, payload_size, + 1000 + i) + msg_id = self.get_next_msg_id() + msgs[msg] = 0 + msg_ids[msg_id] = 0 + p_dut.droid.wifiAwareSendMessage(p_disc_id, peer_id_on_pub, msg_id, + msg, 0) + self.wait_for_messages(msgs, msg_ids, None, None, p_dut, s_dut, + payload_size == self.PAYLOAD_SIZE_MIN) + + # verify there are no more events + time.sleep(autils.EVENT_TIMEOUT) + autils.verify_no_more_events(p_dut, timeout=0) + autils.verify_no_more_events(s_dut, timeout=0) + + def run_message_multi_session_with_queue(self, payload_size): + """Validate L2 message exchange between publishers & subscribers with queueing - i.e. transmit all messages and then wait for ACKs. Uses 2 discovery sessions running concurrently and validates that messages arrive at the correct destination. @@ -321,125 +335,128 @@ class MessageTest(AwareBaseTest): Args: payload_size: min, typical, or max (PAYLOAD_SIZE_xx) """ - discovery_info1 = self.prep_message_exchange(extra_diff="-111") - p_dut = discovery_info1["p_dut"] # same for both sessions - s_dut = discovery_info1["s_dut"] # same for both sessions - p_disc_id1 = discovery_info1["p_disc_id"] - s_disc_id1 = discovery_info1["s_disc_id"] - peer_id_on_sub1 = discovery_info1["peer_id_on_sub"] - - discovery_info2 = self.prep_message_exchange(extra_diff="-222") - p_disc_id2 = discovery_info2["p_disc_id"] - s_disc_id2 = discovery_info2["s_disc_id"] - peer_id_on_sub2 = discovery_info2["peer_id_on_sub"] - - msgs1 = {} - msg_ids1 = {} - msgs2 = {} - msg_ids2 = {} - for i in range( - self.NUM_MSGS_QUEUE_DEPTH_MULT * - s_dut.aware_capabilities[aconsts.CAP_MAX_QUEUED_TRANSMIT_MESSAGES]): - msg1 = self.create_msg(s_dut.aware_capabilities, payload_size, i) - msg_id1 = self.get_next_msg_id() - msgs1[msg1] = 0 - msg_ids1[msg_id1] = 0 - s_dut.droid.wifiAwareSendMessage(s_disc_id1, peer_id_on_sub1, msg_id1, - msg1, 0) - msg2 = self.create_msg(s_dut.aware_capabilities, payload_size, 100 + i) - msg_id2 = self.get_next_msg_id() - msgs2[msg2] = 0 - msg_ids2[msg_id2] = 0 - s_dut.droid.wifiAwareSendMessage(s_disc_id2, peer_id_on_sub2, msg_id2, - msg2, 0) - - peer_id_on_pub1 = self.wait_for_messages( - msgs1, msg_ids1, s_disc_id1, p_disc_id1, s_dut, p_dut, - payload_size == self.PAYLOAD_SIZE_MIN) - peer_id_on_pub2 = self.wait_for_messages( - msgs2, msg_ids2, s_disc_id2, p_disc_id2, s_dut, p_dut, - payload_size == self.PAYLOAD_SIZE_MIN) - - msgs1 = {} - msg_ids1 = {} - msgs2 = {} - msg_ids2 = {} - for i in range( - self.NUM_MSGS_QUEUE_DEPTH_MULT * - p_dut.aware_capabilities[aconsts.CAP_MAX_QUEUED_TRANSMIT_MESSAGES]): - msg1 = self.create_msg(p_dut.aware_capabilities, payload_size, 1000 + i) - msg_id1 = self.get_next_msg_id() - msgs1[msg1] = 0 - msg_ids1[msg_id1] = 0 - p_dut.droid.wifiAwareSendMessage(p_disc_id1, peer_id_on_pub1, msg_id1, - msg1, 0) - msg2 = self.create_msg(p_dut.aware_capabilities, payload_size, 1100 + i) - msg_id2 = self.get_next_msg_id() - msgs2[msg2] = 0 - msg_ids2[msg_id2] = 0 - p_dut.droid.wifiAwareSendMessage(p_disc_id2, peer_id_on_pub2, msg_id2, - msg2, 0) - - self.wait_for_messages(msgs1, msg_ids1, p_disc_id1, s_disc_id1, p_dut, - s_dut, payload_size == self.PAYLOAD_SIZE_MIN) - self.wait_for_messages(msgs2, msg_ids2, p_disc_id2, s_disc_id2, p_dut, - s_dut, payload_size == self.PAYLOAD_SIZE_MIN) - - # verify there are no more events - time.sleep(autils.EVENT_TIMEOUT) - autils.verify_no_more_events(p_dut, timeout=0) - autils.verify_no_more_events(s_dut, timeout=0) - - ############################################################################ - - @test_tracker_info(uuid="a8cd0512-b279-425f-93cf-949ddba22c7a") - def test_message_no_queue_min(self): - """Functional / Message / No queue + discovery_info1 = self.prep_message_exchange(extra_diff="-111") + p_dut = discovery_info1["p_dut"] # same for both sessions + s_dut = discovery_info1["s_dut"] # same for both sessions + p_disc_id1 = discovery_info1["p_disc_id"] + s_disc_id1 = discovery_info1["s_disc_id"] + peer_id_on_sub1 = discovery_info1["peer_id_on_sub"] + + discovery_info2 = self.prep_message_exchange(extra_diff="-222") + p_disc_id2 = discovery_info2["p_disc_id"] + s_disc_id2 = discovery_info2["s_disc_id"] + peer_id_on_sub2 = discovery_info2["peer_id_on_sub"] + + msgs1 = {} + msg_ids1 = {} + msgs2 = {} + msg_ids2 = {} + for i in range( + self.NUM_MSGS_QUEUE_DEPTH_MULT * s_dut. + aware_capabilities[aconsts.CAP_MAX_QUEUED_TRANSMIT_MESSAGES]): + msg1 = self.create_msg(s_dut.aware_capabilities, payload_size, i) + msg_id1 = self.get_next_msg_id() + msgs1[msg1] = 0 + msg_ids1[msg_id1] = 0 + s_dut.droid.wifiAwareSendMessage(s_disc_id1, peer_id_on_sub1, + msg_id1, msg1, 0) + msg2 = self.create_msg(s_dut.aware_capabilities, payload_size, + 100 + i) + msg_id2 = self.get_next_msg_id() + msgs2[msg2] = 0 + msg_ids2[msg_id2] = 0 + s_dut.droid.wifiAwareSendMessage(s_disc_id2, peer_id_on_sub2, + msg_id2, msg2, 0) + + peer_id_on_pub1 = self.wait_for_messages( + msgs1, msg_ids1, s_disc_id1, p_disc_id1, s_dut, p_dut, + payload_size == self.PAYLOAD_SIZE_MIN) + peer_id_on_pub2 = self.wait_for_messages( + msgs2, msg_ids2, s_disc_id2, p_disc_id2, s_dut, p_dut, + payload_size == self.PAYLOAD_SIZE_MIN) + + msgs1 = {} + msg_ids1 = {} + msgs2 = {} + msg_ids2 = {} + for i in range( + self.NUM_MSGS_QUEUE_DEPTH_MULT * p_dut. + aware_capabilities[aconsts.CAP_MAX_QUEUED_TRANSMIT_MESSAGES]): + msg1 = self.create_msg(p_dut.aware_capabilities, payload_size, + 1000 + i) + msg_id1 = self.get_next_msg_id() + msgs1[msg1] = 0 + msg_ids1[msg_id1] = 0 + p_dut.droid.wifiAwareSendMessage(p_disc_id1, peer_id_on_pub1, + msg_id1, msg1, 0) + msg2 = self.create_msg(p_dut.aware_capabilities, payload_size, + 1100 + i) + msg_id2 = self.get_next_msg_id() + msgs2[msg2] = 0 + msg_ids2[msg_id2] = 0 + p_dut.droid.wifiAwareSendMessage(p_disc_id2, peer_id_on_pub2, + msg_id2, msg2, 0) + + self.wait_for_messages(msgs1, msg_ids1, p_disc_id1, s_disc_id1, p_dut, + s_dut, payload_size == self.PAYLOAD_SIZE_MIN) + self.wait_for_messages(msgs2, msg_ids2, p_disc_id2, s_disc_id2, p_dut, + s_dut, payload_size == self.PAYLOAD_SIZE_MIN) + + # verify there are no more events + time.sleep(autils.EVENT_TIMEOUT) + autils.verify_no_more_events(p_dut, timeout=0) + autils.verify_no_more_events(s_dut, timeout=0) + + ############################################################################ + + @test_tracker_info(uuid="a8cd0512-b279-425f-93cf-949ddba22c7a") + def test_message_no_queue_min(self): + """Functional / Message / No queue - Minimal payload size (None or "") """ - self.run_message_no_queue(self.PAYLOAD_SIZE_MIN) + self.run_message_no_queue(self.PAYLOAD_SIZE_MIN) - @test_tracker_info(uuid="2c26170a-5d0a-4cf4-b0b9-56ef03f5dcf4") - def test_message_no_queue_typical(self): - """Functional / Message / No queue + @test_tracker_info(uuid="2c26170a-5d0a-4cf4-b0b9-56ef03f5dcf4") + def test_message_no_queue_typical(self): + """Functional / Message / No queue - Typical payload size """ - self.run_message_no_queue(self.PAYLOAD_SIZE_TYPICAL) + self.run_message_no_queue(self.PAYLOAD_SIZE_TYPICAL) - @test_tracker_info(uuid="c984860c-b62d-4d9b-8bce-4d894ea3bfbe") - def test_message_no_queue_max(self): - """Functional / Message / No queue + @test_tracker_info(uuid="c984860c-b62d-4d9b-8bce-4d894ea3bfbe") + def test_message_no_queue_max(self): + """Functional / Message / No queue - Max payload size (based on device capabilities) """ - self.run_message_no_queue(self.PAYLOAD_SIZE_MAX) + self.run_message_no_queue(self.PAYLOAD_SIZE_MAX) - @test_tracker_info(uuid="3f06de73-31ab-4e0c-bc6f-59abdaf87f4f") - def test_message_with_queue_min(self): - """Functional / Message / With queue + @test_tracker_info(uuid="3f06de73-31ab-4e0c-bc6f-59abdaf87f4f") + def test_message_with_queue_min(self): + """Functional / Message / With queue - Minimal payload size (none or "") """ - self.run_message_with_queue(self.PAYLOAD_SIZE_MIN) + self.run_message_with_queue(self.PAYLOAD_SIZE_MIN) - @test_tracker_info(uuid="9b7f5bd8-b0b1-479e-8e4b-9db0bb56767b") - def test_message_with_queue_typical(self): - """Functional / Message / With queue + @test_tracker_info(uuid="9b7f5bd8-b0b1-479e-8e4b-9db0bb56767b") + def test_message_with_queue_typical(self): + """Functional / Message / With queue - Typical payload size """ - self.run_message_with_queue(self.PAYLOAD_SIZE_TYPICAL) + self.run_message_with_queue(self.PAYLOAD_SIZE_TYPICAL) - @test_tracker_info(uuid="4f9a6dce-3050-4e6a-a143-53592c6c7c28") - def test_message_with_queue_max(self): - """Functional / Message / With queue + @test_tracker_info(uuid="4f9a6dce-3050-4e6a-a143-53592c6c7c28") + def test_message_with_queue_max(self): + """Functional / Message / With queue - Max payload size (based on device capabilities) """ - self.run_message_with_queue(self.PAYLOAD_SIZE_MAX) + self.run_message_with_queue(self.PAYLOAD_SIZE_MAX) - @test_tracker_info(uuid="4cece232-0983-4d6b-90a9-1bb9314b64f0") - def test_message_with_multiple_discovery_sessions_typical(self): - """Functional / Message / Multiple sessions + @test_tracker_info(uuid="4cece232-0983-4d6b-90a9-1bb9314b64f0") + def test_message_with_multiple_discovery_sessions_typical(self): + """Functional / Message / Multiple sessions Sets up 2 discovery sessions on 2 devices. Sends a message in each direction on each discovery session and verifies that reaches expected destination. """ - self.run_message_multi_session_with_queue(self.PAYLOAD_SIZE_TYPICAL) + self.run_message_multi_session_with_queue(self.PAYLOAD_SIZE_TYPICAL) diff --git a/acts/tests/google/wifi/aware/functional/NonConcurrencyTest.py b/acts/tests/google/wifi/aware/functional/NonConcurrencyTest.py index d0b83cfda6..c418c691ac 100644 --- a/acts/tests/google/wifi/aware/functional/NonConcurrencyTest.py +++ b/acts/tests/google/wifi/aware/functional/NonConcurrencyTest.py @@ -22,94 +22,94 @@ from acts.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest class NonConcurrencyTest(AwareBaseTest): - """Tests lack of concurrency scenarios Wi-Fi Aware with WFD (p2p) and + """Tests lack of concurrency scenarios Wi-Fi Aware with WFD (p2p) and SoftAP Note: these tests should be modified if the concurrency behavior changes!""" - SERVICE_NAME = "GoogleTestXYZ" - TETHER_SSID = "GoogleTestSoftApXYZ" + SERVICE_NAME = "GoogleTestXYZ" + TETHER_SSID = "GoogleTestSoftApXYZ" - def __init__(self, controllers): - AwareBaseTest.__init__(self, controllers) + def __init__(self, controllers): + AwareBaseTest.__init__(self, controllers) - def teardown_test(self): - AwareBaseTest.teardown_test(self) - for ad in self.android_devices: - ad.droid.wifiP2pClose() + def teardown_test(self): + AwareBaseTest.teardown_test(self) + for ad in self.android_devices: + ad.droid.wifiP2pClose() - def run_aware_then_incompat_service(self, is_p2p): - """Run test to validate that a running Aware session terminates when an + def run_aware_then_incompat_service(self, is_p2p): + """Run test to validate that a running Aware session terminates when an Aware-incompatible service is started. Args: is_p2p: True for p2p, False for SoftAP """ - dut = self.android_devices[0] + dut = self.android_devices[0] - # start Aware - id = dut.droid.wifiAwareAttach() - autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) + # start Aware + id = dut.droid.wifiAwareAttach() + autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) - # start other service - if is_p2p: - dut.droid.wifiP2pInitialize() - else: - wutils.start_wifi_tethering(dut, self.TETHER_SSID, password=None) + # start other service + if is_p2p: + dut.droid.wifiP2pInitialize() + else: + wutils.start_wifi_tethering(dut, self.TETHER_SSID, password=None) - # expect an announcement about Aware non-availability - autils.wait_for_event(dut, aconsts.BROADCAST_WIFI_AWARE_NOT_AVAILABLE) + # expect an announcement about Aware non-availability + autils.wait_for_event(dut, aconsts.BROADCAST_WIFI_AWARE_NOT_AVAILABLE) - # local clean-up - if not is_p2p: - wutils.stop_wifi_tethering(dut) + # local clean-up + if not is_p2p: + wutils.stop_wifi_tethering(dut) - def run_incompat_service_then_aware(self, is_p2p): - """Validate that if an Aware-incompatible service is already up then any + def run_incompat_service_then_aware(self, is_p2p): + """Validate that if an Aware-incompatible service is already up then any Aware operation fails""" - dut = self.android_devices[0] + dut = self.android_devices[0] - # start other service - if is_p2p: - dut.droid.wifiP2pInitialize() - else: - wutils.start_wifi_tethering(dut, self.TETHER_SSID, password=None) + # start other service + if is_p2p: + dut.droid.wifiP2pInitialize() + else: + wutils.start_wifi_tethering(dut, self.TETHER_SSID, password=None) - # expect an announcement about Aware non-availability - autils.wait_for_event(dut, aconsts.BROADCAST_WIFI_AWARE_NOT_AVAILABLE) + # expect an announcement about Aware non-availability + autils.wait_for_event(dut, aconsts.BROADCAST_WIFI_AWARE_NOT_AVAILABLE) - # try starting anyway (expect failure) - dut.droid.wifiAwareAttach() - autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACH_FAILED) + # try starting anyway (expect failure) + dut.droid.wifiAwareAttach() + autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACH_FAILED) - # stop other service - if is_p2p: - dut.droid.wifiP2pClose() - else: - wutils.stop_wifi_tethering(dut) + # stop other service + if is_p2p: + dut.droid.wifiP2pClose() + else: + wutils.stop_wifi_tethering(dut) - # expect an announcement about Aware availability - autils.wait_for_event(dut, aconsts.BROADCAST_WIFI_AWARE_AVAILABLE) + # expect an announcement about Aware availability + autils.wait_for_event(dut, aconsts.BROADCAST_WIFI_AWARE_AVAILABLE) - # try starting Aware - dut.droid.wifiAwareAttach() - autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) + # try starting Aware + dut.droid.wifiAwareAttach() + autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) - ########################################################################## + ########################################################################## - def test_run_p2p_then_aware(self): - """Validate that if p2p is already up then any Aware operation fails""" - self.run_incompat_service_then_aware(is_p2p=True) + def test_run_p2p_then_aware(self): + """Validate that if p2p is already up then any Aware operation fails""" + self.run_incompat_service_then_aware(is_p2p=True) - def test_run_aware_then_p2p(self): - """Validate that a running Aware session terminates when p2p is started""" - self.run_aware_then_incompat_service(is_p2p=True) + def test_run_aware_then_p2p(self): + """Validate that a running Aware session terminates when p2p is started""" + self.run_aware_then_incompat_service(is_p2p=True) - def test_run_softap_then_aware(self): - """Validate that if SoftAp is already up then any Aware operation fails""" - self.run_incompat_service_then_aware(is_p2p=False) + def test_run_softap_then_aware(self): + """Validate that if SoftAp is already up then any Aware operation fails""" + self.run_incompat_service_then_aware(is_p2p=False) - def test_run_aware_then_softap(self): - """Validate that a running Aware session terminates when softAp is + def test_run_aware_then_softap(self): + """Validate that a running Aware session terminates when softAp is started""" - self.run_aware_then_incompat_service(is_p2p=False) + self.run_aware_then_incompat_service(is_p2p=False) diff --git a/acts/tests/google/wifi/aware/functional/ProtocolsTest.py b/acts/tests/google/wifi/aware/functional/ProtocolsTest.py index 97a61b6e02..2e26d229d5 100644 --- a/acts/tests/google/wifi/aware/functional/ProtocolsTest.py +++ b/acts/tests/google/wifi/aware/functional/ProtocolsTest.py @@ -23,233 +23,243 @@ from acts.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest class ProtocolsTest(AwareBaseTest): - """Set of tests for Wi-Fi Aware data-paths: validating protocols running on + """Set of tests for Wi-Fi Aware data-paths: validating protocols running on top of a data-path""" - SERVICE_NAME = "GoogleTestServiceXY" + SERVICE_NAME = "GoogleTestServiceXY" - def __init__(self, controllers): - AwareBaseTest.__init__(self, controllers) + def __init__(self, controllers): + AwareBaseTest.__init__(self, controllers) - def run_ping6(self, dut, peer_ipv6, dut_if): - """Run a ping6 over the specified device/link + def run_ping6(self, dut, peer_ipv6, dut_if): + """Run a ping6 over the specified device/link Args: dut: Device on which to execute ping6 peer_ipv6: IPv6 address of the peer to ping dut_if: interface name on the dut """ - cmd = "ping6 -c 3 -W 5 %s%%%s" % (peer_ipv6, dut_if) - results = dut.adb.shell(cmd) - self.log.info("cmd='%s' -> '%s'", cmd, results) - if results == "": - asserts.fail("ping6 empty results - seems like a failure") + cmd = "ping6 -c 3 -W 5 %s%%%s" % (peer_ipv6, dut_if) + results = dut.adb.shell(cmd) + self.log.info("cmd='%s' -> '%s'", cmd, results) + if results == "": + asserts.fail("ping6 empty results - seems like a failure") - ######################################################################## + ######################################################################## - @test_tracker_info(uuid="ce103067-7fdd-4379-9a2b-d238959f1d53") - def test_ping6_oob(self): - """Validate that ping6 works correctly on an NDP created using OOB (out-of + @test_tracker_info(uuid="ce103067-7fdd-4379-9a2b-d238959f1d53") + def test_ping6_oob(self): + """Validate that ping6 works correctly on an NDP created using OOB (out-of band) discovery""" - init_dut = self.android_devices[0] - resp_dut = self.android_devices[1] - - # create NDP - (init_req_key, resp_req_key, init_aware_if, resp_aware_if, init_ipv6, - resp_ipv6) = autils.create_oob_ndp(init_dut, resp_dut) - self.log.info("Interface names: I=%s, R=%s", init_aware_if, resp_aware_if) - self.log.info("Interface addresses (IPv6): I=%s, R=%s", init_ipv6, - resp_ipv6) - - # run ping6 - self.run_ping6(init_dut, resp_ipv6, init_aware_if) - self.run_ping6(resp_dut, init_ipv6, resp_aware_if) - - # clean-up - resp_dut.droid.connectivityUnregisterNetworkCallback(resp_req_key) - init_dut.droid.connectivityUnregisterNetworkCallback(init_req_key) - - @test_tracker_info(uuid="fef86a48-0e05-464b-8c66-64316275c5ba") - def test_ping6_ib_unsolicited_passive(self): - """Validate that ping6 works correctly on an NDP created using Aware + init_dut = self.android_devices[0] + resp_dut = self.android_devices[1] + + # create NDP + (init_req_key, resp_req_key, init_aware_if, resp_aware_if, init_ipv6, + resp_ipv6) = autils.create_oob_ndp(init_dut, resp_dut) + self.log.info("Interface names: I=%s, R=%s", init_aware_if, + resp_aware_if) + self.log.info("Interface addresses (IPv6): I=%s, R=%s", init_ipv6, + resp_ipv6) + + # run ping6 + self.run_ping6(init_dut, resp_ipv6, init_aware_if) + self.run_ping6(resp_dut, init_ipv6, resp_aware_if) + + # clean-up + resp_dut.droid.connectivityUnregisterNetworkCallback(resp_req_key) + init_dut.droid.connectivityUnregisterNetworkCallback(init_req_key) + + @test_tracker_info(uuid="fef86a48-0e05-464b-8c66-64316275c5ba") + def test_ping6_ib_unsolicited_passive(self): + """Validate that ping6 works correctly on an NDP created using Aware discovery with UNSOLICITED/PASSIVE sessions.""" - p_dut = self.android_devices[0] - s_dut = self.android_devices[1] - - # create NDP - (p_req_key, s_req_key, p_aware_if, s_aware_if, p_ipv6, - s_ipv6) = autils.create_ib_ndp( - p_dut, - s_dut, - p_config=autils.create_discovery_config( - self.SERVICE_NAME, aconsts.PUBLISH_TYPE_UNSOLICITED), - s_config=autils.create_discovery_config( - self.SERVICE_NAME, aconsts.SUBSCRIBE_TYPE_PASSIVE), - device_startup_offset=self.device_startup_offset) - self.log.info("Interface names: P=%s, S=%s", p_aware_if, s_aware_if) - self.log.info("Interface addresses (IPv6): P=%s, S=%s", p_ipv6, s_ipv6) - - # run ping6 - self.run_ping6(p_dut, s_ipv6, p_aware_if) - self.run_ping6(s_dut, p_ipv6, s_aware_if) - - # clean-up - p_dut.droid.connectivityUnregisterNetworkCallback(p_req_key) - s_dut.droid.connectivityUnregisterNetworkCallback(s_req_key) - - @test_tracker_info(uuid="5bbd68a9-994b-4c26-88cd-43388cec280b") - def test_ping6_ib_solicited_active(self): - """Validate that ping6 works correctly on an NDP created using Aware + p_dut = self.android_devices[0] + s_dut = self.android_devices[1] + + # create NDP + (p_req_key, s_req_key, p_aware_if, s_aware_if, p_ipv6, + s_ipv6) = autils.create_ib_ndp( + p_dut, + s_dut, + p_config=autils.create_discovery_config( + self.SERVICE_NAME, aconsts.PUBLISH_TYPE_UNSOLICITED), + s_config=autils.create_discovery_config( + self.SERVICE_NAME, aconsts.SUBSCRIBE_TYPE_PASSIVE), + device_startup_offset=self.device_startup_offset) + self.log.info("Interface names: P=%s, S=%s", p_aware_if, s_aware_if) + self.log.info("Interface addresses (IPv6): P=%s, S=%s", p_ipv6, s_ipv6) + + # run ping6 + self.run_ping6(p_dut, s_ipv6, p_aware_if) + self.run_ping6(s_dut, p_ipv6, s_aware_if) + + # clean-up + p_dut.droid.connectivityUnregisterNetworkCallback(p_req_key) + s_dut.droid.connectivityUnregisterNetworkCallback(s_req_key) + + @test_tracker_info(uuid="5bbd68a9-994b-4c26-88cd-43388cec280b") + def test_ping6_ib_solicited_active(self): + """Validate that ping6 works correctly on an NDP created using Aware discovery with SOLICITED/ACTIVE sessions.""" - p_dut = self.android_devices[0] - s_dut = self.android_devices[1] - - # create NDP - (p_req_key, s_req_key, p_aware_if, s_aware_if, p_ipv6, - s_ipv6) = autils.create_ib_ndp( - p_dut, - s_dut, - p_config=autils.create_discovery_config( - self.SERVICE_NAME, aconsts.PUBLISH_TYPE_SOLICITED), - s_config=autils.create_discovery_config(self.SERVICE_NAME, - aconsts.SUBSCRIBE_TYPE_ACTIVE), - device_startup_offset=self.device_startup_offset) - self.log.info("Interface names: P=%s, S=%s", p_aware_if, s_aware_if) - self.log.info("Interface addresses (IPv6): P=%s, S=%s", p_ipv6, s_ipv6) - - # run ping6 - self.run_ping6(p_dut, s_ipv6, p_aware_if) - self.run_ping6(s_dut, p_ipv6, s_aware_if) - - # clean-up - p_dut.droid.connectivityUnregisterNetworkCallback(p_req_key) - s_dut.droid.connectivityUnregisterNetworkCallback(s_req_key) - - def test_ping6_oob_max_ndp(self): - """Validate that ping6 works correctly on multiple NDPs brought up + p_dut = self.android_devices[0] + s_dut = self.android_devices[1] + + # create NDP + (p_req_key, s_req_key, p_aware_if, s_aware_if, p_ipv6, + s_ipv6) = autils.create_ib_ndp( + p_dut, + s_dut, + p_config=autils.create_discovery_config( + self.SERVICE_NAME, aconsts.PUBLISH_TYPE_SOLICITED), + s_config=autils.create_discovery_config( + self.SERVICE_NAME, aconsts.SUBSCRIBE_TYPE_ACTIVE), + device_startup_offset=self.device_startup_offset) + self.log.info("Interface names: P=%s, S=%s", p_aware_if, s_aware_if) + self.log.info("Interface addresses (IPv6): P=%s, S=%s", p_ipv6, s_ipv6) + + # run ping6 + self.run_ping6(p_dut, s_ipv6, p_aware_if) + self.run_ping6(s_dut, p_ipv6, s_aware_if) + + # clean-up + p_dut.droid.connectivityUnregisterNetworkCallback(p_req_key) + s_dut.droid.connectivityUnregisterNetworkCallback(s_req_key) + + def test_ping6_oob_max_ndp(self): + """Validate that ping6 works correctly on multiple NDPs brought up concurrently. Uses the capability of the device to determine the max number of NDPs to set up. Note: the test requires MAX_NDP + 1 devices to be validated. If these are not available the test will fail.""" - dut = self.android_devices[0] - - # get max NDP: using first available device (assumes all devices are the - # same) - max_ndp = dut.aware_capabilities[aconsts.CAP_MAX_NDP_SESSIONS] - asserts.assert_true(len(self.android_devices) > max_ndp, - 'Needed %d devices to run the test, have %d' % - (max_ndp + 1, len(self.android_devices))) - - # create all NDPs - dut_aware_if = None - dut_ipv6 = None - peers_aware_ifs = [] - peers_ipv6s = [] - dut_requests = [] - peers_requests = [] - for i in range(max_ndp): - (init_req_key, resp_req_key, init_aware_if, resp_aware_if, init_ipv6, - resp_ipv6) = autils.create_oob_ndp(dut, self.android_devices[i + 1]) - self.log.info("Interface names: I=%s, R=%s", init_aware_if, resp_aware_if) - self.log.info("Interface addresses (IPv6): I=%s, R=%s", init_ipv6, - resp_ipv6) - - dut_requests.append(init_req_key) - peers_requests.append(resp_req_key) - if dut_aware_if is None: - dut_aware_if = init_aware_if - else: - asserts.assert_equal( - dut_aware_if, init_aware_if, - "DUT (Initiator) interface changed on subsequent NDPs!?") - if dut_ipv6 is None: - dut_ipv6 = init_ipv6 - else: - asserts.assert_equal( - dut_ipv6, init_ipv6, - "DUT (Initiator) IPv6 changed on subsequent NDPs!?") - peers_aware_ifs.append(resp_aware_if) - peers_ipv6s.append(resp_ipv6) - - # run ping6 - for i in range(max_ndp): - self.run_ping6(dut, peers_ipv6s[i], dut_aware_if) - self.run_ping6(self.android_devices[i + 1], dut_ipv6, peers_aware_ifs[i]) - - # cleanup - for i in range(max_ndp): - dut.droid.connectivityUnregisterNetworkCallback(dut_requests[i]) - self.android_devices[i + 1].droid.connectivityUnregisterNetworkCallback( - peers_requests[i]) - - def test_nsd_oob(self): - """Validate that NSD (mDNS) works correctly on an NDP created using OOB + dut = self.android_devices[0] + + # get max NDP: using first available device (assumes all devices are the + # same) + max_ndp = dut.aware_capabilities[aconsts.CAP_MAX_NDP_SESSIONS] + asserts.assert_true( + len(self.android_devices) > max_ndp, + 'Needed %d devices to run the test, have %d' % + (max_ndp + 1, len(self.android_devices))) + + # create all NDPs + dut_aware_if = None + dut_ipv6 = None + peers_aware_ifs = [] + peers_ipv6s = [] + dut_requests = [] + peers_requests = [] + for i in range(max_ndp): + (init_req_key, resp_req_key, init_aware_if, resp_aware_if, + init_ipv6, resp_ipv6) = autils.create_oob_ndp( + dut, self.android_devices[i + 1]) + self.log.info("Interface names: I=%s, R=%s", init_aware_if, + resp_aware_if) + self.log.info("Interface addresses (IPv6): I=%s, R=%s", init_ipv6, + resp_ipv6) + + dut_requests.append(init_req_key) + peers_requests.append(resp_req_key) + if dut_aware_if is None: + dut_aware_if = init_aware_if + else: + asserts.assert_equal( + dut_aware_if, init_aware_if, + "DUT (Initiator) interface changed on subsequent NDPs!?") + if dut_ipv6 is None: + dut_ipv6 = init_ipv6 + else: + asserts.assert_equal( + dut_ipv6, init_ipv6, + "DUT (Initiator) IPv6 changed on subsequent NDPs!?") + peers_aware_ifs.append(resp_aware_if) + peers_ipv6s.append(resp_ipv6) + + # run ping6 + for i in range(max_ndp): + self.run_ping6(dut, peers_ipv6s[i], dut_aware_if) + self.run_ping6(self.android_devices[i + 1], dut_ipv6, + peers_aware_ifs[i]) + + # cleanup + for i in range(max_ndp): + dut.droid.connectivityUnregisterNetworkCallback(dut_requests[i]) + self.android_devices[ + i + 1].droid.connectivityUnregisterNetworkCallback( + peers_requests[i]) + + def test_nsd_oob(self): + """Validate that NSD (mDNS) works correctly on an NDP created using OOB (out-of band) discovery""" - init_dut = self.android_devices[0] - resp_dut = self.android_devices[1] - - # create NDP - (init_req_key, resp_req_key, init_aware_if, resp_aware_if, init_ipv6, - resp_ipv6) = autils.create_oob_ndp(init_dut, resp_dut) - self.log.info("Interface names: I=%s, R=%s", init_aware_if, resp_aware_if) - self.log.info("Interface addresses (IPv6): I=%s, R=%s", init_ipv6, - resp_ipv6) - - # run NSD - nsd_service_info = { - "serviceInfoServiceName": "sl4aTestAwareNsd", - "serviceInfoServiceType": "_simple-tx-rx._tcp.", - "serviceInfoPort": 2257 - } - nsd_reg = None - nsd_discovery = None - try: - # Initiator registers an NSD service - nsd_reg = init_dut.droid.nsdRegisterService(nsd_service_info) - event_nsd = autils.wait_for_event_with_keys( - init_dut, nconsts.REG_LISTENER_EVENT, autils.EVENT_TIMEOUT, - (nconsts.REG_LISTENER_CALLBACK, - nconsts.REG_LISTENER_EVENT_ON_SERVICE_REGISTERED)) - self.log.info("Initiator %s: %s", - nconsts.REG_LISTENER_EVENT_ON_SERVICE_REGISTERED, - event_nsd["data"]) - - # Responder starts an NSD discovery - nsd_discovery = resp_dut.droid.nsdDiscoverServices( - nsd_service_info[nconsts.NSD_SERVICE_INFO_SERVICE_TYPE]) - event_nsd = autils.wait_for_event_with_keys( - resp_dut, nconsts.DISCOVERY_LISTENER_EVENT, autils.EVENT_TIMEOUT, - (nconsts.DISCOVERY_LISTENER_DATA_CALLBACK, - nconsts.DISCOVERY_LISTENER_EVENT_ON_SERVICE_FOUND)) - self.log.info("Responder %s: %s", - nconsts.DISCOVERY_LISTENER_EVENT_ON_SERVICE_FOUND, - event_nsd["data"]) - - # Responder resolves IP address of Initiator from NSD service discovery - resp_dut.droid.nsdResolveService(event_nsd["data"]) - event_nsd = autils.wait_for_event_with_keys( - resp_dut, nconsts.RESOLVE_LISTENER_EVENT, autils.EVENT_TIMEOUT, - (nconsts.RESOLVE_LISTENER_DATA_CALLBACK, - nconsts.RESOLVE_LISTENER_EVENT_ON_SERVICE_RESOLVED)) - self.log.info("Responder %s: %s", - nconsts.RESOLVE_LISTENER_EVENT_ON_SERVICE_RESOLVED, - event_nsd["data"]) - - # mDNS returns first character as '/' - strip - # out to get clean IPv6 - init_ipv6_nsd = event_nsd["data"][nconsts.NSD_SERVICE_INFO_HOST][1:] - - asserts.assert_equal( - init_ipv6, init_ipv6_nsd, - "Initiator's IPv6 address obtained through NSD doesn't match!?") - finally: - # Stop NSD - if nsd_reg is not None: - init_dut.droid.nsdUnregisterService(nsd_reg) - if nsd_discovery is not None: - resp_dut.droid.nsdStopServiceDiscovery(nsd_discovery) - - # clean-up - resp_dut.droid.connectivityUnregisterNetworkCallback(resp_req_key) - init_dut.droid.connectivityUnregisterNetworkCallback(init_req_key) + init_dut = self.android_devices[0] + resp_dut = self.android_devices[1] + + # create NDP + (init_req_key, resp_req_key, init_aware_if, resp_aware_if, init_ipv6, + resp_ipv6) = autils.create_oob_ndp(init_dut, resp_dut) + self.log.info("Interface names: I=%s, R=%s", init_aware_if, + resp_aware_if) + self.log.info("Interface addresses (IPv6): I=%s, R=%s", init_ipv6, + resp_ipv6) + + # run NSD + nsd_service_info = { + "serviceInfoServiceName": "sl4aTestAwareNsd", + "serviceInfoServiceType": "_simple-tx-rx._tcp.", + "serviceInfoPort": 2257 + } + nsd_reg = None + nsd_discovery = None + try: + # Initiator registers an NSD service + nsd_reg = init_dut.droid.nsdRegisterService(nsd_service_info) + event_nsd = autils.wait_for_event_with_keys( + init_dut, nconsts.REG_LISTENER_EVENT, autils.EVENT_TIMEOUT, + (nconsts.REG_LISTENER_CALLBACK, + nconsts.REG_LISTENER_EVENT_ON_SERVICE_REGISTERED)) + self.log.info("Initiator %s: %s", + nconsts.REG_LISTENER_EVENT_ON_SERVICE_REGISTERED, + event_nsd["data"]) + + # Responder starts an NSD discovery + nsd_discovery = resp_dut.droid.nsdDiscoverServices( + nsd_service_info[nconsts.NSD_SERVICE_INFO_SERVICE_TYPE]) + event_nsd = autils.wait_for_event_with_keys( + resp_dut, nconsts.DISCOVERY_LISTENER_EVENT, + autils.EVENT_TIMEOUT, + (nconsts.DISCOVERY_LISTENER_DATA_CALLBACK, + nconsts.DISCOVERY_LISTENER_EVENT_ON_SERVICE_FOUND)) + self.log.info("Responder %s: %s", + nconsts.DISCOVERY_LISTENER_EVENT_ON_SERVICE_FOUND, + event_nsd["data"]) + + # Responder resolves IP address of Initiator from NSD service discovery + resp_dut.droid.nsdResolveService(event_nsd["data"]) + event_nsd = autils.wait_for_event_with_keys( + resp_dut, nconsts.RESOLVE_LISTENER_EVENT, autils.EVENT_TIMEOUT, + (nconsts.RESOLVE_LISTENER_DATA_CALLBACK, + nconsts.RESOLVE_LISTENER_EVENT_ON_SERVICE_RESOLVED)) + self.log.info("Responder %s: %s", + nconsts.RESOLVE_LISTENER_EVENT_ON_SERVICE_RESOLVED, + event_nsd["data"]) + + # mDNS returns first character as '/' - strip + # out to get clean IPv6 + init_ipv6_nsd = event_nsd["data"][nconsts.NSD_SERVICE_INFO_HOST][ + 1:] + + asserts.assert_equal( + init_ipv6, init_ipv6_nsd, + "Initiator's IPv6 address obtained through NSD doesn't match!?" + ) + finally: + # Stop NSD + if nsd_reg is not None: + init_dut.droid.nsdUnregisterService(nsd_reg) + if nsd_discovery is not None: + resp_dut.droid.nsdStopServiceDiscovery(nsd_discovery) + + # clean-up + resp_dut.droid.connectivityUnregisterNetworkCallback(resp_req_key) + init_dut.droid.connectivityUnregisterNetworkCallback(init_req_key) diff --git a/acts/tests/google/wifi/aware/ota/ServiceIdsTest.py b/acts/tests/google/wifi/aware/ota/ServiceIdsTest.py index 1137303272..969130501e 100644 --- a/acts/tests/google/wifi/aware/ota/ServiceIdsTest.py +++ b/acts/tests/google/wifi/aware/ota/ServiceIdsTest.py @@ -23,18 +23,18 @@ from acts.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest class ServiceIdsTest(AwareBaseTest): - """Set of tests for Wi-Fi Aware to verify that beacons include service IDs + """Set of tests for Wi-Fi Aware to verify that beacons include service IDs for discovery. Note: this test is an OTA (over-the-air) and requires a Sniffer. """ - def __init__(self, controllers): - AwareBaseTest.__init__(self, controllers) + def __init__(self, controllers): + AwareBaseTest.__init__(self, controllers) - def start_discovery_session(self, dut, session_id, is_publish, dtype, - service_name): - """Start a discovery session + def start_discovery_session(self, dut, session_id, is_publish, dtype, + service_name): + """Start a discovery session Args: dut: Device under test @@ -46,55 +46,56 @@ class ServiceIdsTest(AwareBaseTest): Returns: Discovery session ID. """ - config = {} - config[aconsts.DISCOVERY_KEY_DISCOVERY_TYPE] = dtype - config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = service_name + config = {} + config[aconsts.DISCOVERY_KEY_DISCOVERY_TYPE] = dtype + config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = service_name - if is_publish: - disc_id = dut.droid.wifiAwarePublish(session_id, config) - event_name = aconsts.SESSION_CB_ON_PUBLISH_STARTED - else: - disc_id = dut.droid.wifiAwareSubscribe(session_id, config) - event_name = aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED + if is_publish: + disc_id = dut.droid.wifiAwarePublish(session_id, config) + event_name = aconsts.SESSION_CB_ON_PUBLISH_STARTED + else: + disc_id = dut.droid.wifiAwareSubscribe(session_id, config) + event_name = aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED - autils.wait_for_event(dut, event_name) - return disc_id + autils.wait_for_event(dut, event_name) + return disc_id - #################################################################### + #################################################################### - def test_service_ids_in_beacon(self): - """Verify that beacons include service IDs for both publish and subscribe + def test_service_ids_in_beacon(self): + """Verify that beacons include service IDs for both publish and subscribe sessions of all types: solicited/unsolicited/active/passive.""" - dut = self.android_devices[0] - - self.log.info("Reminder: start a sniffer before running test") - - # attach - session_id = dut.droid.wifiAwareAttach(True) - autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) - ident_event = autils.wait_for_event(dut, - aconsts.EVENT_CB_ON_IDENTITY_CHANGED) - mac = ident_event["data"]["mac"] - self.log.info("Source MAC Address of 'interesting' packets = %s", mac) - self.log.info("Wireshark filter = 'wlan.ta == %s:%s:%s:%s:%s:%s'", mac[0:2], - mac[2:4], mac[4:6], mac[6:8], mac[8:10], mac[10:12]) - - time.sleep(5) # get some samples pre-discovery - - # start 4 discovery session (one of each type) - self.start_discovery_session(dut, session_id, True, - aconsts.PUBLISH_TYPE_UNSOLICITED, - "GoogleTestService-Pub-Unsolicited") - self.start_discovery_session(dut, session_id, True, - aconsts.PUBLISH_TYPE_SOLICITED, - "GoogleTestService-Pub-Solicited") - self.start_discovery_session(dut, session_id, False, - aconsts.SUBSCRIBE_TYPE_ACTIVE, - "GoogleTestService-Sub-Active") - self.start_discovery_session(dut, session_id, False, - aconsts.SUBSCRIBE_TYPE_PASSIVE, - "GoogleTestService-Sub-Passive") - - time.sleep(15) # get some samples while discovery is alive - - self.log.info("Reminder: stop sniffer") + dut = self.android_devices[0] + + self.log.info("Reminder: start a sniffer before running test") + + # attach + session_id = dut.droid.wifiAwareAttach(True) + autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) + ident_event = autils.wait_for_event( + dut, aconsts.EVENT_CB_ON_IDENTITY_CHANGED) + mac = ident_event["data"]["mac"] + self.log.info("Source MAC Address of 'interesting' packets = %s", mac) + self.log.info("Wireshark filter = 'wlan.ta == %s:%s:%s:%s:%s:%s'", + mac[0:2], mac[2:4], mac[4:6], mac[6:8], mac[8:10], + mac[10:12]) + + time.sleep(5) # get some samples pre-discovery + + # start 4 discovery session (one of each type) + self.start_discovery_session(dut, session_id, True, + aconsts.PUBLISH_TYPE_UNSOLICITED, + "GoogleTestService-Pub-Unsolicited") + self.start_discovery_session(dut, session_id, True, + aconsts.PUBLISH_TYPE_SOLICITED, + "GoogleTestService-Pub-Solicited") + self.start_discovery_session(dut, session_id, False, + aconsts.SUBSCRIBE_TYPE_ACTIVE, + "GoogleTestService-Sub-Active") + self.start_discovery_session(dut, session_id, False, + aconsts.SUBSCRIBE_TYPE_PASSIVE, + "GoogleTestService-Sub-Passive") + + time.sleep(15) # get some samples while discovery is alive + + self.log.info("Reminder: stop sniffer") diff --git a/acts/tests/google/wifi/aware/performance/LatencyTest.py b/acts/tests/google/wifi/aware/performance/LatencyTest.py index bfadebcefb..db5d416c41 100644 --- a/acts/tests/google/wifi/aware/performance/LatencyTest.py +++ b/acts/tests/google/wifi/aware/performance/LatencyTest.py @@ -25,19 +25,19 @@ from acts.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest class LatencyTest(AwareBaseTest): - """Set of tests for Wi-Fi Aware to measure latency of Aware operations.""" - SERVICE_NAME = "GoogleTestServiceXY" + """Set of tests for Wi-Fi Aware to measure latency of Aware operations.""" + SERVICE_NAME = "GoogleTestServiceXY" - # number of second to 'reasonably' wait to make sure that devices synchronize - # with each other - useful for OOB test cases, where the OOB discovery would - # take some time - WAIT_FOR_CLUSTER = 5 + # number of second to 'reasonably' wait to make sure that devices synchronize + # with each other - useful for OOB test cases, where the OOB discovery would + # take some time + WAIT_FOR_CLUSTER = 5 - def __init__(self, controllers): - AwareBaseTest.__init__(self, controllers) + def __init__(self, controllers): + AwareBaseTest.__init__(self, controllers) - def start_discovery_session(self, dut, session_id, is_publish, dtype): - """Start a discovery session + def start_discovery_session(self, dut, session_id, is_publish, dtype): + """Start a discovery session Args: dut: Device under test @@ -48,24 +48,24 @@ class LatencyTest(AwareBaseTest): Returns: Discovery session started event. """ - config = {} - config[aconsts.DISCOVERY_KEY_DISCOVERY_TYPE] = dtype - config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = "GoogleTestServiceXY" - - if is_publish: - disc_id = dut.droid.wifiAwarePublish(session_id, config) - event_name = aconsts.SESSION_CB_ON_PUBLISH_STARTED - else: - disc_id = dut.droid.wifiAwareSubscribe(session_id, config) - event_name = aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED - - event = autils.wait_for_event(dut, event_name) - return disc_id, event - - def run_synchronization_latency(self, results, do_unsolicited_passive, - dw_24ghz, dw_5ghz, num_iterations, - startup_offset, timeout_period): - """Run the synchronization latency test with the specified DW intervals. + config = {} + config[aconsts.DISCOVERY_KEY_DISCOVERY_TYPE] = dtype + config[aconsts.DISCOVERY_KEY_SERVICE_NAME] = "GoogleTestServiceXY" + + if is_publish: + disc_id = dut.droid.wifiAwarePublish(session_id, config) + event_name = aconsts.SESSION_CB_ON_PUBLISH_STARTED + else: + disc_id = dut.droid.wifiAwareSubscribe(session_id, config) + event_name = aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED + + event = autils.wait_for_event(dut, event_name) + return disc_id, event + + def run_synchronization_latency(self, results, do_unsolicited_passive, + dw_24ghz, dw_5ghz, num_iterations, + startup_offset, timeout_period): + """Run the synchronization latency test with the specified DW intervals. There is no direct measure of synchronization. Instead starts a discovery session as soon as possible and measures both probability of discovery within a timeout period and the actual discovery time (not necessarily @@ -80,80 +80,82 @@ class LatencyTest(AwareBaseTest): startup_offset: The start-up gap (in seconds) between the two devices timeout_period: Time period over which to measure synchronization """ - key = "%s_dw24_%d_dw5_%d_offset_%d" % ( - "unsolicited_passive" if do_unsolicited_passive else "solicited_active", - dw_24ghz, dw_5ghz, startup_offset) - results[key] = {} - results[key]["num_iterations"] = num_iterations - - p_dut = self.android_devices[0] - p_dut.pretty_name = "Publisher" - s_dut = self.android_devices[1] - s_dut.pretty_name = "Subscriber" - - # override the default DW configuration - autils.config_power_settings(p_dut, dw_24ghz, dw_5ghz) - autils.config_power_settings(s_dut, dw_24ghz, dw_5ghz) - - latencies = [] - failed_discoveries = 0 - for i in range(num_iterations): - # Publisher+Subscriber: attach and wait for confirmation - p_id = p_dut.droid.wifiAwareAttach(False) - autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED) - time.sleep(startup_offset) - s_id = s_dut.droid.wifiAwareAttach(False) - autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED) - - # start publish - p_disc_id, p_disc_event = self.start_discovery_session( - p_dut, p_id, True, aconsts.PUBLISH_TYPE_UNSOLICITED - if do_unsolicited_passive else aconsts.PUBLISH_TYPE_SOLICITED) - - # start subscribe - s_disc_id, s_session_event = self.start_discovery_session( - s_dut, s_id, False, aconsts.SUBSCRIBE_TYPE_PASSIVE - if do_unsolicited_passive else aconsts.SUBSCRIBE_TYPE_ACTIVE) - - # wait for discovery (allow for failures here since running lots of - # samples and would like to get the partial data even in the presence of - # errors) - try: - discovery_event = s_dut.ed.pop_event( - aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, timeout_period) - s_dut.log.info("[Subscriber] SESSION_CB_ON_SERVICE_DISCOVERED: %s", - discovery_event["data"]) - except queue.Empty: - s_dut.log.info("[Subscriber] Timed out while waiting for " - "SESSION_CB_ON_SERVICE_DISCOVERED") - failed_discoveries = failed_discoveries + 1 - continue - finally: - # destroy sessions - p_dut.droid.wifiAwareDestroyDiscoverySession(p_disc_id) - s_dut.droid.wifiAwareDestroyDiscoverySession(s_disc_id) - p_dut.droid.wifiAwareDestroy(p_id) - s_dut.droid.wifiAwareDestroy(s_id) - - # collect latency information - latencies.append( - discovery_event["data"][aconsts.SESSION_CB_KEY_TIMESTAMP_MS] - - s_session_event["data"][aconsts.SESSION_CB_KEY_TIMESTAMP_MS]) - self.log.info("Latency #%d = %d" % (i, latencies[-1])) - - autils.extract_stats( - s_dut, - data=latencies, - results=results[key], - key_prefix="", - log_prefix="Subscribe Session Sync/Discovery (%s, dw24=%d, dw5=%d)" % - ("Unsolicited/Passive" - if do_unsolicited_passive else "Solicited/Active", dw_24ghz, dw_5ghz)) - results[key]["num_failed_discovery"] = failed_discoveries - - def run_discovery_latency(self, results, do_unsolicited_passive, dw_24ghz, - dw_5ghz, num_iterations): - """Run the service discovery latency test with the specified DW intervals. + key = "%s_dw24_%d_dw5_%d_offset_%d" % ("unsolicited_passive" + if do_unsolicited_passive else + "solicited_active", dw_24ghz, + dw_5ghz, startup_offset) + results[key] = {} + results[key]["num_iterations"] = num_iterations + + p_dut = self.android_devices[0] + p_dut.pretty_name = "Publisher" + s_dut = self.android_devices[1] + s_dut.pretty_name = "Subscriber" + + # override the default DW configuration + autils.config_power_settings(p_dut, dw_24ghz, dw_5ghz) + autils.config_power_settings(s_dut, dw_24ghz, dw_5ghz) + + latencies = [] + failed_discoveries = 0 + for i in range(num_iterations): + # Publisher+Subscriber: attach and wait for confirmation + p_id = p_dut.droid.wifiAwareAttach(False) + autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED) + time.sleep(startup_offset) + s_id = s_dut.droid.wifiAwareAttach(False) + autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED) + + # start publish + p_disc_id, p_disc_event = self.start_discovery_session( + p_dut, p_id, True, aconsts.PUBLISH_TYPE_UNSOLICITED + if do_unsolicited_passive else aconsts.PUBLISH_TYPE_SOLICITED) + + # start subscribe + s_disc_id, s_session_event = self.start_discovery_session( + s_dut, s_id, False, aconsts.SUBSCRIBE_TYPE_PASSIVE + if do_unsolicited_passive else aconsts.SUBSCRIBE_TYPE_ACTIVE) + + # wait for discovery (allow for failures here since running lots of + # samples and would like to get the partial data even in the presence of + # errors) + try: + discovery_event = s_dut.ed.pop_event( + aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, timeout_period) + s_dut.log.info( + "[Subscriber] SESSION_CB_ON_SERVICE_DISCOVERED: %s", + discovery_event["data"]) + except queue.Empty: + s_dut.log.info("[Subscriber] Timed out while waiting for " + "SESSION_CB_ON_SERVICE_DISCOVERED") + failed_discoveries = failed_discoveries + 1 + continue + finally: + # destroy sessions + p_dut.droid.wifiAwareDestroyDiscoverySession(p_disc_id) + s_dut.droid.wifiAwareDestroyDiscoverySession(s_disc_id) + p_dut.droid.wifiAwareDestroy(p_id) + s_dut.droid.wifiAwareDestroy(s_id) + + # collect latency information + latencies.append( + discovery_event["data"][aconsts.SESSION_CB_KEY_TIMESTAMP_MS] - + s_session_event["data"][aconsts.SESSION_CB_KEY_TIMESTAMP_MS]) + self.log.info("Latency #%d = %d" % (i, latencies[-1])) + + autils.extract_stats( + s_dut, + data=latencies, + results=results[key], + key_prefix="", + log_prefix="Subscribe Session Sync/Discovery (%s, dw24=%d, dw5=%d)" + % ("Unsolicited/Passive" if do_unsolicited_passive else + "Solicited/Active", dw_24ghz, dw_5ghz)) + results[key]["num_failed_discovery"] = failed_discoveries + + def run_discovery_latency(self, results, do_unsolicited_passive, dw_24ghz, + dw_5ghz, num_iterations): + """Run the service discovery latency test with the specified DW intervals. Args: results: Result array to be populated - will add results (not erase it) @@ -162,274 +164,282 @@ class LatencyTest(AwareBaseTest): dw_24ghz: DW interval in the 2.4GHz band. dw_5ghz: DW interval in the 5GHz band. """ - key = "%s_dw24_%d_dw5_%d" % ( - "unsolicited_passive" - if do_unsolicited_passive else "solicited_active", dw_24ghz, dw_5ghz) - results[key] = {} - results[key]["num_iterations"] = num_iterations - - p_dut = self.android_devices[0] - p_dut.pretty_name = "Publisher" - s_dut = self.android_devices[1] - s_dut.pretty_name = "Subscriber" - - # override the default DW configuration - autils.config_power_settings(p_dut, dw_24ghz, dw_5ghz) - autils.config_power_settings(s_dut, dw_24ghz, dw_5ghz) - - # Publisher+Subscriber: attach and wait for confirmation - p_id = p_dut.droid.wifiAwareAttach(False) - autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED) - time.sleep(self.device_startup_offset) - s_id = s_dut.droid.wifiAwareAttach(False) - autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED) - - # start publish - p_disc_event = self.start_discovery_session( - p_dut, p_id, True, aconsts.PUBLISH_TYPE_UNSOLICITED - if do_unsolicited_passive else aconsts.PUBLISH_TYPE_SOLICITED) - - # wait for for devices to synchronize with each other - used so that first - # discovery isn't biased by synchronization. - time.sleep(self.WAIT_FOR_CLUSTER) - - # loop, perform discovery, and collect latency information - latencies = [] - failed_discoveries = 0 - for i in range(num_iterations): - # start subscribe - s_disc_id, s_session_event = self.start_discovery_session( - s_dut, s_id, False, aconsts.SUBSCRIBE_TYPE_PASSIVE - if do_unsolicited_passive else aconsts.SUBSCRIBE_TYPE_ACTIVE) - - # wait for discovery (allow for failures here since running lots of - # samples and would like to get the partial data even in the presence of - # errors) - try: - discovery_event = s_dut.ed.pop_event( - aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, autils.EVENT_TIMEOUT) - except queue.Empty: - s_dut.log.info("[Subscriber] Timed out while waiting for " - "SESSION_CB_ON_SERVICE_DISCOVERED") - failed_discoveries = failed_discoveries + 1 - continue - finally: - # destroy subscribe - s_dut.droid.wifiAwareDestroyDiscoverySession(s_disc_id) - - # collect latency information - latencies.append( - discovery_event["data"][aconsts.SESSION_CB_KEY_TIMESTAMP_MS] - - s_session_event["data"][aconsts.SESSION_CB_KEY_TIMESTAMP_MS]) - self.log.info("Latency #%d = %d" % (i, latencies[-1])) - - autils.extract_stats( - s_dut, - data=latencies, - results=results[key], - key_prefix="", - log_prefix="Subscribe Session Discovery (%s, dw24=%d, dw5=%d)" % - ("Unsolicited/Passive" - if do_unsolicited_passive else "Solicited/Active", dw_24ghz, dw_5ghz)) - results[key]["num_failed_discovery"] = failed_discoveries - - # clean up - p_dut.droid.wifiAwareDestroyAll() - s_dut.droid.wifiAwareDestroyAll() - - def run_message_latency(self, results, dw_24ghz, dw_5ghz, num_iterations): - """Run the message tx latency test with the specified DW intervals. + key = "%s_dw24_%d_dw5_%d" % ("unsolicited_passive" + if do_unsolicited_passive else + "solicited_active", dw_24ghz, dw_5ghz) + results[key] = {} + results[key]["num_iterations"] = num_iterations + + p_dut = self.android_devices[0] + p_dut.pretty_name = "Publisher" + s_dut = self.android_devices[1] + s_dut.pretty_name = "Subscriber" + + # override the default DW configuration + autils.config_power_settings(p_dut, dw_24ghz, dw_5ghz) + autils.config_power_settings(s_dut, dw_24ghz, dw_5ghz) + + # Publisher+Subscriber: attach and wait for confirmation + p_id = p_dut.droid.wifiAwareAttach(False) + autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED) + time.sleep(self.device_startup_offset) + s_id = s_dut.droid.wifiAwareAttach(False) + autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED) + + # start publish + p_disc_event = self.start_discovery_session( + p_dut, p_id, True, aconsts.PUBLISH_TYPE_UNSOLICITED + if do_unsolicited_passive else aconsts.PUBLISH_TYPE_SOLICITED) + + # wait for for devices to synchronize with each other - used so that first + # discovery isn't biased by synchronization. + time.sleep(self.WAIT_FOR_CLUSTER) + + # loop, perform discovery, and collect latency information + latencies = [] + failed_discoveries = 0 + for i in range(num_iterations): + # start subscribe + s_disc_id, s_session_event = self.start_discovery_session( + s_dut, s_id, False, aconsts.SUBSCRIBE_TYPE_PASSIVE + if do_unsolicited_passive else aconsts.SUBSCRIBE_TYPE_ACTIVE) + + # wait for discovery (allow for failures here since running lots of + # samples and would like to get the partial data even in the presence of + # errors) + try: + discovery_event = s_dut.ed.pop_event( + aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, + autils.EVENT_TIMEOUT) + except queue.Empty: + s_dut.log.info("[Subscriber] Timed out while waiting for " + "SESSION_CB_ON_SERVICE_DISCOVERED") + failed_discoveries = failed_discoveries + 1 + continue + finally: + # destroy subscribe + s_dut.droid.wifiAwareDestroyDiscoverySession(s_disc_id) + + # collect latency information + latencies.append( + discovery_event["data"][aconsts.SESSION_CB_KEY_TIMESTAMP_MS] - + s_session_event["data"][aconsts.SESSION_CB_KEY_TIMESTAMP_MS]) + self.log.info("Latency #%d = %d" % (i, latencies[-1])) + + autils.extract_stats( + s_dut, + data=latencies, + results=results[key], + key_prefix="", + log_prefix="Subscribe Session Discovery (%s, dw24=%d, dw5=%d)" % + ("Unsolicited/Passive" if do_unsolicited_passive else + "Solicited/Active", dw_24ghz, dw_5ghz)) + results[key]["num_failed_discovery"] = failed_discoveries + + # clean up + p_dut.droid.wifiAwareDestroyAll() + s_dut.droid.wifiAwareDestroyAll() + + def run_message_latency(self, results, dw_24ghz, dw_5ghz, num_iterations): + """Run the message tx latency test with the specified DW intervals. Args: results: Result array to be populated - will add results (not erase it) dw_24ghz: DW interval in the 2.4GHz band. dw_5ghz: DW interval in the 5GHz band. """ - key = "dw24_%d_dw5_%d" % (dw_24ghz, dw_5ghz) - results[key] = {} - results[key]["num_iterations"] = num_iterations - - p_dut = self.android_devices[0] - s_dut = self.android_devices[1] - - # override the default DW configuration - autils.config_power_settings(p_dut, dw_24ghz, dw_5ghz) - autils.config_power_settings(s_dut, dw_24ghz, dw_5ghz) - - # Start up a discovery session - (p_id, s_id, p_disc_id, s_disc_id, - peer_id_on_sub) = autils.create_discovery_pair( - p_dut, - s_dut, - p_config=autils.create_discovery_config( - self.SERVICE_NAME, aconsts.PUBLISH_TYPE_UNSOLICITED), - s_config=autils.create_discovery_config( - self.SERVICE_NAME, aconsts.SUBSCRIBE_TYPE_PASSIVE), - device_startup_offset=self.device_startup_offset) - - latencies = [] - failed_tx = 0 - messages_rx = 0 - missing_rx = 0 - corrupted_rx = 0 - for i in range(num_iterations): - # send message - msg_s2p = "Message Subscriber -> Publisher #%d" % i - next_msg_id = self.get_next_msg_id() - s_dut.droid.wifiAwareSendMessage(s_disc_id, peer_id_on_sub, next_msg_id, - msg_s2p, 0) - - # wait for Tx confirmation - try: - sub_tx_msg_event = s_dut.ed.pop_event( - aconsts.SESSION_CB_ON_MESSAGE_SENT, 2 * autils.EVENT_TIMEOUT) - latencies.append( - sub_tx_msg_event["data"][aconsts.SESSION_CB_KEY_LATENCY_MS]) - except queue.Empty: - s_dut.log.info("[Subscriber] Timed out while waiting for " - "SESSION_CB_ON_MESSAGE_SENT") - failed_tx = failed_tx + 1 - continue - - # wait for Rx confirmation (and validate contents) - try: - pub_rx_msg_event = p_dut.ed.pop_event( - aconsts.SESSION_CB_ON_MESSAGE_RECEIVED, 2 * autils.EVENT_TIMEOUT) - messages_rx = messages_rx + 1 - if (pub_rx_msg_event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING] - != msg_s2p): - corrupted_rx = corrupted_rx + 1 - except queue.Empty: - s_dut.log.info("[Publisher] Timed out while waiting for " - "SESSION_CB_ON_MESSAGE_RECEIVED") - missing_rx = missing_rx + 1 - continue - - autils.extract_stats( - s_dut, - data=latencies, - results=results[key], - key_prefix="", - log_prefix="Subscribe Session Discovery (dw24=%d, dw5=%d)" % - (dw_24ghz, dw_5ghz)) - results[key]["failed_tx"] = failed_tx - results[key]["messages_rx"] = messages_rx - results[key]["missing_rx"] = missing_rx - results[key]["corrupted_rx"] = corrupted_rx - - # clean up - p_dut.droid.wifiAwareDestroyAll() - s_dut.droid.wifiAwareDestroyAll() - - def run_ndp_oob_latency(self, results, dw_24ghz, dw_5ghz, num_iterations): - """Runs the NDP setup with OOB (out-of-band) discovery latency test. + key = "dw24_%d_dw5_%d" % (dw_24ghz, dw_5ghz) + results[key] = {} + results[key]["num_iterations"] = num_iterations + + p_dut = self.android_devices[0] + s_dut = self.android_devices[1] + + # override the default DW configuration + autils.config_power_settings(p_dut, dw_24ghz, dw_5ghz) + autils.config_power_settings(s_dut, dw_24ghz, dw_5ghz) + + # Start up a discovery session + (p_id, s_id, p_disc_id, s_disc_id, + peer_id_on_sub) = autils.create_discovery_pair( + p_dut, + s_dut, + p_config=autils.create_discovery_config( + self.SERVICE_NAME, aconsts.PUBLISH_TYPE_UNSOLICITED), + s_config=autils.create_discovery_config( + self.SERVICE_NAME, aconsts.SUBSCRIBE_TYPE_PASSIVE), + device_startup_offset=self.device_startup_offset) + + latencies = [] + failed_tx = 0 + messages_rx = 0 + missing_rx = 0 + corrupted_rx = 0 + for i in range(num_iterations): + # send message + msg_s2p = "Message Subscriber -> Publisher #%d" % i + next_msg_id = self.get_next_msg_id() + s_dut.droid.wifiAwareSendMessage(s_disc_id, peer_id_on_sub, + next_msg_id, msg_s2p, 0) + + # wait for Tx confirmation + try: + sub_tx_msg_event = s_dut.ed.pop_event( + aconsts.SESSION_CB_ON_MESSAGE_SENT, + 2 * autils.EVENT_TIMEOUT) + latencies.append(sub_tx_msg_event["data"][ + aconsts.SESSION_CB_KEY_LATENCY_MS]) + except queue.Empty: + s_dut.log.info("[Subscriber] Timed out while waiting for " + "SESSION_CB_ON_MESSAGE_SENT") + failed_tx = failed_tx + 1 + continue + + # wait for Rx confirmation (and validate contents) + try: + pub_rx_msg_event = p_dut.ed.pop_event( + aconsts.SESSION_CB_ON_MESSAGE_RECEIVED, + 2 * autils.EVENT_TIMEOUT) + messages_rx = messages_rx + 1 + if (pub_rx_msg_event["data"] + [aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING] != msg_s2p): + corrupted_rx = corrupted_rx + 1 + except queue.Empty: + s_dut.log.info("[Publisher] Timed out while waiting for " + "SESSION_CB_ON_MESSAGE_RECEIVED") + missing_rx = missing_rx + 1 + continue + + autils.extract_stats( + s_dut, + data=latencies, + results=results[key], + key_prefix="", + log_prefix="Subscribe Session Discovery (dw24=%d, dw5=%d)" % + (dw_24ghz, dw_5ghz)) + results[key]["failed_tx"] = failed_tx + results[key]["messages_rx"] = messages_rx + results[key]["missing_rx"] = missing_rx + results[key]["corrupted_rx"] = corrupted_rx + + # clean up + p_dut.droid.wifiAwareDestroyAll() + s_dut.droid.wifiAwareDestroyAll() + + def run_ndp_oob_latency(self, results, dw_24ghz, dw_5ghz, num_iterations): + """Runs the NDP setup with OOB (out-of-band) discovery latency test. Args: results: Result array to be populated - will add results (not erase it) dw_24ghz: DW interval in the 2.4GHz band. dw_5ghz: DW interval in the 5GHz band. """ - key_avail = "on_avail_dw24_%d_dw5_%d" % (dw_24ghz, dw_5ghz) - key_link_props = "link_props_dw24_%d_dw5_%d" % (dw_24ghz, dw_5ghz) - results[key_avail] = {} - results[key_link_props] = {} - results[key_avail]["num_iterations"] = num_iterations - - init_dut = self.android_devices[0] - init_dut.pretty_name = 'Initiator' - resp_dut = self.android_devices[1] - resp_dut.pretty_name = 'Responder' - - # override the default DW configuration - autils.config_power_settings(init_dut, dw_24ghz, dw_5ghz) - autils.config_power_settings(resp_dut, dw_24ghz, dw_5ghz) - - # Initiator+Responder: attach and wait for confirmation & identity - init_id = init_dut.droid.wifiAwareAttach(True) - autils.wait_for_event(init_dut, aconsts.EVENT_CB_ON_ATTACHED) - init_ident_event = autils.wait_for_event(init_dut, - aconsts.EVENT_CB_ON_IDENTITY_CHANGED) - init_mac = init_ident_event['data']['mac'] - time.sleep(self.device_startup_offset) - resp_id = resp_dut.droid.wifiAwareAttach(True) - autils.wait_for_event(resp_dut, aconsts.EVENT_CB_ON_ATTACHED) - resp_ident_event = autils.wait_for_event(resp_dut, - aconsts.EVENT_CB_ON_IDENTITY_CHANGED) - resp_mac = resp_ident_event['data']['mac'] - - # wait for for devices to synchronize with each other - there are no other - # mechanisms to make sure this happens for OOB discovery (except retrying - # to execute the data-path request) - time.sleep(autils.WAIT_FOR_CLUSTER) - - on_available_latencies = [] - link_props_latencies = [] - ndp_setup_failures = 0 - for i in range(num_iterations): - # Responder: request network - resp_req_key = autils.request_network( - resp_dut, - resp_dut.droid.wifiAwareCreateNetworkSpecifierOob( - resp_id, aconsts.DATA_PATH_RESPONDER, init_mac, None)) - - # Initiator: request network - init_req_key = autils.request_network( - init_dut, - init_dut.droid.wifiAwareCreateNetworkSpecifierOob( - init_id, aconsts.DATA_PATH_INITIATOR, resp_mac, None)) - - # Initiator & Responder: wait for network formation - got_on_available = False - got_on_link_props = False - while not got_on_available or not got_on_link_props: - try: - nc_event = init_dut.ed.pop_event(cconsts.EVENT_NETWORK_CALLBACK, - autils.EVENT_NDP_TIMEOUT) - if nc_event["data"][ - cconsts.NETWORK_CB_KEY_EVENT] == cconsts.NETWORK_CB_AVAILABLE: - got_on_available = True - on_available_latencies.append( - nc_event["data"][cconsts.NETWORK_CB_KEY_CURRENT_TS] - - nc_event["data"][cconsts.NETWORK_CB_KEY_CREATE_TS]) - elif (nc_event["data"][cconsts.NETWORK_CB_KEY_EVENT] == - cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED): - got_on_link_props = True - link_props_latencies.append( - nc_event["data"][cconsts.NETWORK_CB_KEY_CURRENT_TS] - - nc_event["data"][cconsts.NETWORK_CB_KEY_CREATE_TS]) - except queue.Empty: - ndp_setup_failures = ndp_setup_failures + 1 - init_dut.log.info("[Initiator] Timed out while waiting for " - "EVENT_NETWORK_CALLBACK") - break - - # clean-up - init_dut.droid.connectivityUnregisterNetworkCallback(init_req_key) - resp_dut.droid.connectivityUnregisterNetworkCallback(resp_req_key) - - # wait to make sure previous NDP terminated, otherwise its termination - # time will be counted in the setup latency! - time.sleep(2) - - autils.extract_stats( - init_dut, - data=on_available_latencies, - results=results[key_avail], - key_prefix="", - log_prefix="NDP setup OnAvailable(dw24=%d, dw5=%d)" % (dw_24ghz, - dw_5ghz)) - autils.extract_stats( - init_dut, - data=link_props_latencies, - results=results[key_link_props], - key_prefix="", - log_prefix="NDP setup OnLinkProperties (dw24=%d, dw5=%d)" % (dw_24ghz, - dw_5ghz)) - results[key_avail]["ndp_setup_failures"] = ndp_setup_failures - - def run_end_to_end_latency(self, results, dw_24ghz, dw_5ghz, num_iterations, - startup_offset, include_setup): - """Measure the latency for end-to-end communication link setup: + key_avail = "on_avail_dw24_%d_dw5_%d" % (dw_24ghz, dw_5ghz) + key_link_props = "link_props_dw24_%d_dw5_%d" % (dw_24ghz, dw_5ghz) + results[key_avail] = {} + results[key_link_props] = {} + results[key_avail]["num_iterations"] = num_iterations + + init_dut = self.android_devices[0] + init_dut.pretty_name = 'Initiator' + resp_dut = self.android_devices[1] + resp_dut.pretty_name = 'Responder' + + # override the default DW configuration + autils.config_power_settings(init_dut, dw_24ghz, dw_5ghz) + autils.config_power_settings(resp_dut, dw_24ghz, dw_5ghz) + + # Initiator+Responder: attach and wait for confirmation & identity + init_id = init_dut.droid.wifiAwareAttach(True) + autils.wait_for_event(init_dut, aconsts.EVENT_CB_ON_ATTACHED) + init_ident_event = autils.wait_for_event( + init_dut, aconsts.EVENT_CB_ON_IDENTITY_CHANGED) + init_mac = init_ident_event['data']['mac'] + time.sleep(self.device_startup_offset) + resp_id = resp_dut.droid.wifiAwareAttach(True) + autils.wait_for_event(resp_dut, aconsts.EVENT_CB_ON_ATTACHED) + resp_ident_event = autils.wait_for_event( + resp_dut, aconsts.EVENT_CB_ON_IDENTITY_CHANGED) + resp_mac = resp_ident_event['data']['mac'] + + # wait for for devices to synchronize with each other - there are no other + # mechanisms to make sure this happens for OOB discovery (except retrying + # to execute the data-path request) + time.sleep(autils.WAIT_FOR_CLUSTER) + + on_available_latencies = [] + link_props_latencies = [] + ndp_setup_failures = 0 + for i in range(num_iterations): + # Responder: request network + resp_req_key = autils.request_network( + resp_dut, + resp_dut.droid.wifiAwareCreateNetworkSpecifierOob( + resp_id, aconsts.DATA_PATH_RESPONDER, init_mac, None)) + + # Initiator: request network + init_req_key = autils.request_network( + init_dut, + init_dut.droid.wifiAwareCreateNetworkSpecifierOob( + init_id, aconsts.DATA_PATH_INITIATOR, resp_mac, None)) + + # Initiator & Responder: wait for network formation + got_on_available = False + got_on_link_props = False + while not got_on_available or not got_on_link_props: + try: + nc_event = init_dut.ed.pop_event( + cconsts.EVENT_NETWORK_CALLBACK, + autils.EVENT_NDP_TIMEOUT) + if nc_event["data"][ + cconsts. + NETWORK_CB_KEY_EVENT] == cconsts.NETWORK_CB_AVAILABLE: + got_on_available = True + on_available_latencies.append( + nc_event["data"][cconsts.NETWORK_CB_KEY_CURRENT_TS] + - + nc_event["data"][cconsts.NETWORK_CB_KEY_CREATE_TS]) + elif (nc_event["data"][cconsts.NETWORK_CB_KEY_EVENT] == + cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED): + got_on_link_props = True + link_props_latencies.append( + nc_event["data"][cconsts.NETWORK_CB_KEY_CURRENT_TS] + - + nc_event["data"][cconsts.NETWORK_CB_KEY_CREATE_TS]) + except queue.Empty: + ndp_setup_failures = ndp_setup_failures + 1 + init_dut.log.info( + "[Initiator] Timed out while waiting for " + "EVENT_NETWORK_CALLBACK") + break + + # clean-up + init_dut.droid.connectivityUnregisterNetworkCallback(init_req_key) + resp_dut.droid.connectivityUnregisterNetworkCallback(resp_req_key) + + # wait to make sure previous NDP terminated, otherwise its termination + # time will be counted in the setup latency! + time.sleep(2) + + autils.extract_stats( + init_dut, + data=on_available_latencies, + results=results[key_avail], + key_prefix="", + log_prefix="NDP setup OnAvailable(dw24=%d, dw5=%d)" % (dw_24ghz, + dw_5ghz)) + autils.extract_stats( + init_dut, + data=link_props_latencies, + results=results[key_link_props], + key_prefix="", + log_prefix="NDP setup OnLinkProperties (dw24=%d, dw5=%d)" % + (dw_24ghz, dw_5ghz)) + results[key_avail]["ndp_setup_failures"] = ndp_setup_failures + + def run_end_to_end_latency(self, results, dw_24ghz, dw_5ghz, + num_iterations, startup_offset, include_setup): + """Measure the latency for end-to-end communication link setup: - Start Aware - Discovery - Message from Sub -> Pub @@ -444,341 +454,359 @@ class LatencyTest(AwareBaseTest): include_setup: True to include the cluster setup in the latency measurements. """ - key = "dw24_%d_dw5_%d" % (dw_24ghz, dw_5ghz) - results[key] = {} - results[key]["num_iterations"] = num_iterations - - p_dut = self.android_devices[0] - p_dut.pretty_name = "Publisher" - s_dut = self.android_devices[1] - s_dut.pretty_name = "Subscriber" - - # override the default DW configuration - autils.config_power_settings(p_dut, dw_24ghz, dw_5ghz) - autils.config_power_settings(s_dut, dw_24ghz, dw_5ghz) - - latencies = [] - - # allow for failures here since running lots of samples and would like to - # get the partial data even in the presence of errors - failures = 0 - - if not include_setup: - # Publisher+Subscriber: attach and wait for confirmation - p_id = p_dut.droid.wifiAwareAttach(False) - autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED) - time.sleep(startup_offset) - s_id = s_dut.droid.wifiAwareAttach(False) - autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED) - - for i in range(num_iterations): - while (True): # for pseudo-goto/finalize - timestamp_start = time.perf_counter() - - if include_setup: - # Publisher+Subscriber: attach and wait for confirmation - p_id = p_dut.droid.wifiAwareAttach(False) - autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED) - time.sleep(startup_offset) - s_id = s_dut.droid.wifiAwareAttach(False) - autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED) - - # start publish - p_disc_id, p_disc_event = self.start_discovery_session( - p_dut, p_id, True, aconsts.PUBLISH_TYPE_UNSOLICITED) - - # start subscribe - s_disc_id, s_session_event = self.start_discovery_session( - s_dut, s_id, False, aconsts.SUBSCRIBE_TYPE_PASSIVE) - - # wait for discovery (allow for failures here since running lots of - # samples and would like to get the partial data even in the presence of - # errors) - try: - event = s_dut.ed.pop_event(aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, - autils.EVENT_TIMEOUT) - s_dut.log.info("[Subscriber] SESSION_CB_ON_SERVICE_DISCOVERED: %s", - event["data"]) - peer_id_on_sub = event['data'][aconsts.SESSION_CB_KEY_PEER_ID] - except queue.Empty: - s_dut.log.info("[Subscriber] Timed out while waiting for " - "SESSION_CB_ON_SERVICE_DISCOVERED") - failures = failures + 1 - break - - # message from Sub -> Pub - msg_s2p = "Message Subscriber -> Publisher #%d" % i - next_msg_id = self.get_next_msg_id() - s_dut.droid.wifiAwareSendMessage(s_disc_id, peer_id_on_sub, next_msg_id, - msg_s2p, 0) - - # wait for Tx confirmation - try: - s_dut.ed.pop_event(aconsts.SESSION_CB_ON_MESSAGE_SENT, - autils.EVENT_TIMEOUT) - except queue.Empty: - s_dut.log.info("[Subscriber] Timed out while waiting for " - "SESSION_CB_ON_MESSAGE_SENT") - failures = failures + 1 - break - - # wait for Rx confirmation (and validate contents) - try: - event = p_dut.ed.pop_event(aconsts.SESSION_CB_ON_MESSAGE_RECEIVED, - autils.EVENT_TIMEOUT) - peer_id_on_pub = event['data'][aconsts.SESSION_CB_KEY_PEER_ID] - if (event["data"][ - aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING] != msg_s2p): - p_dut.log.info("[Publisher] Corrupted input message - %s", event) - failures = failures + 1 - break - except queue.Empty: - p_dut.log.info("[Publisher] Timed out while waiting for " - "SESSION_CB_ON_MESSAGE_RECEIVED") - failures = failures + 1 - break - - # message from Pub -> Sub - msg_p2s = "Message Publisher -> Subscriber #%d" % i - next_msg_id = self.get_next_msg_id() - p_dut.droid.wifiAwareSendMessage(p_disc_id, peer_id_on_pub, next_msg_id, - msg_p2s, 0) - - # wait for Tx confirmation - try: - p_dut.ed.pop_event(aconsts.SESSION_CB_ON_MESSAGE_SENT, - autils.EVENT_TIMEOUT) - except queue.Empty: - p_dut.log.info("[Publisher] Timed out while waiting for " - "SESSION_CB_ON_MESSAGE_SENT") - failures = failures + 1 - break - - # wait for Rx confirmation (and validate contents) - try: - event = s_dut.ed.pop_event(aconsts.SESSION_CB_ON_MESSAGE_RECEIVED, - autils.EVENT_TIMEOUT) - if (event["data"][ - aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING] != msg_p2s): - s_dut.log.info("[Subscriber] Corrupted input message - %s", event) - failures = failures + 1 - break - except queue.Empty: - s_dut.log.info("[Subscriber] Timed out while waiting for " - "SESSION_CB_ON_MESSAGE_RECEIVED") - failures = failures + 1 - break - - # create NDP - - # Publisher: request network - p_req_key = autils.request_network( + key = "dw24_%d_dw5_%d" % (dw_24ghz, dw_5ghz) + results[key] = {} + results[key]["num_iterations"] = num_iterations + + p_dut = self.android_devices[0] + p_dut.pretty_name = "Publisher" + s_dut = self.android_devices[1] + s_dut.pretty_name = "Subscriber" + + # override the default DW configuration + autils.config_power_settings(p_dut, dw_24ghz, dw_5ghz) + autils.config_power_settings(s_dut, dw_24ghz, dw_5ghz) + + latencies = [] + + # allow for failures here since running lots of samples and would like to + # get the partial data even in the presence of errors + failures = 0 + + if not include_setup: + # Publisher+Subscriber: attach and wait for confirmation + p_id = p_dut.droid.wifiAwareAttach(False) + autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED) + time.sleep(startup_offset) + s_id = s_dut.droid.wifiAwareAttach(False) + autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED) + + for i in range(num_iterations): + while (True): # for pseudo-goto/finalize + timestamp_start = time.perf_counter() + + if include_setup: + # Publisher+Subscriber: attach and wait for confirmation + p_id = p_dut.droid.wifiAwareAttach(False) + autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED) + time.sleep(startup_offset) + s_id = s_dut.droid.wifiAwareAttach(False) + autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED) + + # start publish + p_disc_id, p_disc_event = self.start_discovery_session( + p_dut, p_id, True, aconsts.PUBLISH_TYPE_UNSOLICITED) + + # start subscribe + s_disc_id, s_session_event = self.start_discovery_session( + s_dut, s_id, False, aconsts.SUBSCRIBE_TYPE_PASSIVE) + + # wait for discovery (allow for failures here since running lots of + # samples and would like to get the partial data even in the presence of + # errors) + try: + event = s_dut.ed.pop_event( + aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, + autils.EVENT_TIMEOUT) + s_dut.log.info( + "[Subscriber] SESSION_CB_ON_SERVICE_DISCOVERED: %s", + event["data"]) + peer_id_on_sub = event['data'][ + aconsts.SESSION_CB_KEY_PEER_ID] + except queue.Empty: + s_dut.log.info("[Subscriber] Timed out while waiting for " + "SESSION_CB_ON_SERVICE_DISCOVERED") + failures = failures + 1 + break + + # message from Sub -> Pub + msg_s2p = "Message Subscriber -> Publisher #%d" % i + next_msg_id = self.get_next_msg_id() + s_dut.droid.wifiAwareSendMessage(s_disc_id, peer_id_on_sub, + next_msg_id, msg_s2p, 0) + + # wait for Tx confirmation + try: + s_dut.ed.pop_event(aconsts.SESSION_CB_ON_MESSAGE_SENT, + autils.EVENT_TIMEOUT) + except queue.Empty: + s_dut.log.info("[Subscriber] Timed out while waiting for " + "SESSION_CB_ON_MESSAGE_SENT") + failures = failures + 1 + break + + # wait for Rx confirmation (and validate contents) + try: + event = p_dut.ed.pop_event( + aconsts.SESSION_CB_ON_MESSAGE_RECEIVED, + autils.EVENT_TIMEOUT) + peer_id_on_pub = event['data'][ + aconsts.SESSION_CB_KEY_PEER_ID] + if (event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING] + != msg_s2p): + p_dut.log.info( + "[Publisher] Corrupted input message - %s", event) + failures = failures + 1 + break + except queue.Empty: + p_dut.log.info("[Publisher] Timed out while waiting for " + "SESSION_CB_ON_MESSAGE_RECEIVED") + failures = failures + 1 + break + + # message from Pub -> Sub + msg_p2s = "Message Publisher -> Subscriber #%d" % i + next_msg_id = self.get_next_msg_id() + p_dut.droid.wifiAwareSendMessage(p_disc_id, peer_id_on_pub, + next_msg_id, msg_p2s, 0) + + # wait for Tx confirmation + try: + p_dut.ed.pop_event(aconsts.SESSION_CB_ON_MESSAGE_SENT, + autils.EVENT_TIMEOUT) + except queue.Empty: + p_dut.log.info("[Publisher] Timed out while waiting for " + "SESSION_CB_ON_MESSAGE_SENT") + failures = failures + 1 + break + + # wait for Rx confirmation (and validate contents) + try: + event = s_dut.ed.pop_event( + aconsts.SESSION_CB_ON_MESSAGE_RECEIVED, + autils.EVENT_TIMEOUT) + if (event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING] + != msg_p2s): + s_dut.log.info( + "[Subscriber] Corrupted input message - %s", event) + failures = failures + 1 + break + except queue.Empty: + s_dut.log.info("[Subscriber] Timed out while waiting for " + "SESSION_CB_ON_MESSAGE_RECEIVED") + failures = failures + 1 + break + + # create NDP + + # Publisher: request network + p_req_key = autils.request_network( + p_dut, + p_dut.droid.wifiAwareCreateNetworkSpecifier( + p_disc_id, peer_id_on_pub, None)) + + # Subscriber: request network + s_req_key = autils.request_network( + s_dut, + s_dut.droid.wifiAwareCreateNetworkSpecifier( + s_disc_id, peer_id_on_sub, None)) + + # Publisher & Subscriber: wait for network formation + try: + p_net_event = autils.wait_for_event_with_keys( + p_dut, cconsts.EVENT_NETWORK_CALLBACK, + autils.EVENT_TIMEOUT, + (cconsts.NETWORK_CB_KEY_EVENT, + cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), + (cconsts.NETWORK_CB_KEY_ID, p_req_key)) + s_net_event = autils.wait_for_event_with_keys( + s_dut, cconsts.EVENT_NETWORK_CALLBACK, + autils.EVENT_TIMEOUT, + (cconsts.NETWORK_CB_KEY_EVENT, + cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), + (cconsts.NETWORK_CB_KEY_ID, s_req_key)) + except: + failures = failures + 1 + break + + p_aware_if = p_net_event["data"][ + cconsts.NETWORK_CB_KEY_INTERFACE_NAME] + s_aware_if = s_net_event["data"][ + cconsts.NETWORK_CB_KEY_INTERFACE_NAME] + + p_ipv6 = \ + p_dut.droid.connectivityGetLinkLocalIpv6Address(p_aware_if).split("%")[ + 0] + s_ipv6 = \ + s_dut.droid.connectivityGetLinkLocalIpv6Address(s_aware_if).split("%")[ + 0] + + p_dut.log.info("[Publisher] IF=%s, IPv6=%s", p_aware_if, + p_ipv6) + s_dut.log.info("[Subscriber] IF=%s, IPv6=%s", s_aware_if, + s_ipv6) + + latencies.append(time.perf_counter() - timestamp_start) + break + + # destroy sessions + p_dut.droid.wifiAwareDestroyDiscoverySession(p_disc_id) + s_dut.droid.wifiAwareDestroyDiscoverySession(s_disc_id) + if include_setup: + p_dut.droid.wifiAwareDestroy(p_id) + s_dut.droid.wifiAwareDestroy(s_id) + + autils.extract_stats( p_dut, - p_dut.droid.wifiAwareCreateNetworkSpecifier(p_disc_id, - peer_id_on_pub, None)) + data=latencies, + results=results[key], + key_prefix="", + log_prefix="End-to-End(dw24=%d, dw5=%d)" % (dw_24ghz, dw_5ghz)) + results[key]["failures"] = failures - # Subscriber: request network - s_req_key = autils.request_network( - s_dut, - s_dut.droid.wifiAwareCreateNetworkSpecifier(s_disc_id, - peer_id_on_sub, None)) - - # Publisher & Subscriber: wait for network formation - try: - p_net_event = autils.wait_for_event_with_keys( - p_dut, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_TIMEOUT, ( - cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, p_req_key)) - s_net_event = autils.wait_for_event_with_keys( - s_dut, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_TIMEOUT, ( - cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, s_req_key)) - except: - failures = failures + 1 - break - - p_aware_if = p_net_event["data"][cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - s_aware_if = s_net_event["data"][cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - - p_ipv6 = \ - p_dut.droid.connectivityGetLinkLocalIpv6Address(p_aware_if).split("%")[ - 0] - s_ipv6 = \ - s_dut.droid.connectivityGetLinkLocalIpv6Address(s_aware_if).split("%")[ - 0] - - p_dut.log.info("[Publisher] IF=%s, IPv6=%s", p_aware_if, p_ipv6) - s_dut.log.info("[Subscriber] IF=%s, IPv6=%s", s_aware_if, s_ipv6) - - latencies.append(time.perf_counter() - timestamp_start) - break - - # destroy sessions - p_dut.droid.wifiAwareDestroyDiscoverySession(p_disc_id) - s_dut.droid.wifiAwareDestroyDiscoverySession(s_disc_id) - if include_setup: - p_dut.droid.wifiAwareDestroy(p_id) - s_dut.droid.wifiAwareDestroy(s_id) - - autils.extract_stats( - p_dut, - data=latencies, - results=results[key], - key_prefix="", - log_prefix="End-to-End(dw24=%d, dw5=%d)" % (dw_24ghz, dw_5ghz)) - results[key]["failures"] = failures - - - ######################################################################## - - def test_synchronization_default_dws(self): - """Measure the device synchronization for default dws. Loop over values + ######################################################################## + + def test_synchronization_default_dws(self): + """Measure the device synchronization for default dws. Loop over values from 0 to 4 seconds.""" - results = {} - for startup_offset in range(5): - self.run_synchronization_latency( - results=results, - do_unsolicited_passive=True, - dw_24ghz=aconsts.POWER_DW_24_INTERACTIVE, - dw_5ghz=aconsts.POWER_DW_5_INTERACTIVE, - num_iterations=10, - startup_offset=startup_offset, - timeout_period=20) - asserts.explicit_pass( - "test_synchronization_default_dws finished", extras=results) - - def test_synchronization_non_interactive_dws(self): - """Measure the device synchronization for non-interactive dws. Loop over + results = {} + for startup_offset in range(5): + self.run_synchronization_latency( + results=results, + do_unsolicited_passive=True, + dw_24ghz=aconsts.POWER_DW_24_INTERACTIVE, + dw_5ghz=aconsts.POWER_DW_5_INTERACTIVE, + num_iterations=10, + startup_offset=startup_offset, + timeout_period=20) + asserts.explicit_pass( + "test_synchronization_default_dws finished", extras=results) + + def test_synchronization_non_interactive_dws(self): + """Measure the device synchronization for non-interactive dws. Loop over values from 0 to 4 seconds.""" - results = {} - for startup_offset in range(5): - self.run_synchronization_latency( - results=results, - do_unsolicited_passive=True, - dw_24ghz=aconsts.POWER_DW_24_NON_INTERACTIVE, - dw_5ghz=aconsts.POWER_DW_5_NON_INTERACTIVE, - num_iterations=10, - startup_offset=startup_offset, - timeout_period=20) - asserts.explicit_pass( - "test_synchronization_non_interactive_dws finished", extras=results) - - def test_discovery_latency_default_dws(self): - """Measure the service discovery latency with the default DW configuration. + results = {} + for startup_offset in range(5): + self.run_synchronization_latency( + results=results, + do_unsolicited_passive=True, + dw_24ghz=aconsts.POWER_DW_24_NON_INTERACTIVE, + dw_5ghz=aconsts.POWER_DW_5_NON_INTERACTIVE, + num_iterations=10, + startup_offset=startup_offset, + timeout_period=20) + asserts.explicit_pass( + "test_synchronization_non_interactive_dws finished", + extras=results) + + def test_discovery_latency_default_dws(self): + """Measure the service discovery latency with the default DW configuration. """ - results = {} - self.run_discovery_latency( - results=results, - do_unsolicited_passive=True, - dw_24ghz=aconsts.POWER_DW_24_INTERACTIVE, - dw_5ghz=aconsts.POWER_DW_5_INTERACTIVE, - num_iterations=100) - asserts.explicit_pass( - "test_discovery_latency_default_parameters finished", extras=results) - - def test_discovery_latency_non_interactive_dws(self): - """Measure the service discovery latency with the DW configuration for non + results = {} + self.run_discovery_latency( + results=results, + do_unsolicited_passive=True, + dw_24ghz=aconsts.POWER_DW_24_INTERACTIVE, + dw_5ghz=aconsts.POWER_DW_5_INTERACTIVE, + num_iterations=100) + asserts.explicit_pass( + "test_discovery_latency_default_parameters finished", + extras=results) + + def test_discovery_latency_non_interactive_dws(self): + """Measure the service discovery latency with the DW configuration for non -interactive mode (lower power).""" - results = {} - self.run_discovery_latency( - results=results, - do_unsolicited_passive=True, - dw_24ghz=aconsts.POWER_DW_24_NON_INTERACTIVE, - dw_5ghz=aconsts.POWER_DW_5_NON_INTERACTIVE, - num_iterations=100) - asserts.explicit_pass( - "test_discovery_latency_non_interactive_dws finished", extras=results) - - def test_discovery_latency_all_dws(self): - """Measure the service discovery latency with all DW combinations (low - iteration count)""" - results = {} - for dw24 in range(1, 6): # permitted values: 1-5 - for dw5 in range(0, 6): # permitted values: 0, 1-5 + results = {} self.run_discovery_latency( results=results, do_unsolicited_passive=True, - dw_24ghz=dw24, - dw_5ghz=dw5, - num_iterations=10) - asserts.explicit_pass( - "test_discovery_latency_all_dws finished", extras=results) - - def test_message_latency_default_dws(self): - """Measure the send message latency with the default DW configuration. Test + dw_24ghz=aconsts.POWER_DW_24_NON_INTERACTIVE, + dw_5ghz=aconsts.POWER_DW_5_NON_INTERACTIVE, + num_iterations=100) + asserts.explicit_pass( + "test_discovery_latency_non_interactive_dws finished", + extras=results) + + def test_discovery_latency_all_dws(self): + """Measure the service discovery latency with all DW combinations (low + iteration count)""" + results = {} + for dw24 in range(1, 6): # permitted values: 1-5 + for dw5 in range(0, 6): # permitted values: 0, 1-5 + self.run_discovery_latency( + results=results, + do_unsolicited_passive=True, + dw_24ghz=dw24, + dw_5ghz=dw5, + num_iterations=10) + asserts.explicit_pass( + "test_discovery_latency_all_dws finished", extras=results) + + def test_message_latency_default_dws(self): + """Measure the send message latency with the default DW configuration. Test performed on non-queued message transmission - i.e. waiting for confirmation of reception (ACK) before sending the next message.""" - results = {} - self.run_message_latency( - results=results, - dw_24ghz=aconsts.POWER_DW_24_INTERACTIVE, - dw_5ghz=aconsts.POWER_DW_5_INTERACTIVE, - num_iterations=100) - asserts.explicit_pass( - "test_message_latency_default_dws finished", extras=results) - - def test_message_latency_non_interactive_dws(self): - """Measure the send message latency with the DW configuration for + results = {} + self.run_message_latency( + results=results, + dw_24ghz=aconsts.POWER_DW_24_INTERACTIVE, + dw_5ghz=aconsts.POWER_DW_5_INTERACTIVE, + num_iterations=100) + asserts.explicit_pass( + "test_message_latency_default_dws finished", extras=results) + + def test_message_latency_non_interactive_dws(self): + """Measure the send message latency with the DW configuration for non-interactive mode. Test performed on non-queued message transmission - i.e. waiting for confirmation of reception (ACK) before sending the next message.""" - results = {} - self.run_message_latency( - results=results, - dw_24ghz=aconsts.POWER_DW_24_NON_INTERACTIVE, - dw_5ghz=aconsts.POWER_DW_5_NON_INTERACTIVE, - num_iterations=100) - asserts.explicit_pass( - "test_message_latency_non_interactive_dws finished", extras=results) - - def test_oob_ndp_setup_latency_default_dws(self): - """Measure the NDP setup latency with the default DW configuration. The + results = {} + self.run_message_latency( + results=results, + dw_24ghz=aconsts.POWER_DW_24_NON_INTERACTIVE, + dw_5ghz=aconsts.POWER_DW_5_NON_INTERACTIVE, + num_iterations=100) + asserts.explicit_pass( + "test_message_latency_non_interactive_dws finished", + extras=results) + + def test_oob_ndp_setup_latency_default_dws(self): + """Measure the NDP setup latency with the default DW configuration. The NDP is setup with OOB (out-of-band) configuration.""" - results = {} - self.run_ndp_oob_latency( - results=results, - dw_24ghz=aconsts.POWER_DW_24_INTERACTIVE, - dw_5ghz=aconsts.POWER_DW_5_INTERACTIVE, - num_iterations=100) - asserts.explicit_pass( - "test_ndp_setup_latency_default_dws finished", extras=results) - - def test_oob_ndp_setup_latency_non_interactive_dws(self): - """Measure the NDP setup latency with the DW configuration for + results = {} + self.run_ndp_oob_latency( + results=results, + dw_24ghz=aconsts.POWER_DW_24_INTERACTIVE, + dw_5ghz=aconsts.POWER_DW_5_INTERACTIVE, + num_iterations=100) + asserts.explicit_pass( + "test_ndp_setup_latency_default_dws finished", extras=results) + + def test_oob_ndp_setup_latency_non_interactive_dws(self): + """Measure the NDP setup latency with the DW configuration for non-interactive mode. The NDP is setup with OOB (out-of-band) configuration""" - results = {} - self.run_ndp_oob_latency( - results=results, - dw_24ghz=aconsts.POWER_DW_24_NON_INTERACTIVE, - dw_5ghz=aconsts.POWER_DW_5_NON_INTERACTIVE, - num_iterations=100) - asserts.explicit_pass( - "test_ndp_setup_latency_non_interactive_dws finished", extras=results) - - def test_end_to_end_latency_default_dws(self): - """Measure the latency for end-to-end communication link setup: + results = {} + self.run_ndp_oob_latency( + results=results, + dw_24ghz=aconsts.POWER_DW_24_NON_INTERACTIVE, + dw_5ghz=aconsts.POWER_DW_5_NON_INTERACTIVE, + num_iterations=100) + asserts.explicit_pass( + "test_ndp_setup_latency_non_interactive_dws finished", + extras=results) + + def test_end_to_end_latency_default_dws(self): + """Measure the latency for end-to-end communication link setup: - Start Aware - Discovery - Message from Sub -> Pub - Message from Pub -> Sub - NDP setup """ - results = {} - self.run_end_to_end_latency( - results, - dw_24ghz=aconsts.POWER_DW_24_INTERACTIVE, - dw_5ghz=aconsts.POWER_DW_5_INTERACTIVE, - num_iterations=10, - startup_offset=0, - include_setup=True) - asserts.explicit_pass( - "test_end_to_end_latency_default_dws finished", extras=results) - - def test_end_to_end_latency_post_attach_default_dws(self): - """Measure the latency for end-to-end communication link setup without + results = {} + self.run_end_to_end_latency( + results, + dw_24ghz=aconsts.POWER_DW_24_INTERACTIVE, + dw_5ghz=aconsts.POWER_DW_5_INTERACTIVE, + num_iterations=10, + startup_offset=0, + include_setup=True) + asserts.explicit_pass( + "test_end_to_end_latency_default_dws finished", extras=results) + + def test_end_to_end_latency_post_attach_default_dws(self): + """Measure the latency for end-to-end communication link setup without the initial synchronization: - Start Aware & synchronize initially - Loop: @@ -787,14 +815,14 @@ class LatencyTest(AwareBaseTest): - Message from Pub -> Sub - NDP setup """ - results = {} - self.run_end_to_end_latency( - results, - dw_24ghz=aconsts.POWER_DW_24_INTERACTIVE, - dw_5ghz=aconsts.POWER_DW_5_INTERACTIVE, - num_iterations=10, - startup_offset=0, - include_setup=False) - asserts.explicit_pass( - "test_end_to_end_latency_post_attach_default_dws finished", - extras=results) + results = {} + self.run_end_to_end_latency( + results, + dw_24ghz=aconsts.POWER_DW_24_INTERACTIVE, + dw_5ghz=aconsts.POWER_DW_5_INTERACTIVE, + num_iterations=10, + startup_offset=0, + include_setup=False) + asserts.explicit_pass( + "test_end_to_end_latency_post_attach_default_dws finished", + extras=results) diff --git a/acts/tests/google/wifi/aware/performance/ThroughputTest.py b/acts/tests/google/wifi/aware/performance/ThroughputTest.py index ddb6d15ae1..a5b1b8d737 100644 --- a/acts/tests/google/wifi/aware/performance/ThroughputTest.py +++ b/acts/tests/google/wifi/aware/performance/ThroughputTest.py @@ -28,82 +28,84 @@ from acts.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest class ThroughputTest(AwareBaseTest): - """Set of tests for Wi-Fi Aware to measure latency of Aware operations.""" + """Set of tests for Wi-Fi Aware to measure latency of Aware operations.""" - SERVICE_NAME = "GoogleTestServiceXYZ" + SERVICE_NAME = "GoogleTestServiceXYZ" - PASSPHRASE = "This is some random passphrase - very very secure!!" - PASSPHRASE2 = "This is some random passphrase - very very secure - but diff!!" + PASSPHRASE = "This is some random passphrase - very very secure!!" + PASSPHRASE2 = "This is some random passphrase - very very secure - but diff!!" - def __init__(self, controllers): - super(ThroughputTest, self).__init__(controllers) + def __init__(self, controllers): + super(ThroughputTest, self).__init__(controllers) - def request_network(self, dut, ns): - """Request a Wi-Fi Aware network. + def request_network(self, dut, ns): + """Request a Wi-Fi Aware network. Args: dut: Device ns: Network specifier Returns: the request key """ - network_req = {"TransportType": 5, "NetworkSpecifier": ns} - return dut.droid.connectivityRequestWifiAwareNetwork(network_req) + network_req = {"TransportType": 5, "NetworkSpecifier": ns} + return dut.droid.connectivityRequestWifiAwareNetwork(network_req) - def run_iperf_single_ndp_aware_only(self, use_ib, results): - """Measure iperf performance on a single NDP, with Aware enabled and no + def run_iperf_single_ndp_aware_only(self, use_ib, results): + """Measure iperf performance on a single NDP, with Aware enabled and no infrastructure connection - i.e. device is not associated to an AP. Args: use_ib: True to use in-band discovery, False to use out-of-band discovery. results: Dictionary into which to place test results. """ - init_dut = self.android_devices[0] - resp_dut = self.android_devices[1] - - if use_ib: - # note: Publisher = Responder, Subscribe = Initiator - (resp_req_key, init_req_key, resp_aware_if, - init_aware_if, resp_ipv6, init_ipv6) = autils.create_ib_ndp( - resp_dut, init_dut, - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.PUBLISH_TYPE_UNSOLICITED), - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.SUBSCRIBE_TYPE_PASSIVE), - self.device_startup_offset) - else: - (init_req_key, resp_req_key, init_aware_if, resp_aware_if, init_ipv6, - resp_ipv6) = autils.create_oob_ndp(init_dut, resp_dut) - self.log.info("Interface names: I=%s, R=%s", init_aware_if, resp_aware_if) - self.log.info("Interface addresses (IPv6): I=%s, R=%s", init_ipv6, - resp_ipv6) - - # Run iperf3 - result, data = init_dut.run_iperf_server("-D") - asserts.assert_true(result, "Can't start iperf3 server") - - result, data = resp_dut.run_iperf_client( - "%s%%%s" % (init_ipv6, resp_aware_if), "-6 -J") - self.log.debug(data) - asserts.assert_true(result, - "Failure starting/running iperf3 in client mode") - self.log.debug(pprint.pformat(data)) - - # clean-up - resp_dut.droid.connectivityUnregisterNetworkCallback(resp_req_key) - init_dut.droid.connectivityUnregisterNetworkCallback(init_req_key) - - # Collect results - data_json = json.loads("".join(data)) - if "error" in data_json: - asserts.fail( - "iperf run failed: %s" % data_json["error"], extras=data_json) - results["tx_rate"] = data_json["end"]["sum_sent"]["bits_per_second"] - results["rx_rate"] = data_json["end"]["sum_received"]["bits_per_second"] - self.log.info("iPerf3: Sent = %d bps Received = %d bps", results["tx_rate"], - results["rx_rate"]) - - def run_iperf(self, q, dut, peer_dut, peer_aware_if, dut_ipv6, port): - """Runs iperf and places results in the queue. + init_dut = self.android_devices[0] + resp_dut = self.android_devices[1] + + if use_ib: + # note: Publisher = Responder, Subscribe = Initiator + (resp_req_key, init_req_key, resp_aware_if, init_aware_if, + resp_ipv6, init_ipv6) = autils.create_ib_ndp( + resp_dut, init_dut, + autils.create_discovery_config( + self.SERVICE_NAME, aconsts.PUBLISH_TYPE_UNSOLICITED), + autils.create_discovery_config( + self.SERVICE_NAME, aconsts.SUBSCRIBE_TYPE_PASSIVE), + self.device_startup_offset) + else: + (init_req_key, resp_req_key, init_aware_if, resp_aware_if, + init_ipv6, resp_ipv6) = autils.create_oob_ndp(init_dut, resp_dut) + self.log.info("Interface names: I=%s, R=%s", init_aware_if, + resp_aware_if) + self.log.info("Interface addresses (IPv6): I=%s, R=%s", init_ipv6, + resp_ipv6) + + # Run iperf3 + result, data = init_dut.run_iperf_server("-D") + asserts.assert_true(result, "Can't start iperf3 server") + + result, data = resp_dut.run_iperf_client( + "%s%%%s" % (init_ipv6, resp_aware_if), "-6 -J") + self.log.debug(data) + asserts.assert_true(result, + "Failure starting/running iperf3 in client mode") + self.log.debug(pprint.pformat(data)) + + # clean-up + resp_dut.droid.connectivityUnregisterNetworkCallback(resp_req_key) + init_dut.droid.connectivityUnregisterNetworkCallback(init_req_key) + + # Collect results + data_json = json.loads("".join(data)) + if "error" in data_json: + asserts.fail( + "iperf run failed: %s" % data_json["error"], extras=data_json) + results["tx_rate"] = data_json["end"]["sum_sent"]["bits_per_second"] + results["rx_rate"] = data_json["end"]["sum_received"][ + "bits_per_second"] + self.log.info("iPerf3: Sent = %d bps Received = %d bps", + results["tx_rate"], results["rx_rate"]) + + def run_iperf(self, q, dut, peer_dut, peer_aware_if, dut_ipv6, port): + """Runs iperf and places results in the queue. Args: q: The queue into which to place the results @@ -113,16 +115,16 @@ class ThroughputTest(AwareBaseTest): dut_ipv6: The IPv6 address of the server. port: The port to use for the server and client. """ - result, data = dut.run_iperf_server("-D -p %d" % port) - asserts.assert_true(result, "Can't start iperf3 server") + result, data = dut.run_iperf_server("-D -p %d" % port) + asserts.assert_true(result, "Can't start iperf3 server") - result, data = peer_dut.run_iperf_client( - "%s%%%s" % (dut_ipv6, peer_aware_if), "-6 -J -p %d" % port) - self.log.debug(data) - q.put((result, data)) + result, data = peer_dut.run_iperf_client( + "%s%%%s" % (dut_ipv6, peer_aware_if), "-6 -J -p %d" % port) + self.log.debug(data) + q.put((result, data)) - def run_iperf_max_ndp_aware_only(self, results): - """Measure iperf performance on the max number of concurrent OOB NDPs, with + def run_iperf_max_ndp_aware_only(self, results): + """Measure iperf performance on the max number of concurrent OOB NDPs, with Aware enabled and no infrastructure connection - i.e. device is not associated to an AP. @@ -132,117 +134,123 @@ class ThroughputTest(AwareBaseTest): Args: results: Dictionary into which to place test results. """ - dut = self.android_devices[0] - - # get max NDP: using first available device (assumes all devices are the - # same) - max_ndp = dut.aware_capabilities[aconsts.CAP_MAX_NDP_SESSIONS] - asserts.assert_true(len(self.android_devices) > max_ndp, - 'Needed %d devices to run the test, have %d' % - (max_ndp + 1, len(self.android_devices))) - - # create all NDPs - dut_aware_if = None - dut_ipv6 = None - peers_aware_ifs = [] - peers_ipv6s = [] - dut_requests = [] - peers_requests = [] - for i in range(max_ndp): - (init_req_key, resp_req_key, init_aware_if, resp_aware_if, init_ipv6, - resp_ipv6) = autils.create_oob_ndp(dut, self.android_devices[i + 1]) - self.log.info("Interface names: I=%s, R=%s", init_aware_if, resp_aware_if) - self.log.info("Interface addresses (IPv6): I=%s, R=%s", init_ipv6, - resp_ipv6) - - dut_requests.append(init_req_key) - peers_requests.append(resp_req_key) - if dut_aware_if is None: - dut_aware_if = init_aware_if - else: - asserts.assert_equal( - dut_aware_if, init_aware_if, - "DUT (Initiator) interface changed on subsequent NDPs!?") - if dut_ipv6 is None: - dut_ipv6 = init_ipv6 - else: - asserts.assert_equal( - dut_ipv6, init_ipv6, - "DUT (Initiator) IPv6 changed on subsequent NDPs!?") - peers_aware_ifs.append(resp_aware_if) - peers_ipv6s.append(resp_ipv6) - - # create threads, start them, and wait for all to finish - base_port = 5000 - q = queue.Queue() - threads = [] - for i in range(max_ndp): - threads.append( - threading.Thread( - target=self.run_iperf, - args=(q, dut, self.android_devices[i + 1], peers_aware_ifs[i], - dut_ipv6, base_port + i))) - - for thread in threads: - thread.start() - - for thread in threads: - thread.join() - - # cleanup - for i in range(max_ndp): - dut.droid.connectivityUnregisterNetworkCallback(dut_requests[i]) - self.android_devices[i + 1].droid.connectivityUnregisterNetworkCallback( - peers_requests[i]) - - # collect data - for i in range(max_ndp): - results[i] = {} - result, data = q.get() - asserts.assert_true(result, - "Failure starting/running iperf3 in client mode") - self.log.debug(pprint.pformat(data)) - data_json = json.loads("".join(data)) - if "error" in data_json: - asserts.fail( - "iperf run failed: %s" % data_json["error"], extras=data_json) - results[i]["tx_rate"] = data_json["end"]["sum_sent"]["bits_per_second"] - results[i]["rx_rate"] = data_json["end"]["sum_received"][ - "bits_per_second"] - self.log.info("iPerf3: Sent = %d bps Received = %d bps", - results[i]["tx_rate"], results[i]["rx_rate"]) - - ######################################################################## - - def test_iperf_single_ndp_aware_only_ib(self): - """Measure throughput using iperf on a single NDP, with Aware enabled and + dut = self.android_devices[0] + + # get max NDP: using first available device (assumes all devices are the + # same) + max_ndp = dut.aware_capabilities[aconsts.CAP_MAX_NDP_SESSIONS] + asserts.assert_true( + len(self.android_devices) > max_ndp, + 'Needed %d devices to run the test, have %d' % + (max_ndp + 1, len(self.android_devices))) + + # create all NDPs + dut_aware_if = None + dut_ipv6 = None + peers_aware_ifs = [] + peers_ipv6s = [] + dut_requests = [] + peers_requests = [] + for i in range(max_ndp): + (init_req_key, resp_req_key, init_aware_if, resp_aware_if, + init_ipv6, resp_ipv6) = autils.create_oob_ndp( + dut, self.android_devices[i + 1]) + self.log.info("Interface names: I=%s, R=%s", init_aware_if, + resp_aware_if) + self.log.info("Interface addresses (IPv6): I=%s, R=%s", init_ipv6, + resp_ipv6) + + dut_requests.append(init_req_key) + peers_requests.append(resp_req_key) + if dut_aware_if is None: + dut_aware_if = init_aware_if + else: + asserts.assert_equal( + dut_aware_if, init_aware_if, + "DUT (Initiator) interface changed on subsequent NDPs!?") + if dut_ipv6 is None: + dut_ipv6 = init_ipv6 + else: + asserts.assert_equal( + dut_ipv6, init_ipv6, + "DUT (Initiator) IPv6 changed on subsequent NDPs!?") + peers_aware_ifs.append(resp_aware_if) + peers_ipv6s.append(resp_ipv6) + + # create threads, start them, and wait for all to finish + base_port = 5000 + q = queue.Queue() + threads = [] + for i in range(max_ndp): + threads.append( + threading.Thread( + target=self.run_iperf, + args=(q, dut, self.android_devices[i + 1], + peers_aware_ifs[i], dut_ipv6, base_port + i))) + + for thread in threads: + thread.start() + + for thread in threads: + thread.join() + + # cleanup + for i in range(max_ndp): + dut.droid.connectivityUnregisterNetworkCallback(dut_requests[i]) + self.android_devices[ + i + 1].droid.connectivityUnregisterNetworkCallback( + peers_requests[i]) + + # collect data + for i in range(max_ndp): + results[i] = {} + result, data = q.get() + asserts.assert_true( + result, "Failure starting/running iperf3 in client mode") + self.log.debug(pprint.pformat(data)) + data_json = json.loads("".join(data)) + if "error" in data_json: + asserts.fail( + "iperf run failed: %s" % data_json["error"], + extras=data_json) + results[i]["tx_rate"] = data_json["end"]["sum_sent"][ + "bits_per_second"] + results[i]["rx_rate"] = data_json["end"]["sum_received"][ + "bits_per_second"] + self.log.info("iPerf3: Sent = %d bps Received = %d bps", + results[i]["tx_rate"], results[i]["rx_rate"]) + + ######################################################################## + + def test_iperf_single_ndp_aware_only_ib(self): + """Measure throughput using iperf on a single NDP, with Aware enabled and no infrastructure connection. Use in-band discovery.""" - results = {} - self.run_iperf_single_ndp_aware_only(use_ib=True, results=results) - asserts.explicit_pass( - "test_iperf_single_ndp_aware_only_ib passes", extras=results) + results = {} + self.run_iperf_single_ndp_aware_only(use_ib=True, results=results) + asserts.explicit_pass( + "test_iperf_single_ndp_aware_only_ib passes", extras=results) - def test_iperf_single_ndp_aware_only_oob(self): - """Measure throughput using iperf on a single NDP, with Aware enabled and + def test_iperf_single_ndp_aware_only_oob(self): + """Measure throughput using iperf on a single NDP, with Aware enabled and no infrastructure connection. Use out-of-band discovery.""" - results = {} - self.run_iperf_single_ndp_aware_only(use_ib=False, results=results) - asserts.explicit_pass( - "test_iperf_single_ndp_aware_only_oob passes", extras=results) + results = {} + self.run_iperf_single_ndp_aware_only(use_ib=False, results=results) + asserts.explicit_pass( + "test_iperf_single_ndp_aware_only_oob passes", extras=results) - def test_iperf_max_ndp_aware_only_oob(self): - """Measure throughput using iperf on all possible concurrent NDPs, with + def test_iperf_max_ndp_aware_only_oob(self): + """Measure throughput using iperf on all possible concurrent NDPs, with Aware enabled and no infrastructure connection. Use out-of-band discovery. """ - results = {} - self.run_iperf_max_ndp_aware_only(results=results) - asserts.explicit_pass( - "test_iperf_max_ndp_aware_only_oob passes", extras=results) + results = {} + self.run_iperf_max_ndp_aware_only(results=results) + asserts.explicit_pass( + "test_iperf_max_ndp_aware_only_oob passes", extras=results) - ######################################################################## + ######################################################################## - def run_iperf_max_ndi_aware_only(self, sec_configs, results): - """Measure iperf performance on multiple NDPs between 2 devices using + def run_iperf_max_ndi_aware_only(self, sec_configs, results): + """Measure iperf performance on multiple NDPs between 2 devices using different security configurations (and hence different NDIs). Test with Aware enabled and no infrastructure connection - i.e. device is not associated to an AP. @@ -256,123 +264,126 @@ class ThroughputTest(AwareBaseTest): sec_configs: list of security configurations results: Dictionary into which to place test results. """ - init_dut = self.android_devices[0] - init_dut.pretty_name = "Initiator" - resp_dut = self.android_devices[1] - resp_dut.pretty_name = "Responder" - - asserts.skip_if(init_dut.aware_capabilities[aconsts.CAP_MAX_NDI_INTERFACES] - < len(sec_configs) or - resp_dut.aware_capabilities[aconsts.CAP_MAX_NDI_INTERFACES] - < len(sec_configs), - "Initiator or Responder do not support multiple NDIs") - - - init_id, init_mac = autils.attach_with_identity(init_dut) - resp_id, resp_mac = autils.attach_with_identity(resp_dut) - - # wait for for devices to synchronize with each other - there are no other - # mechanisms to make sure this happens for OOB discovery (except retrying - # to execute the data-path request) - time.sleep(autils.WAIT_FOR_CLUSTER) - - resp_req_keys = [] - init_req_keys = [] - resp_aware_ifs = [] - init_aware_ifs = [] - resp_aware_ipv6s = [] - init_aware_ipv6s = [] - - for sec in sec_configs: - # Responder: request network - resp_req_key = autils.request_network(resp_dut, - autils.get_network_specifier( - resp_dut, resp_id, - aconsts.DATA_PATH_RESPONDER, - init_mac, sec)) - resp_req_keys.append(resp_req_key) - - # Initiator: request network - init_req_key = autils.request_network(init_dut, - autils.get_network_specifier( - init_dut, init_id, - aconsts.DATA_PATH_INITIATOR, - resp_mac, sec)) - init_req_keys.append(init_req_key) - - # Wait for network - init_net_event = autils.wait_for_event_with_keys( - init_dut, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, init_req_key)) - resp_net_event = autils.wait_for_event_with_keys( - resp_dut, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, resp_req_key)) - - resp_aware_ifs.append( - resp_net_event["data"][cconsts.NETWORK_CB_KEY_INTERFACE_NAME]) - init_aware_ifs.append( - init_net_event["data"][cconsts.NETWORK_CB_KEY_INTERFACE_NAME]) - - resp_aware_ipv6s.append( - autils.get_ipv6_addr(resp_dut, resp_aware_ifs[-1])) - init_aware_ipv6s.append( - autils.get_ipv6_addr(init_dut, init_aware_ifs[-1])) - - self.log.info("Initiator interfaces/ipv6: %s / %s", init_aware_ifs, - init_aware_ipv6s) - self.log.info("Responder interfaces/ipv6: %s / %s", resp_aware_ifs, - resp_aware_ipv6s) - - # create threads, start them, and wait for all to finish - base_port = 5000 - q = queue.Queue() - threads = [] - for i in range(len(sec_configs)): - threads.append( - threading.Thread( - target=self.run_iperf, - args=(q, init_dut, resp_dut, resp_aware_ifs[i], init_aware_ipv6s[ - i], base_port + i))) - - for thread in threads: - thread.start() - - for thread in threads: - thread.join() - - # release requests - for resp_req_key in resp_req_keys: - resp_dut.droid.connectivityUnregisterNetworkCallback(resp_req_key) - for init_req_key in init_req_keys: - init_dut.droid.connectivityUnregisterNetworkCallback(init_req_key) - - - # collect data - for i in range(len(sec_configs)): - results[i] = {} - result, data = q.get() - asserts.assert_true(result, - "Failure starting/running iperf3 in client mode") - self.log.debug(pprint.pformat(data)) - data_json = json.loads("".join(data)) - if "error" in data_json: - asserts.fail( - "iperf run failed: %s" % data_json["error"], extras=data_json) - results[i]["tx_rate"] = data_json["end"]["sum_sent"]["bits_per_second"] - results[i]["rx_rate"] = data_json["end"]["sum_received"][ - "bits_per_second"] - self.log.info("iPerf3: Sent = %d bps Received = %d bps", - results[i]["tx_rate"], results[i]["rx_rate"]) - - def test_iperf_max_ndi_aware_only_passphrases(self): - """Test throughput for multiple NDIs configured with different passphrases. + init_dut = self.android_devices[0] + init_dut.pretty_name = "Initiator" + resp_dut = self.android_devices[1] + resp_dut.pretty_name = "Responder" + + asserts.skip_if( + init_dut.aware_capabilities[aconsts.CAP_MAX_NDI_INTERFACES] < + len(sec_configs) + or resp_dut.aware_capabilities[aconsts.CAP_MAX_NDI_INTERFACES] < + len(sec_configs), + "Initiator or Responder do not support multiple NDIs") + + init_id, init_mac = autils.attach_with_identity(init_dut) + resp_id, resp_mac = autils.attach_with_identity(resp_dut) + + # wait for for devices to synchronize with each other - there are no other + # mechanisms to make sure this happens for OOB discovery (except retrying + # to execute the data-path request) + time.sleep(autils.WAIT_FOR_CLUSTER) + + resp_req_keys = [] + init_req_keys = [] + resp_aware_ifs = [] + init_aware_ifs = [] + resp_aware_ipv6s = [] + init_aware_ipv6s = [] + + for sec in sec_configs: + # Responder: request network + resp_req_key = autils.request_network( + resp_dut, + autils.get_network_specifier(resp_dut, resp_id, + aconsts.DATA_PATH_RESPONDER, + init_mac, sec)) + resp_req_keys.append(resp_req_key) + + # Initiator: request network + init_req_key = autils.request_network( + init_dut, + autils.get_network_specifier(init_dut, init_id, + aconsts.DATA_PATH_INITIATOR, + resp_mac, sec)) + init_req_keys.append(init_req_key) + + # Wait for network + init_net_event = autils.wait_for_event_with_keys( + init_dut, cconsts.EVENT_NETWORK_CALLBACK, + autils.EVENT_NDP_TIMEOUT, + (cconsts.NETWORK_CB_KEY_EVENT, + cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), + (cconsts.NETWORK_CB_KEY_ID, init_req_key)) + resp_net_event = autils.wait_for_event_with_keys( + resp_dut, cconsts.EVENT_NETWORK_CALLBACK, + autils.EVENT_NDP_TIMEOUT, + (cconsts.NETWORK_CB_KEY_EVENT, + cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), + (cconsts.NETWORK_CB_KEY_ID, resp_req_key)) + + resp_aware_ifs.append( + resp_net_event["data"][cconsts.NETWORK_CB_KEY_INTERFACE_NAME]) + init_aware_ifs.append( + init_net_event["data"][cconsts.NETWORK_CB_KEY_INTERFACE_NAME]) + + resp_aware_ipv6s.append( + autils.get_ipv6_addr(resp_dut, resp_aware_ifs[-1])) + init_aware_ipv6s.append( + autils.get_ipv6_addr(init_dut, init_aware_ifs[-1])) + + self.log.info("Initiator interfaces/ipv6: %s / %s", init_aware_ifs, + init_aware_ipv6s) + self.log.info("Responder interfaces/ipv6: %s / %s", resp_aware_ifs, + resp_aware_ipv6s) + + # create threads, start them, and wait for all to finish + base_port = 5000 + q = queue.Queue() + threads = [] + for i in range(len(sec_configs)): + threads.append( + threading.Thread( + target=self.run_iperf, + args=(q, init_dut, resp_dut, resp_aware_ifs[i], + init_aware_ipv6s[i], base_port + i))) + + for thread in threads: + thread.start() + + for thread in threads: + thread.join() + + # release requests + for resp_req_key in resp_req_keys: + resp_dut.droid.connectivityUnregisterNetworkCallback(resp_req_key) + for init_req_key in init_req_keys: + init_dut.droid.connectivityUnregisterNetworkCallback(init_req_key) + + # collect data + for i in range(len(sec_configs)): + results[i] = {} + result, data = q.get() + asserts.assert_true( + result, "Failure starting/running iperf3 in client mode") + self.log.debug(pprint.pformat(data)) + data_json = json.loads("".join(data)) + if "error" in data_json: + asserts.fail( + "iperf run failed: %s" % data_json["error"], + extras=data_json) + results[i]["tx_rate"] = data_json["end"]["sum_sent"][ + "bits_per_second"] + results[i]["rx_rate"] = data_json["end"]["sum_received"][ + "bits_per_second"] + self.log.info("iPerf3: Sent = %d bps Received = %d bps", + results[i]["tx_rate"], results[i]["rx_rate"]) + + def test_iperf_max_ndi_aware_only_passphrases(self): + """Test throughput for multiple NDIs configured with different passphrases. """ - results = {} - self.run_iperf_max_ndi_aware_only( - [self.PASSPHRASE, self.PASSPHRASE2], results=results) - asserts.explicit_pass( - "test_iperf_max_ndi_aware_only_passphrases passes", extras=results) + results = {} + self.run_iperf_max_ndi_aware_only( + [self.PASSPHRASE, self.PASSPHRASE2], results=results) + asserts.explicit_pass( + "test_iperf_max_ndi_aware_only_passphrases passes", extras=results) diff --git a/acts/tests/google/wifi/aware/stress/DataPathStressTest.py b/acts/tests/google/wifi/aware/stress/DataPathStressTest.py index f71800734f..ee84afbf5a 100644 --- a/acts/tests/google/wifi/aware/stress/DataPathStressTest.py +++ b/acts/tests/google/wifi/aware/stress/DataPathStressTest.py @@ -27,23 +27,25 @@ from acts.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest class DataPathStressTest(AwareBaseTest): - # Number of iterations on create/destroy Attach sessions. - ATTACH_ITERATIONS = 2 + # Number of iterations on create/destroy Attach sessions. + ATTACH_ITERATIONS = 2 - # Number of iterations on create/destroy NDP in each discovery session. - NDP_ITERATIONS = 50 + # Number of iterations on create/destroy NDP in each discovery session. + NDP_ITERATIONS = 50 - # Maximum percentage of NDP setup failures over all iterations - MAX_FAILURE_PERCENTAGE = 1 + # Maximum percentage of NDP setup failures over all iterations + MAX_FAILURE_PERCENTAGE = 1 - def __init__(self, controllers): - AwareBaseTest.__init__(self, controllers) + def __init__(self, controllers): + AwareBaseTest.__init__(self, controllers) - ################################################################ + ################################################################ - def run_oob_ndp_stress(self, attach_iterations, ndp_iterations, - trigger_failure_on_index=None): - """Run NDP (NAN data-path) stress test creating and destroying Aware + def run_oob_ndp_stress(self, + attach_iterations, + ndp_iterations, + trigger_failure_on_index=None): + """Run NDP (NAN data-path) stress test creating and destroying Aware attach sessions, discovery sessions, and NDPs. Args: @@ -54,152 +56,165 @@ class DataPathStressTest(AwareBaseTest): before issuing the requeest on the Responder). If None then no artificial failure triggered. """ - init_dut = self.android_devices[0] - init_dut.pretty_name = 'Initiator' - resp_dut = self.android_devices[1] - resp_dut.pretty_name = 'Responder' - - ndp_init_setup_success = 0 - ndp_init_setup_failures = 0 - ndp_resp_setup_success = 0 - ndp_resp_setup_failures = 0 - - for attach_iter in range(attach_iterations): - init_id = init_dut.droid.wifiAwareAttach(True) - autils.wait_for_event(init_dut, aconsts.EVENT_CB_ON_ATTACHED) - init_ident_event = autils.wait_for_event( - init_dut, aconsts.EVENT_CB_ON_IDENTITY_CHANGED) - init_mac = init_ident_event['data']['mac'] - time.sleep(self.device_startup_offset) - resp_id = resp_dut.droid.wifiAwareAttach(True) - autils.wait_for_event(resp_dut, aconsts.EVENT_CB_ON_ATTACHED) - resp_ident_event = autils.wait_for_event( - resp_dut, aconsts.EVENT_CB_ON_IDENTITY_CHANGED) - resp_mac = resp_ident_event['data']['mac'] - - # wait for for devices to synchronize with each other - there are no other - # mechanisms to make sure this happens for OOB discovery (except retrying - # to execute the data-path request) - time.sleep(autils.WAIT_FOR_CLUSTER) - - for ndp_iteration in range(ndp_iterations): - if trigger_failure_on_index != ndp_iteration: - # Responder: request network - resp_req_key = autils.request_network( - resp_dut, - resp_dut.droid.wifiAwareCreateNetworkSpecifierOob( - resp_id, aconsts.DATA_PATH_RESPONDER, init_mac, None)) - - # Wait a minimal amount of time to let the Responder configure itself - # and be ready for the request. While calling it first may be - # sufficient there are no guarantees that a glitch may slow the - # Responder slightly enough to invert the setup order. - time.sleep(1) - - # Initiator: request network - init_req_key = autils.request_network( - init_dut, - init_dut.droid.wifiAwareCreateNetworkSpecifierOob( - init_id, aconsts.DATA_PATH_INITIATOR, resp_mac, None)) - else: - # Initiator: request network - init_req_key = autils.request_network( - init_dut, - init_dut.droid.wifiAwareCreateNetworkSpecifierOob( - init_id, aconsts.DATA_PATH_INITIATOR, resp_mac, None)) - - # Wait a minimal amount of time to let the Initiator configure itself - # to guarantee failure! - time.sleep(2) - - # Responder: request network - resp_req_key = autils.request_network( - resp_dut, - resp_dut.droid.wifiAwareCreateNetworkSpecifierOob( - resp_id, aconsts.DATA_PATH_RESPONDER, init_mac, None)) - - # Initiator: wait for network formation - got_on_available = False - got_on_link_props = False - while not got_on_available or not got_on_link_props: - try: - nc_event = init_dut.ed.pop_event(cconsts.EVENT_NETWORK_CALLBACK, - autils.EVENT_NDP_TIMEOUT) - if nc_event['data'][ - cconsts.NETWORK_CB_KEY_EVENT] == cconsts.NETWORK_CB_AVAILABLE: - got_on_available = True - elif (nc_event['data'][cconsts.NETWORK_CB_KEY_EVENT] == - cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED): - got_on_link_props = True - except queue.Empty: - ndp_init_setup_failures = ndp_init_setup_failures + 1 - init_dut.log.info('[Initiator] Timed out while waiting for ' - 'EVENT_NETWORK_CALLBACK') - break - - if got_on_available and got_on_link_props: - ndp_init_setup_success = ndp_init_setup_success + 1 - - # Responder: wait for network formation - got_on_available = False - got_on_link_props = False - while not got_on_available or not got_on_link_props: - try: - nc_event = resp_dut.ed.pop_event(cconsts.EVENT_NETWORK_CALLBACK, - autils.EVENT_NDP_TIMEOUT) - if nc_event['data'][ - cconsts.NETWORK_CB_KEY_EVENT] == cconsts.NETWORK_CB_AVAILABLE: - got_on_available = True - elif (nc_event['data'][cconsts.NETWORK_CB_KEY_EVENT] == - cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED): - got_on_link_props = True - except queue.Empty: - ndp_resp_setup_failures = ndp_resp_setup_failures + 1 - init_dut.log.info('[Responder] Timed out while waiting for ' - 'EVENT_NETWORK_CALLBACK') - break - - if got_on_available and got_on_link_props: - ndp_resp_setup_success = ndp_resp_setup_success + 1 - - # clean-up - init_dut.droid.connectivityUnregisterNetworkCallback(init_req_key) - resp_dut.droid.connectivityUnregisterNetworkCallback(resp_req_key) - - # clean-up at end of iteration - init_dut.droid.wifiAwareDestroy(init_id) - resp_dut.droid.wifiAwareDestroy(resp_id) - - results = {} - results['ndp_init_setup_success'] = ndp_init_setup_success - results['ndp_init_setup_failures'] = ndp_init_setup_failures - results['ndp_resp_setup_success'] = ndp_resp_setup_success - results['ndp_resp_setup_failures'] = ndp_resp_setup_failures - max_failures = ( - self.MAX_FAILURE_PERCENTAGE * attach_iterations * ndp_iterations / 100) - if max_failures == 0: - max_failures = 1 - if trigger_failure_on_index is not None: - max_failures = max_failures + 1 # for the triggered failure - asserts.assert_true( - (ndp_init_setup_failures + ndp_resp_setup_failures) < (2 * max_failures), - 'NDP setup failure rate exceeds threshold', extras=results) - asserts.explicit_pass("test_oob_ndp_stress* done", extras=results) - - @test_tracker_info(uuid="a20a96ba-e71f-4d31-b850-b88a75381981") - def test_oob_ndp_stress(self): - """Run NDP (NAN data-path) stress test creating and destroying Aware + init_dut = self.android_devices[0] + init_dut.pretty_name = 'Initiator' + resp_dut = self.android_devices[1] + resp_dut.pretty_name = 'Responder' + + ndp_init_setup_success = 0 + ndp_init_setup_failures = 0 + ndp_resp_setup_success = 0 + ndp_resp_setup_failures = 0 + + for attach_iter in range(attach_iterations): + init_id = init_dut.droid.wifiAwareAttach(True) + autils.wait_for_event(init_dut, aconsts.EVENT_CB_ON_ATTACHED) + init_ident_event = autils.wait_for_event( + init_dut, aconsts.EVENT_CB_ON_IDENTITY_CHANGED) + init_mac = init_ident_event['data']['mac'] + time.sleep(self.device_startup_offset) + resp_id = resp_dut.droid.wifiAwareAttach(True) + autils.wait_for_event(resp_dut, aconsts.EVENT_CB_ON_ATTACHED) + resp_ident_event = autils.wait_for_event( + resp_dut, aconsts.EVENT_CB_ON_IDENTITY_CHANGED) + resp_mac = resp_ident_event['data']['mac'] + + # wait for for devices to synchronize with each other - there are no other + # mechanisms to make sure this happens for OOB discovery (except retrying + # to execute the data-path request) + time.sleep(autils.WAIT_FOR_CLUSTER) + + for ndp_iteration in range(ndp_iterations): + if trigger_failure_on_index != ndp_iteration: + # Responder: request network + resp_req_key = autils.request_network( + resp_dut, + resp_dut.droid.wifiAwareCreateNetworkSpecifierOob( + resp_id, aconsts.DATA_PATH_RESPONDER, init_mac, + None)) + + # Wait a minimal amount of time to let the Responder configure itself + # and be ready for the request. While calling it first may be + # sufficient there are no guarantees that a glitch may slow the + # Responder slightly enough to invert the setup order. + time.sleep(1) + + # Initiator: request network + init_req_key = autils.request_network( + init_dut, + init_dut.droid.wifiAwareCreateNetworkSpecifierOob( + init_id, aconsts.DATA_PATH_INITIATOR, resp_mac, + None)) + else: + # Initiator: request network + init_req_key = autils.request_network( + init_dut, + init_dut.droid.wifiAwareCreateNetworkSpecifierOob( + init_id, aconsts.DATA_PATH_INITIATOR, resp_mac, + None)) + + # Wait a minimal amount of time to let the Initiator configure itself + # to guarantee failure! + time.sleep(2) + + # Responder: request network + resp_req_key = autils.request_network( + resp_dut, + resp_dut.droid.wifiAwareCreateNetworkSpecifierOob( + resp_id, aconsts.DATA_PATH_RESPONDER, init_mac, + None)) + + # Initiator: wait for network formation + got_on_available = False + got_on_link_props = False + while not got_on_available or not got_on_link_props: + try: + nc_event = init_dut.ed.pop_event( + cconsts.EVENT_NETWORK_CALLBACK, + autils.EVENT_NDP_TIMEOUT) + if nc_event['data'][ + cconsts. + NETWORK_CB_KEY_EVENT] == cconsts.NETWORK_CB_AVAILABLE: + got_on_available = True + elif (nc_event['data'][cconsts.NETWORK_CB_KEY_EVENT] == + cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED): + got_on_link_props = True + except queue.Empty: + ndp_init_setup_failures = ndp_init_setup_failures + 1 + init_dut.log.info( + '[Initiator] Timed out while waiting for ' + 'EVENT_NETWORK_CALLBACK') + break + + if got_on_available and got_on_link_props: + ndp_init_setup_success = ndp_init_setup_success + 1 + + # Responder: wait for network formation + got_on_available = False + got_on_link_props = False + while not got_on_available or not got_on_link_props: + try: + nc_event = resp_dut.ed.pop_event( + cconsts.EVENT_NETWORK_CALLBACK, + autils.EVENT_NDP_TIMEOUT) + if nc_event['data'][ + cconsts. + NETWORK_CB_KEY_EVENT] == cconsts.NETWORK_CB_AVAILABLE: + got_on_available = True + elif (nc_event['data'][cconsts.NETWORK_CB_KEY_EVENT] == + cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED): + got_on_link_props = True + except queue.Empty: + ndp_resp_setup_failures = ndp_resp_setup_failures + 1 + init_dut.log.info( + '[Responder] Timed out while waiting for ' + 'EVENT_NETWORK_CALLBACK') + break + + if got_on_available and got_on_link_props: + ndp_resp_setup_success = ndp_resp_setup_success + 1 + + # clean-up + init_dut.droid.connectivityUnregisterNetworkCallback( + init_req_key) + resp_dut.droid.connectivityUnregisterNetworkCallback( + resp_req_key) + + # clean-up at end of iteration + init_dut.droid.wifiAwareDestroy(init_id) + resp_dut.droid.wifiAwareDestroy(resp_id) + + results = {} + results['ndp_init_setup_success'] = ndp_init_setup_success + results['ndp_init_setup_failures'] = ndp_init_setup_failures + results['ndp_resp_setup_success'] = ndp_resp_setup_success + results['ndp_resp_setup_failures'] = ndp_resp_setup_failures + max_failures = (self.MAX_FAILURE_PERCENTAGE * attach_iterations * + ndp_iterations / 100) + if max_failures == 0: + max_failures = 1 + if trigger_failure_on_index is not None: + max_failures = max_failures + 1 # for the triggered failure + asserts.assert_true( + (ndp_init_setup_failures + ndp_resp_setup_failures) < + (2 * max_failures), + 'NDP setup failure rate exceeds threshold', + extras=results) + asserts.explicit_pass("test_oob_ndp_stress* done", extras=results) + + @test_tracker_info(uuid="a20a96ba-e71f-4d31-b850-b88a75381981") + def test_oob_ndp_stress(self): + """Run NDP (NAN data-path) stress test creating and destroying Aware attach sessions, discovery sessions, and NDPs.""" - self.run_oob_ndp_stress(self.ATTACH_ITERATIONS, self.NDP_ITERATIONS) + self.run_oob_ndp_stress(self.ATTACH_ITERATIONS, self.NDP_ITERATIONS) - @test_tracker_info(uuid="1fb4a383-bf1a-411a-a904-489dd9e29c6a") - def test_oob_ndp_stress_failure_case(self): - """Run NDP (NAN data-path) stress test creating and destroying Aware + @test_tracker_info(uuid="1fb4a383-bf1a-411a-a904-489dd9e29c6a") + def test_oob_ndp_stress_failure_case(self): + """Run NDP (NAN data-path) stress test creating and destroying Aware attach sessions, discovery sessions, and NDPs. Verify recovery from failure by triggering an artifical failure and verifying that all subsequent iterations succeed. """ - self.run_oob_ndp_stress(attach_iterations=1, - ndp_iterations=10, - trigger_failure_on_index=3) + self.run_oob_ndp_stress( + attach_iterations=1, ndp_iterations=10, trigger_failure_on_index=3) diff --git a/acts/tests/google/wifi/aware/stress/DiscoveryStressTest.py b/acts/tests/google/wifi/aware/stress/DiscoveryStressTest.py index eaa5d19c87..f9bb81e55c 100644 --- a/acts/tests/google/wifi/aware/stress/DiscoveryStressTest.py +++ b/acts/tests/google/wifi/aware/stress/DiscoveryStressTest.py @@ -24,84 +24,93 @@ from acts.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest class DiscoveryStressTest(AwareBaseTest): - """Stress tests for Discovery sessions""" + """Stress tests for Discovery sessions""" - # Number of iterations on create/destroy Attach sessions. - ATTACH_ITERATIONS = 2 + # Number of iterations on create/destroy Attach sessions. + ATTACH_ITERATIONS = 2 - # Number of iterations on create/destroy Discovery sessions - DISCOVERY_ITERATIONS = 40 + # Number of iterations on create/destroy Discovery sessions + DISCOVERY_ITERATIONS = 40 - def __init__(self, controllers): - AwareBaseTest.__init__(self, controllers) + def __init__(self, controllers): + AwareBaseTest.__init__(self, controllers) - #################################################################### + #################################################################### - @test_tracker_info(uuid="783791e5-7726-44e0-ac5b-98c1dbf493cb") - def test_discovery_stress(self): - """Create and destroy a random array of discovery sessions, up to the + @test_tracker_info(uuid="783791e5-7726-44e0-ac5b-98c1dbf493cb") + def test_discovery_stress(self): + """Create and destroy a random array of discovery sessions, up to the limit of capabilities.""" - dut = self.android_devices[0] - - discovery_setup_success = 0 - discovery_setup_fail = 0 - - for attach_iter in range(self.ATTACH_ITERATIONS): - # attach - session_id = dut.droid.wifiAwareAttach(True) - autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) - - p_discovery_ids = [] - s_discovery_ids = [] - for discovery_iter in range(self.DISCOVERY_ITERATIONS): - service_name = 'GoogleTestService-%d-%d' % (attach_iter, discovery_iter) - - p_config = None - s_config = None - - if discovery_iter % 4 == 0: # publish/unsolicited - p_config = autils.create_discovery_config( - service_name, aconsts.PUBLISH_TYPE_UNSOLICITED) - elif discovery_iter % 4 == 1: # publish/solicited - p_config = autils.create_discovery_config( - service_name, aconsts.PUBLISH_TYPE_SOLICITED) - elif discovery_iter % 4 == 2: # subscribe/passive - s_config = autils.create_discovery_config( - service_name, aconsts.SUBSCRIBE_TYPE_PASSIVE) - elif discovery_iter % 4 == 3: # subscribe/active - s_config = autils.create_discovery_config( - service_name, aconsts.SUBSCRIBE_TYPE_ACTIVE) - - if p_config is not None: - if len(p_discovery_ids) == dut.aware_capabilities[ - aconsts.CAP_MAX_PUBLISHES]: - dut.droid.wifiAwareDestroyDiscoverySession( - p_discovery_ids.pop(dut.aware_capabilities[ - aconsts.CAP_MAX_PUBLISHES] // 2)) - disc_id = dut.droid.wifiAwarePublish(session_id, p_config) - event_name = aconsts.SESSION_CB_ON_PUBLISH_STARTED - p_discovery_ids.append(disc_id) - else: - if len(s_discovery_ids) == dut.aware_capabilities[ - aconsts.CAP_MAX_SUBSCRIBES]: - dut.droid.wifiAwareDestroyDiscoverySession( - s_discovery_ids.pop(dut.aware_capabilities[ - aconsts.CAP_MAX_SUBSCRIBES] // 2)) - disc_id = dut.droid.wifiAwareSubscribe(session_id, s_config) - event_name = aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED - s_discovery_ids.append(disc_id) - - try: - dut.ed.pop_event(event_name, autils.EVENT_TIMEOUT) - discovery_setup_success = discovery_setup_success + 1 - except queue.Empty: - discovery_setup_fail = discovery_setup_fail + 1 - - dut.droid.wifiAwareDestroy(session_id) - - results = {} - results['discovery_setup_success'] = discovery_setup_success - results['discovery_setup_fail'] = discovery_setup_fail - asserts.assert_equal(discovery_setup_fail, 0, - 'Discovery setup failures', extras=results) - asserts.explicit_pass('test_discovery_stress done', extras=results) + dut = self.android_devices[0] + + discovery_setup_success = 0 + discovery_setup_fail = 0 + + for attach_iter in range(self.ATTACH_ITERATIONS): + # attach + session_id = dut.droid.wifiAwareAttach(True) + autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) + + p_discovery_ids = [] + s_discovery_ids = [] + for discovery_iter in range(self.DISCOVERY_ITERATIONS): + service_name = 'GoogleTestService-%d-%d' % (attach_iter, + discovery_iter) + + p_config = None + s_config = None + + if discovery_iter % 4 == 0: # publish/unsolicited + p_config = autils.create_discovery_config( + service_name, aconsts.PUBLISH_TYPE_UNSOLICITED) + elif discovery_iter % 4 == 1: # publish/solicited + p_config = autils.create_discovery_config( + service_name, aconsts.PUBLISH_TYPE_SOLICITED) + elif discovery_iter % 4 == 2: # subscribe/passive + s_config = autils.create_discovery_config( + service_name, aconsts.SUBSCRIBE_TYPE_PASSIVE) + elif discovery_iter % 4 == 3: # subscribe/active + s_config = autils.create_discovery_config( + service_name, aconsts.SUBSCRIBE_TYPE_ACTIVE) + + if p_config is not None: + if len(p_discovery_ids) == dut.aware_capabilities[ + aconsts.CAP_MAX_PUBLISHES]: + dut.droid.wifiAwareDestroyDiscoverySession( + p_discovery_ids.pop( + dut.aware_capabilities[aconsts. + CAP_MAX_PUBLISHES] // + 2)) + disc_id = dut.droid.wifiAwarePublish(session_id, p_config) + event_name = aconsts.SESSION_CB_ON_PUBLISH_STARTED + p_discovery_ids.append(disc_id) + else: + if len(s_discovery_ids) == dut.aware_capabilities[ + aconsts.CAP_MAX_SUBSCRIBES]: + dut.droid.wifiAwareDestroyDiscoverySession( + s_discovery_ids.pop( + dut.aware_capabilities[aconsts. + CAP_MAX_SUBSCRIBES] // + 2)) + disc_id = dut.droid.wifiAwareSubscribe( + session_id, s_config) + event_name = aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED + s_discovery_ids.append(disc_id) + + try: + dut.ed.pop_event(event_name, autils.EVENT_TIMEOUT) + discovery_setup_success = discovery_setup_success + 1 + except queue.Empty: + discovery_setup_fail = discovery_setup_fail + 1 + + dut.droid.wifiAwareDestroy(session_id) + + results = {} + results['discovery_setup_success'] = discovery_setup_success + results['discovery_setup_fail'] = discovery_setup_fail + asserts.assert_equal( + discovery_setup_fail, + 0, + 'Discovery setup failures', + extras=results) + asserts.explicit_pass('test_discovery_stress done', extras=results) diff --git a/acts/tests/google/wifi/aware/stress/InfraAssociationStressTest.py b/acts/tests/google/wifi/aware/stress/InfraAssociationStressTest.py index 917a7d994d..fc320c0c93 100644 --- a/acts/tests/google/wifi/aware/stress/InfraAssociationStressTest.py +++ b/acts/tests/google/wifi/aware/stress/InfraAssociationStressTest.py @@ -25,29 +25,28 @@ from acts.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest class InfraAssociationStressTest(AwareBaseTest): + def __init__(self, controllers): + AwareBaseTest.__init__(self, controllers) - def __init__(self, controllers): - AwareBaseTest.__init__(self, controllers) + # Length of test in seconds + TEST_DURATION_SECONDS = 300 - # Length of test in seconds - TEST_DURATION_SECONDS = 300 + # Service name + SERVICE_NAME = "GoogleTestServiceXYXYXY" - # Service name - SERVICE_NAME = "GoogleTestServiceXYXYXY" - - def is_associated(self, dut): - """Checks whether the device is associated (to any AP). + def is_associated(self, dut): + """Checks whether the device is associated (to any AP). Args: dut: Device under test. Returns: True if associated (to any AP), False otherwise. """ - info = dut.droid.wifiGetConnectionInfo() - return info is not None and info["supplicant_state"] != "disconnected" + info = dut.droid.wifiGetConnectionInfo() + return info is not None and info["supplicant_state"] != "disconnected" - def wait_for_disassociation(self, q, dut): - """Waits for a disassociation event on the specified DUT for the given + def wait_for_disassociation(self, q, dut): + """Waits for a disassociation event on the specified DUT for the given timeout. Place a result into the queue (False) only if disassociation observed. @@ -55,14 +54,15 @@ class InfraAssociationStressTest(AwareBaseTest): q: The synchronization queue into which to place the results. dut: The device to track. """ - try: - dut.ed.pop_event(wconsts.WIFI_DISCONNECTED, self.TEST_DURATION_SECONDS) - q.put(True) - except queue.Empty: - pass - - def run_infra_assoc_oob_ndp_stress(self, with_ndp_traffic): - """Validates that Wi-Fi Aware NDP does not interfere with infrastructure + try: + dut.ed.pop_event(wconsts.WIFI_DISCONNECTED, + self.TEST_DURATION_SECONDS) + q.put(True) + except queue.Empty: + pass + + def run_infra_assoc_oob_ndp_stress(self, with_ndp_traffic): + """Validates that Wi-Fi Aware NDP does not interfere with infrastructure (AP) association. Test assumes (and verifies) that device is already associated to an AP. @@ -70,92 +70,94 @@ class InfraAssociationStressTest(AwareBaseTest): Args: with_ndp_traffic: True to run traffic over the NDP. """ - init_dut = self.android_devices[0] - resp_dut = self.android_devices[1] - - # check that associated and start tracking - init_dut.droid.wifiStartTrackingStateChange() - resp_dut.droid.wifiStartTrackingStateChange() - asserts.assert_true( - self.is_associated(init_dut), "DUT is not associated to an AP!") - asserts.assert_true( - self.is_associated(resp_dut), "DUT is not associated to an AP!") - - # set up NDP - (init_req_key, resp_req_key, init_aware_if, resp_aware_if, init_ipv6, - resp_ipv6) = autils.create_oob_ndp(init_dut, resp_dut) - self.log.info("Interface names: I=%s, R=%s", init_aware_if, resp_aware_if) - self.log.info("Interface addresses (IPv6): I=%s, R=%s", init_ipv6, - resp_ipv6) - - # wait for any disassociation change events - q = queue.Queue() - init_thread = threading.Thread( - target=self.wait_for_disassociation, args=(q, init_dut)) - resp_thread = threading.Thread( - target=self.wait_for_disassociation, args=(q, resp_dut)) - - init_thread.start() - resp_thread.start() - - any_disassociations = False - try: - q.get(True, self.TEST_DURATION_SECONDS) - any_disassociations = True # only happens on any disassociation - except queue.Empty: - pass - finally: - # TODO: no way to terminate thread (so even if we fast fail we still have - # to wait for the full timeout. - init_dut.droid.wifiStopTrackingStateChange() - resp_dut.droid.wifiStopTrackingStateChange() - - asserts.assert_false(any_disassociations, - "Wi-Fi disassociated during test run") - - ################################################################ - - def test_infra_assoc_discovery_stress(self): - """Validates that Wi-Fi Aware discovery does not interfere with + init_dut = self.android_devices[0] + resp_dut = self.android_devices[1] + + # check that associated and start tracking + init_dut.droid.wifiStartTrackingStateChange() + resp_dut.droid.wifiStartTrackingStateChange() + asserts.assert_true( + self.is_associated(init_dut), "DUT is not associated to an AP!") + asserts.assert_true( + self.is_associated(resp_dut), "DUT is not associated to an AP!") + + # set up NDP + (init_req_key, resp_req_key, init_aware_if, resp_aware_if, init_ipv6, + resp_ipv6) = autils.create_oob_ndp(init_dut, resp_dut) + self.log.info("Interface names: I=%s, R=%s", init_aware_if, + resp_aware_if) + self.log.info("Interface addresses (IPv6): I=%s, R=%s", init_ipv6, + resp_ipv6) + + # wait for any disassociation change events + q = queue.Queue() + init_thread = threading.Thread( + target=self.wait_for_disassociation, args=(q, init_dut)) + resp_thread = threading.Thread( + target=self.wait_for_disassociation, args=(q, resp_dut)) + + init_thread.start() + resp_thread.start() + + any_disassociations = False + try: + q.get(True, self.TEST_DURATION_SECONDS) + any_disassociations = True # only happens on any disassociation + except queue.Empty: + pass + finally: + # TODO: no way to terminate thread (so even if we fast fail we still have + # to wait for the full timeout. + init_dut.droid.wifiStopTrackingStateChange() + resp_dut.droid.wifiStopTrackingStateChange() + + asserts.assert_false(any_disassociations, + "Wi-Fi disassociated during test run") + + ################################################################ + + def test_infra_assoc_discovery_stress(self): + """Validates that Wi-Fi Aware discovery does not interfere with infrastructure (AP) association. Test assumes (and verifies) that device is already associated to an AP. """ - dut = self.android_devices[0] - - # check that associated and start tracking - dut.droid.wifiStartTrackingStateChange() - asserts.assert_true( - self.is_associated(dut), "DUT is not associated to an AP!") - - # attach - session_id = dut.droid.wifiAwareAttach(True) - autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) - - # publish - p_disc_id = dut.droid.wifiAwarePublish( - session_id, - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.PUBLISH_TYPE_UNSOLICITED)) - autils.wait_for_event(dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED) - - # wait for any disassociation change events - any_disassociations = False - try: - dut.ed.pop_event(wconsts.WIFI_DISCONNECTED, self.TEST_DURATION_SECONDS) - any_disassociations = True - except queue.Empty: - pass - finally: - dut.droid.wifiStopTrackingStateChange() - - asserts.assert_false(any_disassociations, - "Wi-Fi disassociated during test run") - - def test_infra_assoc_ndp_no_traffic_stress(self): - """Validates that Wi-Fi Aware NDP (with no traffic) does not interfere with + dut = self.android_devices[0] + + # check that associated and start tracking + dut.droid.wifiStartTrackingStateChange() + asserts.assert_true( + self.is_associated(dut), "DUT is not associated to an AP!") + + # attach + session_id = dut.droid.wifiAwareAttach(True) + autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) + + # publish + p_disc_id = dut.droid.wifiAwarePublish( + session_id, + autils.create_discovery_config(self.SERVICE_NAME, + aconsts.PUBLISH_TYPE_UNSOLICITED)) + autils.wait_for_event(dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED) + + # wait for any disassociation change events + any_disassociations = False + try: + dut.ed.pop_event(wconsts.WIFI_DISCONNECTED, + self.TEST_DURATION_SECONDS) + any_disassociations = True + except queue.Empty: + pass + finally: + dut.droid.wifiStopTrackingStateChange() + + asserts.assert_false(any_disassociations, + "Wi-Fi disassociated during test run") + + def test_infra_assoc_ndp_no_traffic_stress(self): + """Validates that Wi-Fi Aware NDP (with no traffic) does not interfere with infrastructure (AP) association. Test assumes (and verifies) that devices are already associated to an AP. """ - self.run_infra_assoc_oob_ndp_stress(with_ndp_traffic=False) + self.run_infra_assoc_oob_ndp_stress(with_ndp_traffic=False) diff --git a/acts/tests/google/wifi/aware/stress/MessagesStressTest.py b/acts/tests/google/wifi/aware/stress/MessagesStressTest.py index 34827f1ae7..e01a543b76 100644 --- a/acts/tests/google/wifi/aware/stress/MessagesStressTest.py +++ b/acts/tests/google/wifi/aware/stress/MessagesStressTest.py @@ -29,27 +29,27 @@ KEY_RX_COUNT = "rx_count" class MessagesStressTest(AwareBaseTest): - """Set of stress tests for Wi-Fi Aware L2 (layer 2) message exchanges.""" + """Set of stress tests for Wi-Fi Aware L2 (layer 2) message exchanges.""" - # Number of iterations in the stress test (number of messages) - NUM_ITERATIONS = 100 + # Number of iterations in the stress test (number of messages) + NUM_ITERATIONS = 100 - # Maximum permitted percentage of messages which fail to be transmitted - # correctly - MAX_TX_FAILURE_PERCENTAGE = 2 + # Maximum permitted percentage of messages which fail to be transmitted + # correctly + MAX_TX_FAILURE_PERCENTAGE = 2 - # Maximum permitted percentage of messages which are received more than once - # (indicating, most likely, that the ACK wasn't received and the message was - # retransmitted) - MAX_DUPLICATE_RX_PERCENTAGE = 2 + # Maximum permitted percentage of messages which are received more than once + # (indicating, most likely, that the ACK wasn't received and the message was + # retransmitted) + MAX_DUPLICATE_RX_PERCENTAGE = 2 - SERVICE_NAME = "GoogleTestServiceXY" + SERVICE_NAME = "GoogleTestServiceXY" - def __init__(self, controllers): - AwareBaseTest.__init__(self, controllers) + def __init__(self, controllers): + AwareBaseTest.__init__(self, controllers) - def init_info(self, msg, id, messages_by_msg, messages_by_id): - """Initialize the message data structures. + def init_info(self, msg, id, messages_by_msg, messages_by_id): + """Initialize the message data structures. Args: msg: message text @@ -57,15 +57,16 @@ class MessagesStressTest(AwareBaseTest): messages_by_msg: {text -> {id, tx_ok_count, tx_fail_count, rx_count}} messages_by_id: {id -> text} """ - messages_by_msg[msg] = {} - messages_by_msg[msg][KEY_ID] = id - messages_by_msg[msg][KEY_TX_OK_COUNT] = 0 - messages_by_msg[msg][KEY_TX_FAIL_COUNT] = 0 - messages_by_msg[msg][KEY_RX_COUNT] = 0 - messages_by_id[id] = msg + messages_by_msg[msg] = {} + messages_by_msg[msg][KEY_ID] = id + messages_by_msg[msg][KEY_TX_OK_COUNT] = 0 + messages_by_msg[msg][KEY_TX_FAIL_COUNT] = 0 + messages_by_msg[msg][KEY_RX_COUNT] = 0 + messages_by_id[id] = msg - def wait_for_tx_events(self, dut, num_msgs, messages_by_msg, messages_by_id): - """Wait for messages to be transmitted and update data structures. + def wait_for_tx_events(self, dut, num_msgs, messages_by_msg, + messages_by_id): + """Wait for messages to be transmitted and update data structures. Args: dut: device under test @@ -73,224 +74,238 @@ class MessagesStressTest(AwareBaseTest): messages_by_msg: {text -> {id, tx_ok_count, tx_fail_count, rx_count}} messages_by_id: {id -> text} """ - num_ok_tx_confirmations = 0 - num_fail_tx_confirmations = 0 - num_unexpected_ids = 0 - tx_events_regex = "%s|%s" % (aconsts.SESSION_CB_ON_MESSAGE_SEND_FAILED, - aconsts.SESSION_CB_ON_MESSAGE_SENT) - while num_ok_tx_confirmations + num_fail_tx_confirmations < num_msgs: - try: - events = dut.ed.pop_events(tx_events_regex, autils.EVENT_TIMEOUT) - for event in events: - if (event["name"] != aconsts.SESSION_CB_ON_MESSAGE_SENT and - event["name"] != aconsts.SESSION_CB_ON_MESSAGE_SEND_FAILED): - asserts.fail("Unexpected event: %s" % event) - is_tx_ok = event["name"] == aconsts.SESSION_CB_ON_MESSAGE_SENT - - id = event["data"][aconsts.SESSION_CB_KEY_MESSAGE_ID] - if id in messages_by_id: - msg = messages_by_id[id] - if is_tx_ok: - messages_by_msg[msg][ - KEY_TX_OK_COUNT] = messages_by_msg[msg][KEY_TX_OK_COUNT] + 1 - if messages_by_msg[msg][KEY_TX_OK_COUNT] == 1: - num_ok_tx_confirmations = num_ok_tx_confirmations + 1 - else: - messages_by_msg[msg][KEY_TX_FAIL_COUNT] = ( - messages_by_msg[msg][KEY_TX_FAIL_COUNT] + 1) - if messages_by_msg[msg][KEY_TX_FAIL_COUNT] == 1: - num_fail_tx_confirmations = num_fail_tx_confirmations + 1 - else: - self.log.warning( - "Tx confirmation of unknown message ID received: %s", event) - num_unexpected_ids = num_unexpected_ids + 1 - except queue.Empty: - self.log.warning("[%s] Timed out waiting for any MESSAGE_SEND* event - " - "assuming the rest are not coming", dut.pretty_name) - break - - return (num_ok_tx_confirmations, num_fail_tx_confirmations, - num_unexpected_ids) - - def wait_for_rx_events(self, dut, num_msgs, messages_by_msg): - """Wait for messages to be received and update data structures + num_ok_tx_confirmations = 0 + num_fail_tx_confirmations = 0 + num_unexpected_ids = 0 + tx_events_regex = "%s|%s" % (aconsts.SESSION_CB_ON_MESSAGE_SEND_FAILED, + aconsts.SESSION_CB_ON_MESSAGE_SENT) + while num_ok_tx_confirmations + num_fail_tx_confirmations < num_msgs: + try: + events = dut.ed.pop_events(tx_events_regex, + autils.EVENT_TIMEOUT) + for event in events: + if (event["name"] != aconsts.SESSION_CB_ON_MESSAGE_SENT + and event["name"] != + aconsts.SESSION_CB_ON_MESSAGE_SEND_FAILED): + asserts.fail("Unexpected event: %s" % event) + is_tx_ok = event[ + "name"] == aconsts.SESSION_CB_ON_MESSAGE_SENT + + id = event["data"][aconsts.SESSION_CB_KEY_MESSAGE_ID] + if id in messages_by_id: + msg = messages_by_id[id] + if is_tx_ok: + messages_by_msg[msg][ + KEY_TX_OK_COUNT] = messages_by_msg[msg][KEY_TX_OK_COUNT] + 1 + if messages_by_msg[msg][KEY_TX_OK_COUNT] == 1: + num_ok_tx_confirmations = num_ok_tx_confirmations + 1 + else: + messages_by_msg[msg][KEY_TX_FAIL_COUNT] = ( + messages_by_msg[msg][KEY_TX_FAIL_COUNT] + 1) + if messages_by_msg[msg][KEY_TX_FAIL_COUNT] == 1: + num_fail_tx_confirmations = num_fail_tx_confirmations + 1 + else: + self.log.warning( + "Tx confirmation of unknown message ID received: %s", + event) + num_unexpected_ids = num_unexpected_ids + 1 + except queue.Empty: + self.log.warning( + "[%s] Timed out waiting for any MESSAGE_SEND* event - " + "assuming the rest are not coming", dut.pretty_name) + break + + return (num_ok_tx_confirmations, num_fail_tx_confirmations, + num_unexpected_ids) + + def wait_for_rx_events(self, dut, num_msgs, messages_by_msg): + """Wait for messages to be received and update data structures Args: dut: device under test num_msgs: number of expected messages to receive messages_by_msg: {text -> {id, tx_ok_count, tx_fail_count, rx_count}} """ - num_rx_msgs = 0 - while num_rx_msgs < num_msgs: - try: - event = dut.ed.pop_event(aconsts.SESSION_CB_ON_MESSAGE_RECEIVED, - autils.EVENT_TIMEOUT) - msg = event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING] - if msg not in messages_by_msg: - messages_by_msg[msg] = {} - messages_by_msg[msg][KEY_ID] = -1 - messages_by_msg[msg][KEY_TX_OK_COUNT] = 0 - messages_by_msg[msg][KEY_TX_FAIL_COUNT] = 0 - messages_by_msg[msg][KEY_RX_COUNT] = 1 - - messages_by_msg[msg][ - KEY_RX_COUNT] = messages_by_msg[msg][KEY_RX_COUNT] + 1 - if messages_by_msg[msg][KEY_RX_COUNT] == 1: - num_rx_msgs = num_rx_msgs + 1 - except queue.Empty: - self.log.warning( - "[%s] Timed out waiting for ON_MESSAGE_RECEIVED event - " - "assuming the rest are not coming", dut.pretty_name) - break - - def analyze_results(self, results, messages_by_msg): - """Analyze the results of the stress message test and add to the results + num_rx_msgs = 0 + while num_rx_msgs < num_msgs: + try: + event = dut.ed.pop_event( + aconsts.SESSION_CB_ON_MESSAGE_RECEIVED, + autils.EVENT_TIMEOUT) + msg = event["data"][aconsts.SESSION_CB_KEY_MESSAGE_AS_STRING] + if msg not in messages_by_msg: + messages_by_msg[msg] = {} + messages_by_msg[msg][KEY_ID] = -1 + messages_by_msg[msg][KEY_TX_OK_COUNT] = 0 + messages_by_msg[msg][KEY_TX_FAIL_COUNT] = 0 + messages_by_msg[msg][KEY_RX_COUNT] = 1 + + messages_by_msg[msg][ + KEY_RX_COUNT] = messages_by_msg[msg][KEY_RX_COUNT] + 1 + if messages_by_msg[msg][KEY_RX_COUNT] == 1: + num_rx_msgs = num_rx_msgs + 1 + except queue.Empty: + self.log.warning( + "[%s] Timed out waiting for ON_MESSAGE_RECEIVED event - " + "assuming the rest are not coming", dut.pretty_name) + break + + def analyze_results(self, results, messages_by_msg): + """Analyze the results of the stress message test and add to the results dictionary Args: results: result dictionary into which to add data messages_by_msg: {text -> {id, tx_ok_count, tx_fail_count, rx_count}} """ - results["raw_data"] = messages_by_msg - results["tx_count_success"] = 0 - results["tx_count_duplicate_success"] = 0 - results["tx_count_fail"] = 0 - results["tx_count_duplicate_fail"] = 0 - results["tx_count_neither"] = 0 - results["tx_count_tx_ok_but_no_rx"] = 0 - results["rx_count"] = 0 - results["rx_count_duplicate"] = 0 - results["rx_count_no_ok_tx_indication"] = 0 - results["rx_count_fail_tx_indication"] = 0 - results["rx_count_no_tx_message"] = 0 - - for msg, data in messages_by_msg.items(): - if data[KEY_TX_OK_COUNT] > 0: - results["tx_count_success"] = results["tx_count_success"] + 1 - if data[KEY_TX_OK_COUNT] > 1: - results["tx_count_duplicate_success"] = ( - results["tx_count_duplicate_success"] + 1) - if data[KEY_TX_FAIL_COUNT] > 0: - results["tx_count_fail"] = results["tx_count_fail"] + 1 - if data[KEY_TX_FAIL_COUNT] > 1: - results[ - "tx_count_duplicate_fail"] = results["tx_count_duplicate_fail"] + 1 - if (data[KEY_TX_OK_COUNT] == 0 and data[KEY_TX_FAIL_COUNT] == 0 and - data[KEY_ID] != -1): - results["tx_count_neither"] = results["tx_count_neither"] + 1 - if data[KEY_TX_OK_COUNT] > 0 and data[KEY_RX_COUNT] == 0: - results["tx_count_tx_ok_but_no_rx"] = ( - results["tx_count_tx_ok_but_no_rx"] + 1) - if data[KEY_RX_COUNT] > 0: - results["rx_count"] = results["rx_count"] + 1 - if data[KEY_RX_COUNT] > 1: - results["rx_count_duplicate"] = results["rx_count_duplicate"] + 1 - if data[KEY_RX_COUNT] > 0 and data[KEY_TX_OK_COUNT] == 0: - results["rx_count_no_ok_tx_indication"] = ( - results["rx_count_no_ok_tx_indication"] + 1) - if data[KEY_RX_COUNT] > 0 and data[KEY_TX_FAIL_COUNT] > 0: - results["rx_count_fail_tx_indication"] = ( - results["rx_count_fail_tx_indication"] + 1) - if data[KEY_RX_COUNT] > 0 and data[KEY_ID] == -1: - results[ - "rx_count_no_tx_message"] = results["rx_count_no_tx_message"] + 1 - - ####################################################################### - - @test_tracker_info(uuid="e88c060f-4ca7-41c1-935a-d3d62878ec0b") - def test_stress_message(self): - """Stress test for bi-directional message transmission and reception.""" - p_dut = self.android_devices[0] - s_dut = self.android_devices[1] - - # Start up a discovery session - discovery_data = autils.create_discovery_pair( - p_dut, - s_dut, - p_config=autils.create_discovery_config( - self.SERVICE_NAME, aconsts.PUBLISH_TYPE_UNSOLICITED), - s_config=autils.create_discovery_config(self.SERVICE_NAME, - aconsts.SUBSCRIBE_TYPE_PASSIVE), - device_startup_offset=self.device_startup_offset, - msg_id=self.get_next_msg_id()) - p_id = discovery_data[0] - s_id = discovery_data[1] - p_disc_id = discovery_data[2] - s_disc_id = discovery_data[3] - peer_id_on_sub = discovery_data[4] - peer_id_on_pub = discovery_data[5] - - # Store information on Tx & Rx messages - messages_by_msg = {} # keyed by message text - # {text -> {id, tx_ok_count, tx_fail_count, rx_count}} - messages_by_id = {} # keyed by message ID {id -> text} - - # send all messages at once (one in each direction) - for i in range(self.NUM_ITERATIONS): - msg_p2s = "Message Publisher -> Subscriber #%d" % i - next_msg_id = self.get_next_msg_id() - self.init_info(msg_p2s, next_msg_id, messages_by_msg, messages_by_id) - p_dut.droid.wifiAwareSendMessage(p_disc_id, peer_id_on_pub, next_msg_id, - msg_p2s, 0) - - msg_s2p = "Message Subscriber -> Publisher #%d" % i - next_msg_id = self.get_next_msg_id() - self.init_info(msg_s2p, next_msg_id, messages_by_msg, messages_by_id) - s_dut.droid.wifiAwareSendMessage(s_disc_id, peer_id_on_sub, next_msg_id, - msg_s2p, 0) - - # wait for message tx confirmation - (p_tx_ok_count, p_tx_fail_count, p_tx_unknown_id) = self.wait_for_tx_events( - p_dut, self.NUM_ITERATIONS, messages_by_msg, messages_by_id) - (s_tx_ok_count, s_tx_fail_count, s_tx_unknown_id) = self.wait_for_tx_events( - s_dut, self.NUM_ITERATIONS, messages_by_msg, messages_by_id) - self.log.info("Transmission done: pub=%d, sub=%d transmitted successfully", - p_tx_ok_count, s_tx_ok_count) - - # wait for message rx confirmation (giving it the total number of messages - # transmitted rather than just those transmitted correctly since sometimes - # the Tx doesn't get that information correctly. I.e. a message the Tx - # thought was not transmitted correctly is actually received - missing ACK? - # bug?) - self.wait_for_rx_events(p_dut, self.NUM_ITERATIONS, messages_by_msg) - self.wait_for_rx_events(s_dut, self.NUM_ITERATIONS, messages_by_msg) - - # analyze results - results = {} - results["tx_count"] = 2 * self.NUM_ITERATIONS - results["tx_unknown_ids"] = p_tx_unknown_id + s_tx_unknown_id - self.analyze_results(results, messages_by_msg) - - # clear errors - asserts.assert_equal(results["tx_unknown_ids"], 0, "Message ID corruption", - results) - asserts.assert_equal(results["tx_count_neither"], 0, - "Tx message with no success or fail indication", - results) - asserts.assert_equal(results["tx_count_duplicate_fail"], 0, - "Duplicate Tx fail messages", results) - asserts.assert_equal(results["tx_count_duplicate_success"], 0, - "Duplicate Tx success messages", results) - asserts.assert_equal(results["rx_count_no_tx_message"], 0, - "Rx message which wasn't sent - message corruption?", - results) - asserts.assert_equal(results["tx_count_tx_ok_but_no_rx"], 0, - "Tx got ACK but Rx didn't get message", results) - - # possibly ok - but flag since most frequently a bug - asserts.assert_equal(results["rx_count_no_ok_tx_indication"], 0, - "Message received but Tx didn't get ACK", results) - asserts.assert_equal(results["rx_count_fail_tx_indication"], 0, - "Message received but Tx didn't get ACK", results) - - # permissible failures based on thresholds - asserts.assert_true(results["tx_count_fail"] <= ( - self.MAX_TX_FAILURE_PERCENTAGE * self.NUM_ITERATIONS / 100), - "Number of Tx failures exceeds threshold", - extras=results) - asserts.assert_true(results["rx_count_duplicate"] <= ( - self.MAX_DUPLICATE_RX_PERCENTAGE * self.NUM_ITERATIONS / 100), - "Number of duplicate Rx exceeds threshold", - extras=results) - - asserts.explicit_pass("test_stress_message done", extras=results)
\ No newline at end of file + results["raw_data"] = messages_by_msg + results["tx_count_success"] = 0 + results["tx_count_duplicate_success"] = 0 + results["tx_count_fail"] = 0 + results["tx_count_duplicate_fail"] = 0 + results["tx_count_neither"] = 0 + results["tx_count_tx_ok_but_no_rx"] = 0 + results["rx_count"] = 0 + results["rx_count_duplicate"] = 0 + results["rx_count_no_ok_tx_indication"] = 0 + results["rx_count_fail_tx_indication"] = 0 + results["rx_count_no_tx_message"] = 0 + + for msg, data in messages_by_msg.items(): + if data[KEY_TX_OK_COUNT] > 0: + results["tx_count_success"] = results["tx_count_success"] + 1 + if data[KEY_TX_OK_COUNT] > 1: + results["tx_count_duplicate_success"] = ( + results["tx_count_duplicate_success"] + 1) + if data[KEY_TX_FAIL_COUNT] > 0: + results["tx_count_fail"] = results["tx_count_fail"] + 1 + if data[KEY_TX_FAIL_COUNT] > 1: + results[ + "tx_count_duplicate_fail"] = results["tx_count_duplicate_fail"] + 1 + if (data[KEY_TX_OK_COUNT] == 0 and data[KEY_TX_FAIL_COUNT] == 0 + and data[KEY_ID] != -1): + results["tx_count_neither"] = results["tx_count_neither"] + 1 + if data[KEY_TX_OK_COUNT] > 0 and data[KEY_RX_COUNT] == 0: + results["tx_count_tx_ok_but_no_rx"] = ( + results["tx_count_tx_ok_but_no_rx"] + 1) + if data[KEY_RX_COUNT] > 0: + results["rx_count"] = results["rx_count"] + 1 + if data[KEY_RX_COUNT] > 1: + results[ + "rx_count_duplicate"] = results["rx_count_duplicate"] + 1 + if data[KEY_RX_COUNT] > 0 and data[KEY_TX_OK_COUNT] == 0: + results["rx_count_no_ok_tx_indication"] = ( + results["rx_count_no_ok_tx_indication"] + 1) + if data[KEY_RX_COUNT] > 0 and data[KEY_TX_FAIL_COUNT] > 0: + results["rx_count_fail_tx_indication"] = ( + results["rx_count_fail_tx_indication"] + 1) + if data[KEY_RX_COUNT] > 0 and data[KEY_ID] == -1: + results[ + "rx_count_no_tx_message"] = results["rx_count_no_tx_message"] + 1 + + ####################################################################### + + @test_tracker_info(uuid="e88c060f-4ca7-41c1-935a-d3d62878ec0b") + def test_stress_message(self): + """Stress test for bi-directional message transmission and reception.""" + p_dut = self.android_devices[0] + s_dut = self.android_devices[1] + + # Start up a discovery session + discovery_data = autils.create_discovery_pair( + p_dut, + s_dut, + p_config=autils.create_discovery_config( + self.SERVICE_NAME, aconsts.PUBLISH_TYPE_UNSOLICITED), + s_config=autils.create_discovery_config( + self.SERVICE_NAME, aconsts.SUBSCRIBE_TYPE_PASSIVE), + device_startup_offset=self.device_startup_offset, + msg_id=self.get_next_msg_id()) + p_id = discovery_data[0] + s_id = discovery_data[1] + p_disc_id = discovery_data[2] + s_disc_id = discovery_data[3] + peer_id_on_sub = discovery_data[4] + peer_id_on_pub = discovery_data[5] + + # Store information on Tx & Rx messages + messages_by_msg = {} # keyed by message text + # {text -> {id, tx_ok_count, tx_fail_count, rx_count}} + messages_by_id = {} # keyed by message ID {id -> text} + + # send all messages at once (one in each direction) + for i in range(self.NUM_ITERATIONS): + msg_p2s = "Message Publisher -> Subscriber #%d" % i + next_msg_id = self.get_next_msg_id() + self.init_info(msg_p2s, next_msg_id, messages_by_msg, + messages_by_id) + p_dut.droid.wifiAwareSendMessage(p_disc_id, peer_id_on_pub, + next_msg_id, msg_p2s, 0) + + msg_s2p = "Message Subscriber -> Publisher #%d" % i + next_msg_id = self.get_next_msg_id() + self.init_info(msg_s2p, next_msg_id, messages_by_msg, + messages_by_id) + s_dut.droid.wifiAwareSendMessage(s_disc_id, peer_id_on_sub, + next_msg_id, msg_s2p, 0) + + # wait for message tx confirmation + (p_tx_ok_count, + p_tx_fail_count, p_tx_unknown_id) = self.wait_for_tx_events( + p_dut, self.NUM_ITERATIONS, messages_by_msg, messages_by_id) + (s_tx_ok_count, + s_tx_fail_count, s_tx_unknown_id) = self.wait_for_tx_events( + s_dut, self.NUM_ITERATIONS, messages_by_msg, messages_by_id) + self.log.info( + "Transmission done: pub=%d, sub=%d transmitted successfully", + p_tx_ok_count, s_tx_ok_count) + + # wait for message rx confirmation (giving it the total number of messages + # transmitted rather than just those transmitted correctly since sometimes + # the Tx doesn't get that information correctly. I.e. a message the Tx + # thought was not transmitted correctly is actually received - missing ACK? + # bug?) + self.wait_for_rx_events(p_dut, self.NUM_ITERATIONS, messages_by_msg) + self.wait_for_rx_events(s_dut, self.NUM_ITERATIONS, messages_by_msg) + + # analyze results + results = {} + results["tx_count"] = 2 * self.NUM_ITERATIONS + results["tx_unknown_ids"] = p_tx_unknown_id + s_tx_unknown_id + self.analyze_results(results, messages_by_msg) + + # clear errors + asserts.assert_equal(results["tx_unknown_ids"], 0, + "Message ID corruption", results) + asserts.assert_equal(results["tx_count_neither"], 0, + "Tx message with no success or fail indication", + results) + asserts.assert_equal(results["tx_count_duplicate_fail"], 0, + "Duplicate Tx fail messages", results) + asserts.assert_equal(results["tx_count_duplicate_success"], 0, + "Duplicate Tx success messages", results) + asserts.assert_equal( + results["rx_count_no_tx_message"], 0, + "Rx message which wasn't sent - message corruption?", results) + asserts.assert_equal(results["tx_count_tx_ok_but_no_rx"], 0, + "Tx got ACK but Rx didn't get message", results) + + # possibly ok - but flag since most frequently a bug + asserts.assert_equal(results["rx_count_no_ok_tx_indication"], 0, + "Message received but Tx didn't get ACK", results) + asserts.assert_equal(results["rx_count_fail_tx_indication"], 0, + "Message received but Tx didn't get ACK", results) + + # permissible failures based on thresholds + asserts.assert_true( + results["tx_count_fail"] <= + (self.MAX_TX_FAILURE_PERCENTAGE * self.NUM_ITERATIONS / 100), + "Number of Tx failures exceeds threshold", + extras=results) + asserts.assert_true( + results["rx_count_duplicate"] <= + (self.MAX_DUPLICATE_RX_PERCENTAGE * self.NUM_ITERATIONS / 100), + "Number of duplicate Rx exceeds threshold", + extras=results) + + asserts.explicit_pass("test_stress_message done", extras=results) diff --git a/acts/tests/google/wifi/rtt/functional/AwareDiscoveryWithRangingTest.py b/acts/tests/google/wifi/rtt/functional/AwareDiscoveryWithRangingTest.py index f6d7c8ddb7..7490f1c400 100644 --- a/acts/tests/google/wifi/rtt/functional/AwareDiscoveryWithRangingTest.py +++ b/acts/tests/google/wifi/rtt/functional/AwareDiscoveryWithRangingTest.py @@ -29,41 +29,44 @@ from acts.test_utils.wifi.rtt.RttBaseTest import RttBaseTest class AwareDiscoveryWithRangingTest(AwareBaseTest, RttBaseTest): - """Set of tests for Wi-Fi Aware discovery configured with ranging (RTT).""" + """Set of tests for Wi-Fi Aware discovery configured with ranging (RTT).""" - SERVICE_NAME = "GoogleTestServiceRRRRR" + SERVICE_NAME = "GoogleTestServiceRRRRR" - # Flag indicating whether the device has a limitation that does not allow it - # to execute Aware-based Ranging (whether direct or as part of discovery) - # whenever NDP is enabled. - RANGING_NDP_CONCURRENCY_LIMITATION = True + # Flag indicating whether the device has a limitation that does not allow it + # to execute Aware-based Ranging (whether direct or as part of discovery) + # whenever NDP is enabled. + RANGING_NDP_CONCURRENCY_LIMITATION = True - # Flag indicating whether the device has a limitation that does not allow it - # to execute Aware-based Ranging (whether direct or as part of discovery) - # for both Initiators and Responders. Only the first mode works. - RANGING_INITIATOR_RESPONDER_CONCURRENCY_LIMITATION = True + # Flag indicating whether the device has a limitation that does not allow it + # to execute Aware-based Ranging (whether direct or as part of discovery) + # for both Initiators and Responders. Only the first mode works. + RANGING_INITIATOR_RESPONDER_CONCURRENCY_LIMITATION = True - def __init__(self, controllers): - AwareBaseTest.__init__(self, controllers) - RttBaseTest.__init__(self, controllers) + def __init__(self, controllers): + AwareBaseTest.__init__(self, controllers) + RttBaseTest.__init__(self, controllers) - def setup_test(self): - """Manual setup here due to multiple inheritance: explicitly execute the + def setup_test(self): + """Manual setup here due to multiple inheritance: explicitly execute the setup method from both parents.""" - AwareBaseTest.setup_test(self) - RttBaseTest.setup_test(self) + AwareBaseTest.setup_test(self) + RttBaseTest.setup_test(self) - def teardown_test(self): - """Manual teardown here due to multiple inheritance: explicitly execute the + def teardown_test(self): + """Manual teardown here due to multiple inheritance: explicitly execute the teardown method from both parents.""" - AwareBaseTest.teardown_test(self) - RttBaseTest.teardown_test(self) + AwareBaseTest.teardown_test(self) + RttBaseTest.teardown_test(self) - ######################################################################### + ######################################################################### - def run_discovery(self, p_config, s_config, expect_discovery, - expect_range=False): - """Run discovery on the 2 input devices with the specified configurations. + def run_discovery(self, + p_config, + s_config, + expect_discovery, + expect_range=False): + """Run discovery on the 2 input devices with the specified configurations. Args: p_config, s_config: Publisher and Subscriber discovery configuration. @@ -75,50 +78,59 @@ class AwareDiscoveryWithRangingTest(AwareBaseTest, RttBaseTest): p_dut, s_dut: Publisher/Subscribe DUT p_disc_id, s_disc_id: Publisher/Subscribe discovery session ID """ - p_dut = self.android_devices[0] - p_dut.pretty_name = "Publisher" - s_dut = self.android_devices[1] - s_dut.pretty_name = "Subscriber" - - # Publisher+Subscriber: attach and wait for confirmation - p_id = p_dut.droid.wifiAwareAttach(False) - autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED) - time.sleep(self.device_startup_offset) - s_id = s_dut.droid.wifiAwareAttach(False) - autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED) - - # Publisher: start publish and wait for confirmation - p_disc_id = p_dut.droid.wifiAwarePublish(p_id, p_config) - autils.wait_for_event(p_dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED) - - # Subscriber: start subscribe and wait for confirmation - s_disc_id = s_dut.droid.wifiAwareSubscribe(s_id, s_config) - autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED) - - # Subscriber: wait or fail on service discovery - if expect_discovery: - event = autils.wait_for_event(s_dut, - aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) - if expect_range: - asserts.assert_true(aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], - "Discovery with ranging expected!") - else: - asserts.assert_false( - aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], - "Discovery with ranging NOT expected!") - else: - autils.fail_on_event(s_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) - - # (single) sleep for timeout period and then verify that no further events - time.sleep(autils.EVENT_TIMEOUT) - autils.verify_no_more_events(p_dut, timeout=0) - autils.verify_no_more_events(s_dut, timeout=0) - - return p_dut, s_dut, p_disc_id, s_disc_id - - def run_discovery_update(self, p_dut, s_dut, p_disc_id, s_disc_id, p_config, - s_config, expect_discovery, expect_range=False): - """Run discovery on the 2 input devices with the specified update + p_dut = self.android_devices[0] + p_dut.pretty_name = "Publisher" + s_dut = self.android_devices[1] + s_dut.pretty_name = "Subscriber" + + # Publisher+Subscriber: attach and wait for confirmation + p_id = p_dut.droid.wifiAwareAttach(False) + autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED) + time.sleep(self.device_startup_offset) + s_id = s_dut.droid.wifiAwareAttach(False) + autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED) + + # Publisher: start publish and wait for confirmation + p_disc_id = p_dut.droid.wifiAwarePublish(p_id, p_config) + autils.wait_for_event(p_dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED) + + # Subscriber: start subscribe and wait for confirmation + s_disc_id = s_dut.droid.wifiAwareSubscribe(s_id, s_config) + autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED) + + # Subscriber: wait or fail on service discovery + if expect_discovery: + event = autils.wait_for_event( + s_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) + if expect_range: + asserts.assert_true( + aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], + "Discovery with ranging expected!") + else: + asserts.assert_false( + aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], + "Discovery with ranging NOT expected!") + else: + autils.fail_on_event(s_dut, + aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) + + # (single) sleep for timeout period and then verify that no further events + time.sleep(autils.EVENT_TIMEOUT) + autils.verify_no_more_events(p_dut, timeout=0) + autils.verify_no_more_events(s_dut, timeout=0) + + return p_dut, s_dut, p_disc_id, s_disc_id + + def run_discovery_update(self, + p_dut, + s_dut, + p_disc_id, + s_disc_id, + p_config, + s_config, + expect_discovery, + expect_range=False): + """Run discovery on the 2 input devices with the specified update configurations. I.e. update the existing discovery sessions with the configurations. @@ -132,39 +144,43 @@ class AwareDiscoveryWithRangingTest(AwareBaseTest, RttBaseTest): Only relevant if expect_discovery is True. """ - # try to perform reconfiguration at same time (and wait once for all - # confirmations) - if p_config is not None: - p_dut.droid.wifiAwareUpdatePublish(p_disc_id, p_config) - if s_config is not None: - s_dut.droid.wifiAwareUpdateSubscribe(s_disc_id, s_config) - - if p_config is not None: - autils.wait_for_event(p_dut, aconsts.SESSION_CB_ON_SESSION_CONFIG_UPDATED) - if s_config is not None: - autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_SESSION_CONFIG_UPDATED) - - # Subscriber: wait or fail on service discovery - if expect_discovery: - event = autils.wait_for_event(s_dut, - aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) - if expect_range: - asserts.assert_true(aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], - "Discovery with ranging expected!") - else: - asserts.assert_false( - aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], - "Discovery with ranging NOT expected!") - else: - autils.fail_on_event(s_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) - - # (single) sleep for timeout period and then verify that no further events - time.sleep(autils.EVENT_TIMEOUT) - autils.verify_no_more_events(p_dut, timeout=0) - autils.verify_no_more_events(s_dut, timeout=0) - - def run_discovery_prange_sminmax_outofrange(self, is_unsolicited_passive): - """Run discovery with ranging: + # try to perform reconfiguration at same time (and wait once for all + # confirmations) + if p_config is not None: + p_dut.droid.wifiAwareUpdatePublish(p_disc_id, p_config) + if s_config is not None: + s_dut.droid.wifiAwareUpdateSubscribe(s_disc_id, s_config) + + if p_config is not None: + autils.wait_for_event(p_dut, + aconsts.SESSION_CB_ON_SESSION_CONFIG_UPDATED) + if s_config is not None: + autils.wait_for_event(s_dut, + aconsts.SESSION_CB_ON_SESSION_CONFIG_UPDATED) + + # Subscriber: wait or fail on service discovery + if expect_discovery: + event = autils.wait_for_event( + s_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) + if expect_range: + asserts.assert_true( + aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], + "Discovery with ranging expected!") + else: + asserts.assert_false( + aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], + "Discovery with ranging NOT expected!") + else: + autils.fail_on_event(s_dut, + aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) + + # (single) sleep for timeout period and then verify that no further events + time.sleep(autils.EVENT_TIMEOUT) + autils.verify_no_more_events(p_dut, timeout=0) + autils.verify_no_more_events(s_dut, timeout=0) + + def run_discovery_prange_sminmax_outofrange(self, is_unsolicited_passive): + """Run discovery with ranging: - Publisher enables ranging - Subscriber enables ranging with min/max such that out of range (min=large, max=large+1) @@ -178,88 +194,92 @@ class AwareDiscoveryWithRangingTest(AwareBaseTest, RttBaseTest): Solicited/Active. Returns: the return arguments of the run_discovery. """ - pub_type = (aconsts.PUBLISH_TYPE_UNSOLICITED if is_unsolicited_passive - else aconsts.PUBLISH_TYPE_SOLICITED) - sub_type = (aconsts.SUBSCRIBE_TYPE_PASSIVE if is_unsolicited_passive - else aconsts.SUBSCRIBE_TYPE_ACTIVE) - return self.run_discovery( - p_config=autils.add_ranging_to_pub( - autils.create_discovery_config(self.SERVICE_NAME, pub_type, - ssi=self.getname(2)), - enable_ranging=True), - s_config=autils.add_ranging_to_sub( - autils.create_discovery_config(self.SERVICE_NAME, sub_type, - ssi=self.getname(2)), - min_distance_mm=1000000, - max_distance_mm=1000001), - expect_discovery=False) - - def getname(self, level=1): - """Python magic to return the name of the *calling* function. + pub_type = (aconsts.PUBLISH_TYPE_UNSOLICITED if is_unsolicited_passive + else aconsts.PUBLISH_TYPE_SOLICITED) + sub_type = (aconsts.SUBSCRIBE_TYPE_PASSIVE if is_unsolicited_passive + else aconsts.SUBSCRIBE_TYPE_ACTIVE) + return self.run_discovery( + p_config=autils.add_ranging_to_pub( + autils.create_discovery_config( + self.SERVICE_NAME, pub_type, ssi=self.getname(2)), + enable_ranging=True), + s_config=autils.add_ranging_to_sub( + autils.create_discovery_config( + self.SERVICE_NAME, sub_type, ssi=self.getname(2)), + min_distance_mm=1000000, + max_distance_mm=1000001), + expect_discovery=False) + + def getname(self, level=1): + """Python magic to return the name of the *calling* function. Args: level: How many levels up to go for the method name. Default = calling method. """ - return sys._getframe(level).f_code.co_name - - ######################################################################### - # Run discovery with ranging configuration. - # - # Names: test_ranged_discovery_<ptype>_<stype>_<p_range>_<s_range>_<ref_dist> - # - # where: - # <ptype>_<stype>: unsolicited_passive or solicited_active - # <p_range>: prange or pnorange - # <s_range>: smin or smax or sminmax or snorange - # <ref_distance>: inrange or outoforange - ######################################################################### - - @test_tracker_info(uuid="3a216e9a-7a57-4741-89c0-84456975e1ac") - def test_ranged_discovery_unsolicited_passive_prange_snorange(self): - """Verify discovery with ranging: + return sys._getframe(level).f_code.co_name + + ######################################################################### + # Run discovery with ranging configuration. + # + # Names: test_ranged_discovery_<ptype>_<stype>_<p_range>_<s_range>_<ref_dist> + # + # where: + # <ptype>_<stype>: unsolicited_passive or solicited_active + # <p_range>: prange or pnorange + # <s_range>: smin or smax or sminmax or snorange + # <ref_distance>: inrange or outoforange + ######################################################################### + + @test_tracker_info(uuid="3a216e9a-7a57-4741-89c0-84456975e1ac") + def test_ranged_discovery_unsolicited_passive_prange_snorange(self): + """Verify discovery with ranging: - Unsolicited Publish/Passive Subscribe - Publisher enables ranging - Subscriber disables ranging Expect: normal discovery (as if no ranging performed) - no distance """ - self.run_discovery( - p_config=autils.add_ranging_to_pub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.PUBLISH_TYPE_UNSOLICITED, - ssi=self.getname()), - enable_ranging=True), - s_config=autils.create_discovery_config(self.SERVICE_NAME, - aconsts.SUBSCRIBE_TYPE_PASSIVE, - ssi=self.getname()), - expect_discovery=True, - expect_range=False) - - @test_tracker_info(uuid="859a321e-18e2-437b-aa7a-2a45a42ee737") - def test_ranged_discovery_solicited_active_prange_snorange(self): - """Verify discovery with ranging: + self.run_discovery( + p_config=autils.add_ranging_to_pub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.PUBLISH_TYPE_UNSOLICITED, + ssi=self.getname()), + enable_ranging=True), + s_config=autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.SUBSCRIBE_TYPE_PASSIVE, + ssi=self.getname()), + expect_discovery=True, + expect_range=False) + + @test_tracker_info(uuid="859a321e-18e2-437b-aa7a-2a45a42ee737") + def test_ranged_discovery_solicited_active_prange_snorange(self): + """Verify discovery with ranging: - Solicited Publish/Active Subscribe - Publisher enables ranging - Subscriber disables ranging Expect: normal discovery (as if no ranging performed) - no distance """ - self.run_discovery( - p_config=autils.add_ranging_to_pub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.PUBLISH_TYPE_SOLICITED, - ssi=self.getname()), - enable_ranging=True), - s_config=autils.create_discovery_config(self.SERVICE_NAME, - aconsts.SUBSCRIBE_TYPE_ACTIVE, - ssi=self.getname()), - expect_discovery=True, - expect_range=False) - - @test_tracker_info(uuid="12a4f899-4f70-4641-8f3c-351004669b71") - def test_ranged_discovery_unsolicited_passive_pnorange_smax_inrange(self): - """Verify discovery with ranging: + self.run_discovery( + p_config=autils.add_ranging_to_pub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.PUBLISH_TYPE_SOLICITED, + ssi=self.getname()), + enable_ranging=True), + s_config=autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.SUBSCRIBE_TYPE_ACTIVE, + ssi=self.getname()), + expect_discovery=True, + expect_range=False) + + @test_tracker_info(uuid="12a4f899-4f70-4641-8f3c-351004669b71") + def test_ranged_discovery_unsolicited_passive_pnorange_smax_inrange(self): + """Verify discovery with ranging: - Unsolicited Publish/Passive Subscribe - Publisher disables ranging - Subscriber enables ranging with max such that always within range (large @@ -267,24 +287,26 @@ class AwareDiscoveryWithRangingTest(AwareBaseTest, RttBaseTest): Expect: normal discovery (as if no ranging performed) - no distance """ - self.run_discovery( - p_config=autils.add_ranging_to_pub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.PUBLISH_TYPE_UNSOLICITED, - ssi=self.getname()), - enable_ranging=False), - s_config=autils.add_ranging_to_sub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.SUBSCRIBE_TYPE_PASSIVE, - ssi=self.getname()), - min_distance_mm=None, - max_distance_mm=1000000), - expect_discovery=True, - expect_range=False) - - @test_tracker_info(uuid="b7f90793-113d-4355-be20-856d92ac939f") - def test_ranged_discovery_solicited_active_pnorange_smax_inrange(self): - """Verify discovery with ranging: + self.run_discovery( + p_config=autils.add_ranging_to_pub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.PUBLISH_TYPE_UNSOLICITED, + ssi=self.getname()), + enable_ranging=False), + s_config=autils.add_ranging_to_sub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.SUBSCRIBE_TYPE_PASSIVE, + ssi=self.getname()), + min_distance_mm=None, + max_distance_mm=1000000), + expect_discovery=True, + expect_range=False) + + @test_tracker_info(uuid="b7f90793-113d-4355-be20-856d92ac939f") + def test_ranged_discovery_solicited_active_pnorange_smax_inrange(self): + """Verify discovery with ranging: - Solicited Publish/Active Subscribe - Publisher disables ranging - Subscriber enables ranging with max such that always within range (large @@ -292,24 +314,27 @@ class AwareDiscoveryWithRangingTest(AwareBaseTest, RttBaseTest): Expect: normal discovery (as if no ranging performed) - no distance """ - self.run_discovery( - p_config=autils.add_ranging_to_pub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.PUBLISH_TYPE_SOLICITED, - ssi=self.getname()), - enable_ranging=False), - s_config=autils.add_ranging_to_sub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.SUBSCRIBE_TYPE_ACTIVE, - ssi=self.getname()), - min_distance_mm=None, - max_distance_mm=1000000), - expect_discovery=True, - expect_range=False) - - @test_tracker_info(uuid="da3ab6df-58f9-44ae-b7be-8200d9e1bb76") - def test_ranged_discovery_unsolicited_passive_pnorange_smin_outofrange(self): - """Verify discovery with ranging: + self.run_discovery( + p_config=autils.add_ranging_to_pub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.PUBLISH_TYPE_SOLICITED, + ssi=self.getname()), + enable_ranging=False), + s_config=autils.add_ranging_to_sub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.SUBSCRIBE_TYPE_ACTIVE, + ssi=self.getname()), + min_distance_mm=None, + max_distance_mm=1000000), + expect_discovery=True, + expect_range=False) + + @test_tracker_info(uuid="da3ab6df-58f9-44ae-b7be-8200d9e1bb76") + def test_ranged_discovery_unsolicited_passive_pnorange_smin_outofrange( + self): + """Verify discovery with ranging: - Unsolicited Publish/Passive Subscribe - Publisher disables ranging - Subscriber enables ranging with min such that always out of range (large @@ -317,24 +342,26 @@ class AwareDiscoveryWithRangingTest(AwareBaseTest, RttBaseTest): Expect: normal discovery (as if no ranging performed) - no distance """ - self.run_discovery( - p_config=autils.add_ranging_to_pub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.PUBLISH_TYPE_UNSOLICITED, - ssi=self.getname()), - enable_ranging=False), - s_config=autils.add_ranging_to_sub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.SUBSCRIBE_TYPE_PASSIVE, - ssi=self.getname()), - min_distance_mm=1000000, - max_distance_mm=None), - expect_discovery=True, - expect_range=False) - - @test_tracker_info(uuid="275e0806-f266-4fa6-9ca0-1cfd7b65a6ca") - def test_ranged_discovery_solicited_active_pnorange_smin_outofrange(self): - """Verify discovery with ranging: + self.run_discovery( + p_config=autils.add_ranging_to_pub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.PUBLISH_TYPE_UNSOLICITED, + ssi=self.getname()), + enable_ranging=False), + s_config=autils.add_ranging_to_sub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.SUBSCRIBE_TYPE_PASSIVE, + ssi=self.getname()), + min_distance_mm=1000000, + max_distance_mm=None), + expect_discovery=True, + expect_range=False) + + @test_tracker_info(uuid="275e0806-f266-4fa6-9ca0-1cfd7b65a6ca") + def test_ranged_discovery_solicited_active_pnorange_smin_outofrange(self): + """Verify discovery with ranging: - Solicited Publish/Active Subscribe - Publisher disables ranging - Subscriber enables ranging with min such that always out of range (large @@ -342,72 +369,78 @@ class AwareDiscoveryWithRangingTest(AwareBaseTest, RttBaseTest): Expect: normal discovery (as if no ranging performed) - no distance """ - self.run_discovery( - p_config=autils.add_ranging_to_pub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.PUBLISH_TYPE_SOLICITED, - ssi=self.getname()), - enable_ranging=False), - s_config=autils.add_ranging_to_sub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.SUBSCRIBE_TYPE_ACTIVE, - ssi=self.getname()), - min_distance_mm=1000000, - max_distance_mm=None), - expect_discovery=True, - expect_range=False) - - @test_tracker_info(uuid="8cd0aa1e-6866-4a5d-a550-f25483eebea1") - def test_ranged_discovery_unsolicited_passive_prange_smin_inrange(self): - """Verify discovery with ranging: + self.run_discovery( + p_config=autils.add_ranging_to_pub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.PUBLISH_TYPE_SOLICITED, + ssi=self.getname()), + enable_ranging=False), + s_config=autils.add_ranging_to_sub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.SUBSCRIBE_TYPE_ACTIVE, + ssi=self.getname()), + min_distance_mm=1000000, + max_distance_mm=None), + expect_discovery=True, + expect_range=False) + + @test_tracker_info(uuid="8cd0aa1e-6866-4a5d-a550-f25483eebea1") + def test_ranged_discovery_unsolicited_passive_prange_smin_inrange(self): + """Verify discovery with ranging: - Unsolicited Publish/Passive Subscribe - Publisher enables ranging - Subscriber enables ranging with min such that in range (min=0) Expect: discovery with distance """ - self.run_discovery( - p_config=autils.add_ranging_to_pub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.PUBLISH_TYPE_UNSOLICITED, - ssi=self.getname()), - enable_ranging=True), - s_config=autils.add_ranging_to_sub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.SUBSCRIBE_TYPE_PASSIVE, - ssi=self.getname()), - min_distance_mm=0, - max_distance_mm=None), - expect_discovery=True, - expect_range=True) - - @test_tracker_info(uuid="97c22c54-669b-4f7a-bf51-2f484e5f3e74") - def test_ranged_discovery_unsolicited_passive_prange_smax_inrange(self): - """Verify discovery with ranging: + self.run_discovery( + p_config=autils.add_ranging_to_pub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.PUBLISH_TYPE_UNSOLICITED, + ssi=self.getname()), + enable_ranging=True), + s_config=autils.add_ranging_to_sub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.SUBSCRIBE_TYPE_PASSIVE, + ssi=self.getname()), + min_distance_mm=0, + max_distance_mm=None), + expect_discovery=True, + expect_range=True) + + @test_tracker_info(uuid="97c22c54-669b-4f7a-bf51-2f484e5f3e74") + def test_ranged_discovery_unsolicited_passive_prange_smax_inrange(self): + """Verify discovery with ranging: - Unsolicited Publish/Passive Subscribe - Publisher enables ranging - Subscriber enables ranging with max such that in range (max=large) Expect: discovery with distance """ - self.run_discovery( - p_config=autils.add_ranging_to_pub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.PUBLISH_TYPE_UNSOLICITED, - ssi=self.getname()), - enable_ranging=True), - s_config=autils.add_ranging_to_sub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.SUBSCRIBE_TYPE_PASSIVE, - ssi=self.getname()), - min_distance_mm=None, - max_distance_mm=1000000), - expect_discovery=True, - expect_range=True) - - @test_tracker_info(uuid="616673d7-9d0b-43de-a378-e5e949b51b32") - def test_ranged_discovery_unsolicited_passive_prange_sminmax_inrange(self): - """Verify discovery with ranging: + self.run_discovery( + p_config=autils.add_ranging_to_pub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.PUBLISH_TYPE_UNSOLICITED, + ssi=self.getname()), + enable_ranging=True), + s_config=autils.add_ranging_to_sub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.SUBSCRIBE_TYPE_PASSIVE, + ssi=self.getname()), + min_distance_mm=None, + max_distance_mm=1000000), + expect_discovery=True, + expect_range=True) + + @test_tracker_info(uuid="616673d7-9d0b-43de-a378-e5e949b51b32") + def test_ranged_discovery_unsolicited_passive_prange_sminmax_inrange(self): + """Verify discovery with ranging: - Unsolicited Publish/Passive Subscribe - Publisher enables ranging - Subscriber enables ranging with min/max such that in range (min=0, @@ -415,72 +448,78 @@ class AwareDiscoveryWithRangingTest(AwareBaseTest, RttBaseTest): Expect: discovery with distance """ - self.run_discovery( - p_config=autils.add_ranging_to_pub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.PUBLISH_TYPE_UNSOLICITED, - ssi=self.getname()), - enable_ranging=True), - s_config=autils.add_ranging_to_sub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.SUBSCRIBE_TYPE_PASSIVE, - ssi=self.getname()), - min_distance_mm=0, - max_distance_mm=1000000), - expect_discovery=True, - expect_range=True) - - @test_tracker_info(uuid="2bf84912-dcad-4a8f-971f-e445a07f05ce") - def test_ranged_discovery_solicited_active_prange_smin_inrange(self): - """Verify discovery with ranging: + self.run_discovery( + p_config=autils.add_ranging_to_pub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.PUBLISH_TYPE_UNSOLICITED, + ssi=self.getname()), + enable_ranging=True), + s_config=autils.add_ranging_to_sub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.SUBSCRIBE_TYPE_PASSIVE, + ssi=self.getname()), + min_distance_mm=0, + max_distance_mm=1000000), + expect_discovery=True, + expect_range=True) + + @test_tracker_info(uuid="2bf84912-dcad-4a8f-971f-e445a07f05ce") + def test_ranged_discovery_solicited_active_prange_smin_inrange(self): + """Verify discovery with ranging: - Solicited Publish/Active Subscribe - Publisher enables ranging - Subscriber enables ranging with min such that in range (min=0) Expect: discovery with distance """ - self.run_discovery( - p_config=autils.add_ranging_to_pub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.PUBLISH_TYPE_SOLICITED, - ssi=self.getname()), - enable_ranging=True), - s_config=autils.add_ranging_to_sub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.SUBSCRIBE_TYPE_ACTIVE, - ssi=self.getname()), - min_distance_mm=0, - max_distance_mm=None), - expect_discovery=True, - expect_range=True) - - @test_tracker_info(uuid="5cfd7961-9665-4742-a1b5-2d1fc97f9795") - def test_ranged_discovery_solicited_active_prange_smax_inrange(self): - """Verify discovery with ranging: + self.run_discovery( + p_config=autils.add_ranging_to_pub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.PUBLISH_TYPE_SOLICITED, + ssi=self.getname()), + enable_ranging=True), + s_config=autils.add_ranging_to_sub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.SUBSCRIBE_TYPE_ACTIVE, + ssi=self.getname()), + min_distance_mm=0, + max_distance_mm=None), + expect_discovery=True, + expect_range=True) + + @test_tracker_info(uuid="5cfd7961-9665-4742-a1b5-2d1fc97f9795") + def test_ranged_discovery_solicited_active_prange_smax_inrange(self): + """Verify discovery with ranging: - Solicited Publish/Active Subscribe - Publisher enables ranging - Subscriber enables ranging with max such that in range (max=large) Expect: discovery with distance """ - self.run_discovery( - p_config=autils.add_ranging_to_pub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.PUBLISH_TYPE_SOLICITED, - ssi=self.getname()), - enable_ranging=True), - s_config=autils.add_ranging_to_sub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.SUBSCRIBE_TYPE_ACTIVE, - ssi=self.getname()), - min_distance_mm=None, - max_distance_mm=1000000), - expect_discovery=True, - expect_range=True) - - @test_tracker_info(uuid="5cf650ad-0b42-4b7d-9e05-d5f45fe0554d") - def test_ranged_discovery_solicited_active_prange_sminmax_inrange(self): - """Verify discovery with ranging: + self.run_discovery( + p_config=autils.add_ranging_to_pub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.PUBLISH_TYPE_SOLICITED, + ssi=self.getname()), + enable_ranging=True), + s_config=autils.add_ranging_to_sub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.SUBSCRIBE_TYPE_ACTIVE, + ssi=self.getname()), + min_distance_mm=None, + max_distance_mm=1000000), + expect_discovery=True, + expect_range=True) + + @test_tracker_info(uuid="5cf650ad-0b42-4b7d-9e05-d5f45fe0554d") + def test_ranged_discovery_solicited_active_prange_sminmax_inrange(self): + """Verify discovery with ranging: - Solicited Publish/Active Subscribe - Publisher enables ranging - Subscriber enables ranging with min/max such that in range (min=0, @@ -488,70 +527,77 @@ class AwareDiscoveryWithRangingTest(AwareBaseTest, RttBaseTest): Expect: discovery with distance """ - self.run_discovery( - p_config=autils.add_ranging_to_pub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.PUBLISH_TYPE_SOLICITED, - ssi=self.getname()), - enable_ranging=True), - s_config=autils.add_ranging_to_sub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.SUBSCRIBE_TYPE_ACTIVE, - ssi=self.getname()), - min_distance_mm=0, - max_distance_mm=1000000), - expect_discovery=True, - expect_range=True) - - @test_tracker_info(uuid="5277f418-ac35-43ce-9b30-3c895272898e") - def test_ranged_discovery_unsolicited_passive_prange_smin_outofrange(self): - """Verify discovery with ranging: + self.run_discovery( + p_config=autils.add_ranging_to_pub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.PUBLISH_TYPE_SOLICITED, + ssi=self.getname()), + enable_ranging=True), + s_config=autils.add_ranging_to_sub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.SUBSCRIBE_TYPE_ACTIVE, + ssi=self.getname()), + min_distance_mm=0, + max_distance_mm=1000000), + expect_discovery=True, + expect_range=True) + + @test_tracker_info(uuid="5277f418-ac35-43ce-9b30-3c895272898e") + def test_ranged_discovery_unsolicited_passive_prange_smin_outofrange(self): + """Verify discovery with ranging: - Unsolicited Publish/Passive Subscribe - Publisher enables ranging - Subscriber enables ranging with min such that out of range (min=large) Expect: no discovery """ - self.run_discovery( - p_config=autils.add_ranging_to_pub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.PUBLISH_TYPE_UNSOLICITED, - ssi=self.getname()), - enable_ranging=True), - s_config=autils.add_ranging_to_sub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.SUBSCRIBE_TYPE_PASSIVE, - ssi=self.getname()), - min_distance_mm=1000000, - max_distance_mm=None), - expect_discovery=False) - - @test_tracker_info(uuid="8a7e6ab1-acf4-41a7-a5fb-8c164d593b5f") - def test_ranged_discovery_unsolicited_passive_prange_smax_outofrange(self): - """Verify discovery with ranging: + self.run_discovery( + p_config=autils.add_ranging_to_pub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.PUBLISH_TYPE_UNSOLICITED, + ssi=self.getname()), + enable_ranging=True), + s_config=autils.add_ranging_to_sub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.SUBSCRIBE_TYPE_PASSIVE, + ssi=self.getname()), + min_distance_mm=1000000, + max_distance_mm=None), + expect_discovery=False) + + @test_tracker_info(uuid="8a7e6ab1-acf4-41a7-a5fb-8c164d593b5f") + def test_ranged_discovery_unsolicited_passive_prange_smax_outofrange(self): + """Verify discovery with ranging: - Unsolicited Publish/Passive Subscribe - Publisher enables ranging - Subscriber enables ranging with max such that in range (max=0) Expect: no discovery """ - self.run_discovery( - p_config=autils.add_ranging_to_pub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.PUBLISH_TYPE_UNSOLICITED, - ssi=self.getname()), - enable_ranging=True), - s_config=autils.add_ranging_to_sub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.SUBSCRIBE_TYPE_PASSIVE, - ssi=self.getname()), - min_distance_mm=None, - max_distance_mm=0), - expect_discovery=False) - - @test_tracker_info(uuid="b744f5f9-2641-4373-bf86-3752e2f9aace") - def test_ranged_discovery_unsolicited_passive_prange_sminmax_outofrange(self): - """Verify discovery with ranging: + self.run_discovery( + p_config=autils.add_ranging_to_pub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.PUBLISH_TYPE_UNSOLICITED, + ssi=self.getname()), + enable_ranging=True), + s_config=autils.add_ranging_to_sub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.SUBSCRIBE_TYPE_PASSIVE, + ssi=self.getname()), + min_distance_mm=None, + max_distance_mm=0), + expect_discovery=False) + + @test_tracker_info(uuid="b744f5f9-2641-4373-bf86-3752e2f9aace") + def test_ranged_discovery_unsolicited_passive_prange_sminmax_outofrange( + self): + """Verify discovery with ranging: - Unsolicited Publish/Passive Subscribe - Publisher enables ranging - Subscriber enables ranging with min/max such that out of range (min=large, @@ -559,69 +605,75 @@ class AwareDiscoveryWithRangingTest(AwareBaseTest, RttBaseTest): Expect: no discovery """ - self.run_discovery( - p_config=autils.add_ranging_to_pub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.PUBLISH_TYPE_UNSOLICITED, - ssi=self.getname()), - enable_ranging=True), - s_config=autils.add_ranging_to_sub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.SUBSCRIBE_TYPE_PASSIVE, - ssi=self.getname()), - min_distance_mm=1000000, - max_distance_mm=1000001), - expect_discovery=False) - - @test_tracker_info(uuid="d2e94199-b2e6-4fa5-a347-24594883c801") - def test_ranged_discovery_solicited_active_prange_smin_outofrange(self): - """Verify discovery with ranging: + self.run_discovery( + p_config=autils.add_ranging_to_pub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.PUBLISH_TYPE_UNSOLICITED, + ssi=self.getname()), + enable_ranging=True), + s_config=autils.add_ranging_to_sub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.SUBSCRIBE_TYPE_PASSIVE, + ssi=self.getname()), + min_distance_mm=1000000, + max_distance_mm=1000001), + expect_discovery=False) + + @test_tracker_info(uuid="d2e94199-b2e6-4fa5-a347-24594883c801") + def test_ranged_discovery_solicited_active_prange_smin_outofrange(self): + """Verify discovery with ranging: - Solicited Publish/Active Subscribe - Publisher enables ranging - Subscriber enables ranging with min such that out of range (min=large) Expect: no discovery """ - self.run_discovery( - p_config=autils.add_ranging_to_pub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.PUBLISH_TYPE_SOLICITED, - ssi=self.getname()), - enable_ranging=True), - s_config=autils.add_ranging_to_sub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.SUBSCRIBE_TYPE_ACTIVE, - ssi=self.getname()), - min_distance_mm=1000000, - max_distance_mm=None), - expect_discovery=False) - - @test_tracker_info(uuid="a5619835-496a-4244-a428-f85cba3d4115") - def test_ranged_discovery_solicited_active_prange_smax_outofrange(self): - """Verify discovery with ranging: + self.run_discovery( + p_config=autils.add_ranging_to_pub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.PUBLISH_TYPE_SOLICITED, + ssi=self.getname()), + enable_ranging=True), + s_config=autils.add_ranging_to_sub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.SUBSCRIBE_TYPE_ACTIVE, + ssi=self.getname()), + min_distance_mm=1000000, + max_distance_mm=None), + expect_discovery=False) + + @test_tracker_info(uuid="a5619835-496a-4244-a428-f85cba3d4115") + def test_ranged_discovery_solicited_active_prange_smax_outofrange(self): + """Verify discovery with ranging: - Solicited Publish/Active Subscribe - Publisher enables ranging - Subscriber enables ranging with max such that out of range (max=0) Expect: no discovery """ - self.run_discovery( - p_config=autils.add_ranging_to_pub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.PUBLISH_TYPE_SOLICITED, - ssi=self.getname()), - enable_ranging=True), - s_config=autils.add_ranging_to_sub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.SUBSCRIBE_TYPE_ACTIVE, - ssi=self.getname()), - min_distance_mm=None, - max_distance_mm=0), - expect_discovery=False) - - @test_tracker_info(uuid="12ebd91f-a973-410b-8ee1-0bd86024b921") - def test_ranged_discovery_solicited_active_prange_sminmax_outofrange(self): - """Verify discovery with ranging: + self.run_discovery( + p_config=autils.add_ranging_to_pub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.PUBLISH_TYPE_SOLICITED, + ssi=self.getname()), + enable_ranging=True), + s_config=autils.add_ranging_to_sub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.SUBSCRIBE_TYPE_ACTIVE, + ssi=self.getname()), + min_distance_mm=None, + max_distance_mm=0), + expect_discovery=False) + + @test_tracker_info(uuid="12ebd91f-a973-410b-8ee1-0bd86024b921") + def test_ranged_discovery_solicited_active_prange_sminmax_outofrange(self): + """Verify discovery with ranging: - Solicited Publish/Active Subscribe - Publisher enables ranging - Subscriber enables ranging with min/max such that out of range (min=large, @@ -629,34 +681,36 @@ class AwareDiscoveryWithRangingTest(AwareBaseTest, RttBaseTest): Expect: no discovery """ - self.run_discovery( - p_config=autils.add_ranging_to_pub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.PUBLISH_TYPE_SOLICITED, - ssi=self.getname()), - enable_ranging=True), - s_config=autils.add_ranging_to_sub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.SUBSCRIBE_TYPE_ACTIVE, - ssi=self.getname()), - min_distance_mm=1000000, - max_distance_mm=1000001), - expect_discovery=False) - - ######################################################################### - # Run discovery with ranging configuration & update configurations after - # first run. - # - # Names: test_ranged_updated_discovery_<ptype>_<stype>_<scenario> - # - # where: - # <ptype>_<stype>: unsolicited_passive or solicited_active - # <scenario>: test scenario (details in name) - ######################################################################### - - @test_tracker_info(uuid="59442180-4a6c-428f-b926-86000e8339b4") - def test_ranged_updated_discovery_unsolicited_passive_oor_to_ir(self): - """Verify discovery with ranging operation with updated configuration: + self.run_discovery( + p_config=autils.add_ranging_to_pub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.PUBLISH_TYPE_SOLICITED, + ssi=self.getname()), + enable_ranging=True), + s_config=autils.add_ranging_to_sub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.SUBSCRIBE_TYPE_ACTIVE, + ssi=self.getname()), + min_distance_mm=1000000, + max_distance_mm=1000001), + expect_discovery=False) + + ######################################################################### + # Run discovery with ranging configuration & update configurations after + # first run. + # + # Names: test_ranged_updated_discovery_<ptype>_<stype>_<scenario> + # + # where: + # <ptype>_<stype>: unsolicited_passive or solicited_active + # <scenario>: test scenario (details in name) + ######################################################################### + + @test_tracker_info(uuid="59442180-4a6c-428f-b926-86000e8339b4") + def test_ranged_updated_discovery_unsolicited_passive_oor_to_ir(self): + """Verify discovery with ranging operation with updated configuration: - Unsolicited Publish/Passive Subscribe - Publisher enables ranging - Subscriber: @@ -667,22 +721,27 @@ class AwareDiscoveryWithRangingTest(AwareBaseTest, RttBaseTest): Expect: discovery + ranging after update """ - (p_dut, s_dut, p_disc_id, - s_disc_id) = self.run_discovery_prange_sminmax_outofrange(True) - self.run_discovery_update(p_dut, s_dut, p_disc_id, s_disc_id, - p_config=None, # no updates - s_config=autils.add_ranging_to_sub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.SUBSCRIBE_TYPE_PASSIVE, - ssi=self.getname()), - min_distance_mm=0, - max_distance_mm=1000000), - expect_discovery=True, - expect_range=True) - - @test_tracker_info(uuid="60188508-104d-42d5-ac3a-3605093c45d7") - def test_ranged_updated_discovery_unsolicited_passive_pub_unrange(self): - """Verify discovery with ranging operation with updated configuration: + (p_dut, s_dut, p_disc_id, + s_disc_id) = self.run_discovery_prange_sminmax_outofrange(True) + self.run_discovery_update( + p_dut, + s_dut, + p_disc_id, + s_disc_id, + p_config=None, # no updates + s_config=autils.add_ranging_to_sub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.SUBSCRIBE_TYPE_PASSIVE, + ssi=self.getname()), + min_distance_mm=0, + max_distance_mm=1000000), + expect_discovery=True, + expect_range=True) + + @test_tracker_info(uuid="60188508-104d-42d5-ac3a-3605093c45d7") + def test_ranged_updated_discovery_unsolicited_passive_pub_unrange(self): + """Verify discovery with ranging operation with updated configuration: - Unsolicited Publish/Passive Subscribe - Publisher enables ranging - Subscriber: Ranging enabled, min/max such that out of range (min=large, @@ -691,19 +750,24 @@ class AwareDiscoveryWithRangingTest(AwareBaseTest, RttBaseTest): Expect: discovery w/o ranging after update """ - (p_dut, s_dut, p_disc_id, - s_disc_id) = self.run_discovery_prange_sminmax_outofrange(True) - self.run_discovery_update(p_dut, s_dut, p_disc_id, s_disc_id, - p_config=autils.create_discovery_config(self.SERVICE_NAME, - aconsts.PUBLISH_TYPE_UNSOLICITED, - ssi=self.getname()), - s_config=None, # no updates - expect_discovery=True, - expect_range=False) - - @test_tracker_info(uuid="f96b434e-751d-4eb5-ae01-0c5c3a6fb4a2") - def test_ranged_updated_discovery_unsolicited_passive_sub_unrange(self): - """Verify discovery with ranging operation with updated configuration: + (p_dut, s_dut, p_disc_id, + s_disc_id) = self.run_discovery_prange_sminmax_outofrange(True) + self.run_discovery_update( + p_dut, + s_dut, + p_disc_id, + s_disc_id, + p_config=autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.PUBLISH_TYPE_UNSOLICITED, + ssi=self.getname()), + s_config=None, # no updates + expect_discovery=True, + expect_range=False) + + @test_tracker_info(uuid="f96b434e-751d-4eb5-ae01-0c5c3a6fb4a2") + def test_ranged_updated_discovery_unsolicited_passive_sub_unrange(self): + """Verify discovery with ranging operation with updated configuration: - Unsolicited Publish/Passive Subscribe - Publisher enables ranging - Subscriber: @@ -713,19 +777,24 @@ class AwareDiscoveryWithRangingTest(AwareBaseTest, RttBaseTest): Expect: discovery w/o ranging after update """ - (p_dut, s_dut, p_disc_id, - s_disc_id) = self.run_discovery_prange_sminmax_outofrange(True) - self.run_discovery_update(p_dut, s_dut, p_disc_id, s_disc_id, - p_config=None, # no updates - s_config=autils.create_discovery_config(self.SERVICE_NAME, - aconsts.SUBSCRIBE_TYPE_PASSIVE, - ssi=self.getname()), - expect_discovery=True, - expect_range=False) - - @test_tracker_info(uuid="78970de8-9362-4647-931a-3513bcf58e80") - def test_ranged_updated_discovery_unsolicited_passive_sub_oor(self): - """Verify discovery with ranging operation with updated configuration: + (p_dut, s_dut, p_disc_id, + s_disc_id) = self.run_discovery_prange_sminmax_outofrange(True) + self.run_discovery_update( + p_dut, + s_dut, + p_disc_id, + s_disc_id, + p_config=None, # no updates + s_config=autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.SUBSCRIBE_TYPE_PASSIVE, + ssi=self.getname()), + expect_discovery=True, + expect_range=False) + + @test_tracker_info(uuid="78970de8-9362-4647-931a-3513bcf58e80") + def test_ranged_updated_discovery_unsolicited_passive_sub_oor(self): + """Verify discovery with ranging operation with updated configuration: - Unsolicited Publish/Passive Subscribe - Publisher enables ranging - Subscriber: @@ -735,21 +804,26 @@ class AwareDiscoveryWithRangingTest(AwareBaseTest, RttBaseTest): Expect: no discovery after update """ - (p_dut, s_dut, p_disc_id, - s_disc_id) = self.run_discovery_prange_sminmax_outofrange(True) - self.run_discovery_update(p_dut, s_dut, p_disc_id, s_disc_id, - p_config=None, # no updates - s_config=autils.add_ranging_to_sub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.SUBSCRIBE_TYPE_PASSIVE, - ssi=self.getname()), - min_distance_mm=100000, - max_distance_mm=100001), - expect_discovery=False) - - @test_tracker_info(uuid="0841ad05-4899-4521-bd24-04a8e2e345ac") - def test_ranged_updated_discovery_unsolicited_passive_pub_same(self): - """Verify discovery with ranging operation with updated configuration: + (p_dut, s_dut, p_disc_id, + s_disc_id) = self.run_discovery_prange_sminmax_outofrange(True) + self.run_discovery_update( + p_dut, + s_dut, + p_disc_id, + s_disc_id, + p_config=None, # no updates + s_config=autils.add_ranging_to_sub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.SUBSCRIBE_TYPE_PASSIVE, + ssi=self.getname()), + min_distance_mm=100000, + max_distance_mm=100001), + expect_discovery=False) + + @test_tracker_info(uuid="0841ad05-4899-4521-bd24-04a8e2e345ac") + def test_ranged_updated_discovery_unsolicited_passive_pub_same(self): + """Verify discovery with ranging operation with updated configuration: - Unsolicited Publish/Passive Subscribe - Publisher enables ranging - Subscriber: Ranging enabled, min/max such that out of range (min=large, @@ -758,20 +832,25 @@ class AwareDiscoveryWithRangingTest(AwareBaseTest, RttBaseTest): Expect: no discovery after update """ - (p_dut, s_dut, p_disc_id, - s_disc_id) = self.run_discovery_prange_sminmax_outofrange(True) - self.run_discovery_update(p_dut, s_dut, p_disc_id, s_disc_id, - p_config=autils.add_ranging_to_pub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.PUBLISH_TYPE_UNSOLICITED, - ssi=self.getname()), - enable_ranging=True), - s_config=None, # no updates - expect_discovery=False) - - @test_tracker_info(uuid="ec6ca57b-f115-4516-813a-4572b930c8d3") - def test_ranged_updated_discovery_unsolicited_passive_multi_step(self): - """Verify discovery with ranging operation with updated configuration: + (p_dut, s_dut, p_disc_id, + s_disc_id) = self.run_discovery_prange_sminmax_outofrange(True) + self.run_discovery_update( + p_dut, + s_dut, + p_disc_id, + s_disc_id, + p_config=autils.add_ranging_to_pub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.PUBLISH_TYPE_UNSOLICITED, + ssi=self.getname()), + enable_ranging=True), + s_config=None, # no updates + expect_discovery=False) + + @test_tracker_info(uuid="ec6ca57b-f115-4516-813a-4572b930c8d3") + def test_ranged_updated_discovery_unsolicited_passive_multi_step(self): + """Verify discovery with ranging operation with updated configuration: - Unsolicited Publish/Passive Subscribe - Publisher enables ranging - Subscriber: Ranging enabled, min/max such that out of range (min=large, @@ -785,38 +864,53 @@ class AwareDiscoveryWithRangingTest(AwareBaseTest, RttBaseTest): - Reconfigured to: Ranging disabled - Expect: discovery without ranging """ - (p_dut, s_dut, p_disc_id, - s_disc_id) = self.run_discovery_prange_sminmax_outofrange(True) - self.run_discovery_update(p_dut, s_dut, p_disc_id, s_disc_id, - p_config=None, # no updates + (p_dut, s_dut, p_disc_id, + s_disc_id) = self.run_discovery_prange_sminmax_outofrange(True) + self.run_discovery_update( + p_dut, + s_dut, + p_disc_id, + s_disc_id, + p_config=None, # no updates s_config=autils.add_ranging_to_sub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.SUBSCRIBE_TYPE_PASSIVE, - ssi=self.getname()), + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.SUBSCRIBE_TYPE_PASSIVE, + ssi=self.getname()), min_distance_mm=0, max_distance_mm=None), expect_discovery=True, expect_range=True) - self.run_discovery_update(p_dut, s_dut, p_disc_id, s_disc_id, - p_config=None, # no updates + self.run_discovery_update( + p_dut, + s_dut, + p_disc_id, + s_disc_id, + p_config=None, # no updates s_config=autils.add_ranging_to_sub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.SUBSCRIBE_TYPE_PASSIVE, - ssi=self.getname()), + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.SUBSCRIBE_TYPE_PASSIVE, + ssi=self.getname()), min_distance_mm=1000000, max_distance_mm=None), expect_discovery=False) - self.run_discovery_update(p_dut, s_dut, p_disc_id, s_disc_id, - p_config=None, # no updates - s_config=autils.create_discovery_config(self.SERVICE_NAME, - aconsts.SUBSCRIBE_TYPE_PASSIVE, - ssi=self.getname()), + self.run_discovery_update( + p_dut, + s_dut, + p_disc_id, + s_disc_id, + p_config=None, # no updates + s_config=autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.SUBSCRIBE_TYPE_PASSIVE, + ssi=self.getname()), expect_discovery=True, expect_range=False) - @test_tracker_info(uuid="bbaac63b-000c-415f-bf19-0906f04031cd") - def test_ranged_updated_discovery_solicited_active_oor_to_ir(self): - """Verify discovery with ranging operation with updated configuration: + @test_tracker_info(uuid="bbaac63b-000c-415f-bf19-0906f04031cd") + def test_ranged_updated_discovery_solicited_active_oor_to_ir(self): + """Verify discovery with ranging operation with updated configuration: - Solicited Publish/Active Subscribe - Publisher enables ranging - Subscriber: @@ -827,22 +921,27 @@ class AwareDiscoveryWithRangingTest(AwareBaseTest, RttBaseTest): Expect: discovery + ranging after update """ - (p_dut, s_dut, p_disc_id, - s_disc_id) = self.run_discovery_prange_sminmax_outofrange(False) - self.run_discovery_update(p_dut, s_dut, p_disc_id, s_disc_id, - p_config=None, # no updates - s_config=autils.add_ranging_to_sub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.SUBSCRIBE_TYPE_ACTIVE, - ssi=self.getname()), - min_distance_mm=0, - max_distance_mm=1000000), - expect_discovery=True, - expect_range=True) - - @test_tracker_info(uuid="c385b361-7955-4f34-9109-8d8ca81cb4cc") - def test_ranged_updated_discovery_solicited_active_pub_unrange(self): - """Verify discovery with ranging operation with updated configuration: + (p_dut, s_dut, p_disc_id, + s_disc_id) = self.run_discovery_prange_sminmax_outofrange(False) + self.run_discovery_update( + p_dut, + s_dut, + p_disc_id, + s_disc_id, + p_config=None, # no updates + s_config=autils.add_ranging_to_sub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.SUBSCRIBE_TYPE_ACTIVE, + ssi=self.getname()), + min_distance_mm=0, + max_distance_mm=1000000), + expect_discovery=True, + expect_range=True) + + @test_tracker_info(uuid="c385b361-7955-4f34-9109-8d8ca81cb4cc") + def test_ranged_updated_discovery_solicited_active_pub_unrange(self): + """Verify discovery with ranging operation with updated configuration: - Solicited Publish/Active Subscribe - Publisher enables ranging - Subscriber: Ranging enabled, min/max such that out of range (min=large, @@ -851,19 +950,24 @@ class AwareDiscoveryWithRangingTest(AwareBaseTest, RttBaseTest): Expect: discovery w/o ranging after update """ - (p_dut, s_dut, p_disc_id, - s_disc_id) = self.run_discovery_prange_sminmax_outofrange(False) - self.run_discovery_update(p_dut, s_dut, p_disc_id, s_disc_id, - p_config=autils.create_discovery_config(self.SERVICE_NAME, - aconsts.PUBLISH_TYPE_SOLICITED, - ssi=self.getname()), - s_config=None, # no updates - expect_discovery=True, - expect_range=False) - - @test_tracker_info(uuid="ec5120ea-77ec-48c6-8820-48b82ad3dfd4") - def test_ranged_updated_discovery_solicited_active_sub_unrange(self): - """Verify discovery with ranging operation with updated configuration: + (p_dut, s_dut, p_disc_id, + s_disc_id) = self.run_discovery_prange_sminmax_outofrange(False) + self.run_discovery_update( + p_dut, + s_dut, + p_disc_id, + s_disc_id, + p_config=autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.PUBLISH_TYPE_SOLICITED, + ssi=self.getname()), + s_config=None, # no updates + expect_discovery=True, + expect_range=False) + + @test_tracker_info(uuid="ec5120ea-77ec-48c6-8820-48b82ad3dfd4") + def test_ranged_updated_discovery_solicited_active_sub_unrange(self): + """Verify discovery with ranging operation with updated configuration: - Solicited Publish/Active Subscribe - Publisher enables ranging - Subscriber: @@ -873,19 +977,24 @@ class AwareDiscoveryWithRangingTest(AwareBaseTest, RttBaseTest): Expect: discovery w/o ranging after update """ - (p_dut, s_dut, p_disc_id, - s_disc_id) = self.run_discovery_prange_sminmax_outofrange(False) - self.run_discovery_update(p_dut, s_dut, p_disc_id, s_disc_id, - p_config=None, # no updates - s_config=autils.create_discovery_config(self.SERVICE_NAME, - aconsts.SUBSCRIBE_TYPE_ACTIVE, - ssi=self.getname()), - expect_discovery=True, - expect_range=False) - - @test_tracker_info(uuid="6231cb42-91e4-48d3-b9db-b37efbe8537c") - def test_ranged_updated_discovery_solicited_active_sub_oor(self): - """Verify discovery with ranging operation with updated configuration: + (p_dut, s_dut, p_disc_id, + s_disc_id) = self.run_discovery_prange_sminmax_outofrange(False) + self.run_discovery_update( + p_dut, + s_dut, + p_disc_id, + s_disc_id, + p_config=None, # no updates + s_config=autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.SUBSCRIBE_TYPE_ACTIVE, + ssi=self.getname()), + expect_discovery=True, + expect_range=False) + + @test_tracker_info(uuid="6231cb42-91e4-48d3-b9db-b37efbe8537c") + def test_ranged_updated_discovery_solicited_active_sub_oor(self): + """Verify discovery with ranging operation with updated configuration: - Solicited Publish/Active Subscribe - Publisher enables ranging - Subscriber: @@ -895,21 +1004,26 @@ class AwareDiscoveryWithRangingTest(AwareBaseTest, RttBaseTest): Expect: no discovery after update """ - (p_dut, s_dut, p_disc_id, - s_disc_id) = self.run_discovery_prange_sminmax_outofrange(False) - self.run_discovery_update(p_dut, s_dut, p_disc_id, s_disc_id, - p_config=None, # no updates - s_config=autils.add_ranging_to_sub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.SUBSCRIBE_TYPE_ACTIVE, - ssi=self.getname()), - min_distance_mm=100000, - max_distance_mm=100001), - expect_discovery=False) - - @test_tracker_info(uuid="ec999420-6a50-455e-b624-f4c9b4cb7ea5") - def test_ranged_updated_discovery_solicited_active_pub_same(self): - """Verify discovery with ranging operation with updated configuration: + (p_dut, s_dut, p_disc_id, + s_disc_id) = self.run_discovery_prange_sminmax_outofrange(False) + self.run_discovery_update( + p_dut, + s_dut, + p_disc_id, + s_disc_id, + p_config=None, # no updates + s_config=autils.add_ranging_to_sub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.SUBSCRIBE_TYPE_ACTIVE, + ssi=self.getname()), + min_distance_mm=100000, + max_distance_mm=100001), + expect_discovery=False) + + @test_tracker_info(uuid="ec999420-6a50-455e-b624-f4c9b4cb7ea5") + def test_ranged_updated_discovery_solicited_active_pub_same(self): + """Verify discovery with ranging operation with updated configuration: - Solicited Publish/Active Subscribe - Publisher enables ranging - Subscriber: Ranging enabled, min/max such that out of range (min=large, @@ -918,20 +1032,25 @@ class AwareDiscoveryWithRangingTest(AwareBaseTest, RttBaseTest): Expect: no discovery after update """ - (p_dut, s_dut, p_disc_id, - s_disc_id) = self.run_discovery_prange_sminmax_outofrange(False) - self.run_discovery_update(p_dut, s_dut, p_disc_id, s_disc_id, - p_config=autils.add_ranging_to_pub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.PUBLISH_TYPE_SOLICITED, - ssi=self.getname()), - enable_ranging=True), - s_config=None, # no updates - expect_discovery=False) - - @test_tracker_info(uuid="ec6ca57b-f115-4516-813a-4572b930c8d3") - def test_ranged_updated_discovery_solicited_active_multi_step(self): - """Verify discovery with ranging operation with updated configuration: + (p_dut, s_dut, p_disc_id, + s_disc_id) = self.run_discovery_prange_sminmax_outofrange(False) + self.run_discovery_update( + p_dut, + s_dut, + p_disc_id, + s_disc_id, + p_config=autils.add_ranging_to_pub( + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.PUBLISH_TYPE_SOLICITED, + ssi=self.getname()), + enable_ranging=True), + s_config=None, # no updates + expect_discovery=False) + + @test_tracker_info(uuid="ec6ca57b-f115-4516-813a-4572b930c8d3") + def test_ranged_updated_discovery_solicited_active_multi_step(self): + """Verify discovery with ranging operation with updated configuration: - Unsolicited Publish/Passive Subscribe - Publisher enables ranging - Subscriber: Ranging enabled, min/max such that out of range (min=large, @@ -945,40 +1064,55 @@ class AwareDiscoveryWithRangingTest(AwareBaseTest, RttBaseTest): - Reconfigured to: Ranging disabled - Expect: discovery without ranging """ - (p_dut, s_dut, p_disc_id, - s_disc_id) = self.run_discovery_prange_sminmax_outofrange(True) - self.run_discovery_update(p_dut, s_dut, p_disc_id, s_disc_id, - p_config=None, # no updates + (p_dut, s_dut, p_disc_id, + s_disc_id) = self.run_discovery_prange_sminmax_outofrange(True) + self.run_discovery_update( + p_dut, + s_dut, + p_disc_id, + s_disc_id, + p_config=None, # no updates s_config=autils.add_ranging_to_sub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.SUBSCRIBE_TYPE_ACTIVE, - ssi=self.getname()), + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.SUBSCRIBE_TYPE_ACTIVE, + ssi=self.getname()), min_distance_mm=0, max_distance_mm=None), expect_discovery=True, expect_range=True) - self.run_discovery_update(p_dut, s_dut, p_disc_id, s_disc_id, - p_config=None, # no updates + self.run_discovery_update( + p_dut, + s_dut, + p_disc_id, + s_disc_id, + p_config=None, # no updates s_config=autils.add_ranging_to_sub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.SUBSCRIBE_TYPE_ACTIVE, - ssi=self.getname()), + autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.SUBSCRIBE_TYPE_ACTIVE, + ssi=self.getname()), min_distance_mm=1000000, max_distance_mm=None), expect_discovery=False) - self.run_discovery_update(p_dut, s_dut, p_disc_id, s_disc_id, - p_config=None, # no updates - s_config=autils.create_discovery_config(self.SERVICE_NAME, - aconsts.SUBSCRIBE_TYPE_ACTIVE, - ssi=self.getname()), + self.run_discovery_update( + p_dut, + s_dut, + p_disc_id, + s_disc_id, + p_config=None, # no updates + s_config=autils.create_discovery_config( + self.SERVICE_NAME, + aconsts.SUBSCRIBE_TYPE_ACTIVE, + ssi=self.getname()), expect_discovery=True, expect_range=False) - ######################################################################### + ######################################################################### - @test_tracker_info(uuid="6edc47ab-7300-4bff-b7dd-5de83f58928a") - def test_ranged_discovery_multi_session(self): - """Verify behavior with multiple concurrent discovery session with different + @test_tracker_info(uuid="6edc47ab-7300-4bff-b7dd-5de83f58928a") + def test_ranged_discovery_multi_session(self): + """Verify behavior with multiple concurrent discovery session with different configurations: Device A (Publisher): @@ -992,118 +1126,140 @@ class AwareDiscoveryWithRangingTest(AwareBaseTest, RttBaseTest): Subscriber CC: ranging disabled -> match w/o range Subscriber DD: ranging out-of-range -> match w/o range """ - p_dut = self.android_devices[0] - p_dut.pretty_name = "Publisher" - s_dut = self.android_devices[1] - s_dut.pretty_name = "Subscriber" - - # Publisher+Subscriber: attach and wait for confirmation - p_id = p_dut.droid.wifiAwareAttach(False) - autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED) - time.sleep(self.device_startup_offset) - s_id = s_dut.droid.wifiAwareAttach(False) - autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED) - - # Subscriber: start sessions - aa_s_disc_id = s_dut.droid.wifiAwareSubscribe( - s_id, - autils.add_ranging_to_sub( - autils.create_discovery_config("AA", - aconsts.SUBSCRIBE_TYPE_PASSIVE), - min_distance_mm=1000000, max_distance_mm=1000001), - True) - bb_s_disc_id = s_dut.droid.wifiAwareSubscribe( - s_id, - autils.add_ranging_to_sub( - autils.create_discovery_config("BB", - aconsts.SUBSCRIBE_TYPE_PASSIVE), - min_distance_mm=0, max_distance_mm=1000000), - True) - cc_s_disc_id = s_dut.droid.wifiAwareSubscribe( - s_id, - autils.create_discovery_config("CC", aconsts.SUBSCRIBE_TYPE_PASSIVE), - True) - dd_s_disc_id = s_dut.droid.wifiAwareSubscribe( - s_id, - autils.add_ranging_to_sub( - autils.create_discovery_config("DD", - aconsts.SUBSCRIBE_TYPE_PASSIVE), - min_distance_mm=1000000, max_distance_mm=1000001), - True) - - autils.wait_for_event(s_dut, autils.decorate_event( - aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, aa_s_disc_id)) - autils.wait_for_event(s_dut, autils.decorate_event( - aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, bb_s_disc_id)) - autils.wait_for_event(s_dut, autils.decorate_event( - aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, cc_s_disc_id)) - autils.wait_for_event(s_dut, autils.decorate_event( - aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, dd_s_disc_id)) - - # Publisher: start sessions - aa_p_disc_id = p_dut.droid.wifiAwarePublish( - p_id, - autils.add_ranging_to_pub( - autils.create_discovery_config("AA", - aconsts.PUBLISH_TYPE_UNSOLICITED), - enable_ranging=True), - True) - bb_p_disc_id = p_dut.droid.wifiAwarePublish( - p_id, - autils.add_ranging_to_pub( - autils.create_discovery_config("BB", - aconsts.PUBLISH_TYPE_UNSOLICITED), - enable_ranging=True), - True) - cc_p_disc_id = p_dut.droid.wifiAwarePublish( - p_id, - autils.add_ranging_to_pub( - autils.create_discovery_config("CC", - aconsts.PUBLISH_TYPE_UNSOLICITED), - enable_ranging=True), - True) - dd_p_disc_id = p_dut.droid.wifiAwarePublish( - p_id, - autils.create_discovery_config("DD", aconsts.PUBLISH_TYPE_UNSOLICITED), - True) - - autils.wait_for_event(p_dut, autils.decorate_event( - aconsts.SESSION_CB_ON_PUBLISH_STARTED, aa_p_disc_id)) - autils.wait_for_event(p_dut, autils.decorate_event( - aconsts.SESSION_CB_ON_PUBLISH_STARTED, bb_p_disc_id)) - autils.wait_for_event(p_dut, autils.decorate_event( - aconsts.SESSION_CB_ON_PUBLISH_STARTED, cc_p_disc_id)) - autils.wait_for_event(p_dut, autils.decorate_event( - aconsts.SESSION_CB_ON_PUBLISH_STARTED, dd_p_disc_id)) - - # Expected and unexpected service discovery - event = autils.wait_for_event(s_dut, autils.decorate_event( - aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, bb_s_disc_id)) - asserts.assert_true(aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], - "Discovery with ranging for BB expected!") - event = autils.wait_for_event(s_dut, autils.decorate_event( - aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, cc_s_disc_id)) - asserts.assert_false( - aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], - "Discovery with ranging for CC NOT expected!") - event = autils.wait_for_event(s_dut, autils.decorate_event( - aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, dd_s_disc_id)) - asserts.assert_false( - aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], - "Discovery with ranging for DD NOT expected!") - autils.fail_on_event(s_dut, autils.decorate_event( - aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, aa_s_disc_id)) - - # (single) sleep for timeout period and then verify that no further events - time.sleep(autils.EVENT_TIMEOUT) - autils.verify_no_more_events(p_dut, timeout=0) - autils.verify_no_more_events(s_dut, timeout=0) - - ######################################################################### - - @test_tracker_info(uuid="deede47f-a54c-46d9-88bb-f4482fbd8470") - def test_ndp_concurrency(self): - """Verify the behavior of Wi-Fi Aware Ranging whenever an NDP is created - + p_dut = self.android_devices[0] + p_dut.pretty_name = "Publisher" + s_dut = self.android_devices[1] + s_dut.pretty_name = "Subscriber" + + # Publisher+Subscriber: attach and wait for confirmation + p_id = p_dut.droid.wifiAwareAttach(False) + autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED) + time.sleep(self.device_startup_offset) + s_id = s_dut.droid.wifiAwareAttach(False) + autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED) + + # Subscriber: start sessions + aa_s_disc_id = s_dut.droid.wifiAwareSubscribe( + s_id, + autils.add_ranging_to_sub( + autils.create_discovery_config("AA", + aconsts.SUBSCRIBE_TYPE_PASSIVE), + min_distance_mm=1000000, + max_distance_mm=1000001), True) + bb_s_disc_id = s_dut.droid.wifiAwareSubscribe( + s_id, + autils.add_ranging_to_sub( + autils.create_discovery_config("BB", + aconsts.SUBSCRIBE_TYPE_PASSIVE), + min_distance_mm=0, + max_distance_mm=1000000), True) + cc_s_disc_id = s_dut.droid.wifiAwareSubscribe( + s_id, + autils.create_discovery_config( + "CC", aconsts.SUBSCRIBE_TYPE_PASSIVE), True) + dd_s_disc_id = s_dut.droid.wifiAwareSubscribe( + s_id, + autils.add_ranging_to_sub( + autils.create_discovery_config("DD", + aconsts.SUBSCRIBE_TYPE_PASSIVE), + min_distance_mm=1000000, + max_distance_mm=1000001), True) + + autils.wait_for_event( + s_dut, + autils.decorate_event(aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, + aa_s_disc_id)) + autils.wait_for_event( + s_dut, + autils.decorate_event(aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, + bb_s_disc_id)) + autils.wait_for_event( + s_dut, + autils.decorate_event(aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, + cc_s_disc_id)) + autils.wait_for_event( + s_dut, + autils.decorate_event(aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, + dd_s_disc_id)) + + # Publisher: start sessions + aa_p_disc_id = p_dut.droid.wifiAwarePublish( + p_id, + autils.add_ranging_to_pub( + autils.create_discovery_config( + "AA", aconsts.PUBLISH_TYPE_UNSOLICITED), + enable_ranging=True), True) + bb_p_disc_id = p_dut.droid.wifiAwarePublish( + p_id, + autils.add_ranging_to_pub( + autils.create_discovery_config( + "BB", aconsts.PUBLISH_TYPE_UNSOLICITED), + enable_ranging=True), True) + cc_p_disc_id = p_dut.droid.wifiAwarePublish( + p_id, + autils.add_ranging_to_pub( + autils.create_discovery_config( + "CC", aconsts.PUBLISH_TYPE_UNSOLICITED), + enable_ranging=True), True) + dd_p_disc_id = p_dut.droid.wifiAwarePublish( + p_id, + autils.create_discovery_config( + "DD", aconsts.PUBLISH_TYPE_UNSOLICITED), True) + + autils.wait_for_event( + p_dut, + autils.decorate_event(aconsts.SESSION_CB_ON_PUBLISH_STARTED, + aa_p_disc_id)) + autils.wait_for_event( + p_dut, + autils.decorate_event(aconsts.SESSION_CB_ON_PUBLISH_STARTED, + bb_p_disc_id)) + autils.wait_for_event( + p_dut, + autils.decorate_event(aconsts.SESSION_CB_ON_PUBLISH_STARTED, + cc_p_disc_id)) + autils.wait_for_event( + p_dut, + autils.decorate_event(aconsts.SESSION_CB_ON_PUBLISH_STARTED, + dd_p_disc_id)) + + # Expected and unexpected service discovery + event = autils.wait_for_event( + s_dut, + autils.decorate_event(aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, + bb_s_disc_id)) + asserts.assert_true( + aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], + "Discovery with ranging for BB expected!") + event = autils.wait_for_event( + s_dut, + autils.decorate_event(aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, + cc_s_disc_id)) + asserts.assert_false( + aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], + "Discovery with ranging for CC NOT expected!") + event = autils.wait_for_event( + s_dut, + autils.decorate_event(aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, + dd_s_disc_id)) + asserts.assert_false( + aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], + "Discovery with ranging for DD NOT expected!") + autils.fail_on_event( + s_dut, + autils.decorate_event(aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, + aa_s_disc_id)) + + # (single) sleep for timeout period and then verify that no further events + time.sleep(autils.EVENT_TIMEOUT) + autils.verify_no_more_events(p_dut, timeout=0) + autils.verify_no_more_events(s_dut, timeout=0) + + ######################################################################### + + @test_tracker_info(uuid="deede47f-a54c-46d9-88bb-f4482fbd8470") + def test_ndp_concurrency(self): + """Verify the behavior of Wi-Fi Aware Ranging whenever an NDP is created - for those devices that have a concurrency limitation that does not allow Aware Ranging, whether direct or as part of discovery. @@ -1135,185 +1291,276 @@ class AwareDiscoveryWithRangingTest(AwareBaseTest, RttBaseTest): Update configuration to be in-range Verify that get match with ranging information """ - p_dut = self.android_devices[0] - p_dut.pretty_name = "Publisher" - s_dut = self.android_devices[1] - s_dut.pretty_name = "Subscriber" - - # Publisher+Subscriber: attach and wait for confirmation - p_id = p_dut.droid.wifiAwareAttach(False) - autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED) - time.sleep(self.device_startup_offset) - s_id = s_dut.droid.wifiAwareAttach(False) - autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED) - - # Publisher: AA w/o ranging, BB w/ ranging, CC w/ ranging, DD w/ ranging - aa_p_id = p_dut.droid.wifiAwarePublish(p_id, - autils.create_discovery_config("AA", aconsts.PUBLISH_TYPE_SOLICITED), - True) - autils.wait_for_event(p_dut, autils.decorate_event( - aconsts.SESSION_CB_ON_PUBLISH_STARTED, aa_p_id)) - bb_p_id = p_dut.droid.wifiAwarePublish(p_id, autils.add_ranging_to_pub( - autils.create_discovery_config("BB", aconsts.PUBLISH_TYPE_UNSOLICITED), - enable_ranging=True), True) - autils.wait_for_event(p_dut, autils.decorate_event( - aconsts.SESSION_CB_ON_PUBLISH_STARTED, bb_p_id)) - cc_p_id = p_dut.droid.wifiAwarePublish(p_id, autils.add_ranging_to_pub( - autils.create_discovery_config("CC", aconsts.PUBLISH_TYPE_UNSOLICITED), - enable_ranging=True), True) - autils.wait_for_event(p_dut, autils.decorate_event( - aconsts.SESSION_CB_ON_PUBLISH_STARTED, cc_p_id)) - dd_p_id = p_dut.droid.wifiAwarePublish(p_id, autils.add_ranging_to_pub( - autils.create_discovery_config("DD", aconsts.PUBLISH_TYPE_UNSOLICITED), - enable_ranging=True), True) - autils.wait_for_event(p_dut, autils.decorate_event( - aconsts.SESSION_CB_ON_PUBLISH_STARTED, dd_p_id)) - - # Subscriber: AA w/o ranging, BB w/ranging out-of-range, - # DD w /ranging in-range - aa_s_id = s_dut.droid.wifiAwareSubscribe(s_id, - autils.create_discovery_config("AA", aconsts.SUBSCRIBE_TYPE_ACTIVE), - True) - autils.wait_for_event(s_dut, autils.decorate_event( - aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, aa_s_id)) - bb_s_id = s_dut.droid.wifiAwareSubscribe(s_id, autils.add_ranging_to_sub( - autils.create_discovery_config("BB", aconsts.SUBSCRIBE_TYPE_PASSIVE), - min_distance_mm=1000000, max_distance_mm=1000001), True) - autils.wait_for_event(s_dut, autils.decorate_event( - aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, bb_s_id)) - dd_s_id = s_dut.droid.wifiAwareSubscribe(s_id, autils.add_ranging_to_sub( - autils.create_discovery_config("DD", aconsts.SUBSCRIBE_TYPE_PASSIVE), - min_distance_mm=None, max_distance_mm=1000000), True) - autils.wait_for_event(s_dut, autils.decorate_event( - aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, dd_s_id)) - - # verify: AA discovered, BB not discovered, DD discovery w/range - event = autils.wait_for_event(s_dut, autils.decorate_event( - aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, aa_s_id)) - asserts.assert_false(aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], - "Discovery with ranging for AA NOT expected!") - aa_peer_id_on_sub = event['data'][aconsts.SESSION_CB_KEY_PEER_ID] - autils.fail_on_event(s_dut, autils.decorate_event( - aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, bb_s_id)) - event = autils.wait_for_event(s_dut, autils.decorate_event( - aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, dd_s_id)) - asserts.assert_true(aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], - "Discovery with ranging for DD expected!") - - # start NDP in context of AA: - - # Publisher: request network (from ANY) - p_req_key = autils.request_network(p_dut, - p_dut.droid.wifiAwareCreateNetworkSpecifier(aa_p_id, None)) - - # Subscriber: request network - s_req_key = autils.request_network(s_dut, - s_dut.droid.wifiAwareCreateNetworkSpecifier(aa_s_id, aa_peer_id_on_sub)) - - # Publisher & Subscriber: wait for network formation - p_net_event = autils.wait_for_event_with_keys(p_dut, - cconsts.EVENT_NETWORK_CALLBACK, - autils.EVENT_TIMEOUT, ( - cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, - p_req_key)) - s_net_event = autils.wait_for_event_with_keys(s_dut, - cconsts.EVENT_NETWORK_CALLBACK, - autils.EVENT_TIMEOUT, ( - cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, - s_req_key)) - - p_aware_if = p_net_event["data"][cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - s_aware_if = s_net_event["data"][cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - - p_ipv6 = p_dut.droid.connectivityGetLinkLocalIpv6Address(p_aware_if).split( - "%")[0] - s_ipv6 = s_dut.droid.connectivityGetLinkLocalIpv6Address(s_aware_if).split( - "%")[0] - - self.log.info("AA NDP Interface names: P=%s, S=%s", p_aware_if, s_aware_if) - self.log.info("AA NDP Interface addresses (IPv6): P=%s, S=%s", p_ipv6, - s_ipv6) - - if self.RANGING_NDP_CONCURRENCY_LIMITATION: - # Expect BB to now discover w/o ranging - event = autils.wait_for_event(s_dut, autils.decorate_event( - aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, bb_s_id)) - asserts.assert_false(aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], - "Discovery with ranging for BB NOT expected!") - - # Publishers: EE, FF w/ ranging - ee_p_id = p_dut.droid.wifiAwarePublish(p_id, autils.add_ranging_to_pub( - autils.create_discovery_config("EE", aconsts.PUBLISH_TYPE_SOLICITED), - enable_ranging=True), True) - autils.wait_for_event(p_dut, autils.decorate_event( - aconsts.SESSION_CB_ON_PUBLISH_STARTED, ee_p_id)) - ff_p_id = p_dut.droid.wifiAwarePublish(p_id, autils.add_ranging_to_pub( - autils.create_discovery_config("FF", aconsts.PUBLISH_TYPE_UNSOLICITED), - enable_ranging=True), True) - autils.wait_for_event(p_dut, autils.decorate_event( - aconsts.SESSION_CB_ON_PUBLISH_STARTED, ff_p_id)) - - # Subscribers: EE out-of-range, FF in-range - ee_s_id = s_dut.droid.wifiAwareSubscribe(s_id, autils.add_ranging_to_sub( - autils.create_discovery_config("EE", aconsts.SUBSCRIBE_TYPE_ACTIVE), - min_distance_mm=1000000, max_distance_mm=1000001), True) - autils.wait_for_event(s_dut, autils.decorate_event( - aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, ee_s_id)) - ff_s_id = s_dut.droid.wifiAwareSubscribe(s_id, autils.add_ranging_to_sub( - autils.create_discovery_config("FF", aconsts.SUBSCRIBE_TYPE_PASSIVE), - min_distance_mm=None, max_distance_mm=1000000), True) - autils.wait_for_event(s_dut, autils.decorate_event( - aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, ff_s_id)) - - if self.RANGING_NDP_CONCURRENCY_LIMITATION: - # Expect EE & FF discovery w/o range - event = autils.wait_for_event(s_dut, autils.decorate_event( - aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, ee_s_id)) - asserts.assert_false(aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], - "Discovery with ranging for EE NOT expected!") - event = autils.wait_for_event(s_dut, autils.decorate_event( - aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, ff_s_id)) - asserts.assert_false(aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], - "Discovery with ranging for FF NOT expected!") - else: - event = autils.wait_for_event(s_dut, autils.decorate_event( - aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, ff_s_id)) - asserts.assert_true(aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], - "Discovery with ranging for FF expected!") - - # tear down NDP - p_dut.droid.connectivityUnregisterNetworkCallback(p_req_key) - s_dut.droid.connectivityUnregisterNetworkCallback(s_req_key) - - time.sleep(5) # give time for NDP termination to finish - - # Subscriber: start CC out-of-range - no discovery expected! - cc_s_id = s_dut.droid.wifiAwareSubscribe(s_id, autils.add_ranging_to_sub( - autils.create_discovery_config("CC", aconsts.SUBSCRIBE_TYPE_PASSIVE), - min_distance_mm=1000000, max_distance_mm=1000001), True) - autils.wait_for_event(s_dut, autils.decorate_event( - aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, cc_s_id)) - autils.fail_on_event(s_dut, autils.decorate_event( - aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, cc_s_id)) - - # Subscriber: modify CC to in-range - expect discovery w/ range - s_dut.droid.wifiAwareUpdateSubscribe(cc_s_id, autils.add_ranging_to_sub( - autils.create_discovery_config("CC", aconsts.SUBSCRIBE_TYPE_PASSIVE), - min_distance_mm=None, max_distance_mm=1000001)) - autils.wait_for_event(s_dut, autils.decorate_event( - aconsts.SESSION_CB_ON_SESSION_CONFIG_UPDATED, cc_s_id)) - event = autils.wait_for_event(s_dut, autils.decorate_event( - aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, cc_s_id)) - asserts.assert_true(aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], - "Discovery with ranging for CC expected!") - - @test_tracker_info(uuid="d94dac91-4090-4c03-a867-6dfac6558ba3") - def test_role_concurrency(self): - """Verify the behavior of Wi-Fi Aware Ranging (in the context of discovery) + p_dut = self.android_devices[0] + p_dut.pretty_name = "Publisher" + s_dut = self.android_devices[1] + s_dut.pretty_name = "Subscriber" + + # Publisher+Subscriber: attach and wait for confirmation + p_id = p_dut.droid.wifiAwareAttach(False) + autils.wait_for_event(p_dut, aconsts.EVENT_CB_ON_ATTACHED) + time.sleep(self.device_startup_offset) + s_id = s_dut.droid.wifiAwareAttach(False) + autils.wait_for_event(s_dut, aconsts.EVENT_CB_ON_ATTACHED) + + # Publisher: AA w/o ranging, BB w/ ranging, CC w/ ranging, DD w/ ranging + aa_p_id = p_dut.droid.wifiAwarePublish( + p_id, + autils.create_discovery_config( + "AA", aconsts.PUBLISH_TYPE_SOLICITED), True) + autils.wait_for_event( + p_dut, + autils.decorate_event(aconsts.SESSION_CB_ON_PUBLISH_STARTED, + aa_p_id)) + bb_p_id = p_dut.droid.wifiAwarePublish( + p_id, + autils.add_ranging_to_pub( + autils.create_discovery_config( + "BB", aconsts.PUBLISH_TYPE_UNSOLICITED), + enable_ranging=True), True) + autils.wait_for_event( + p_dut, + autils.decorate_event(aconsts.SESSION_CB_ON_PUBLISH_STARTED, + bb_p_id)) + cc_p_id = p_dut.droid.wifiAwarePublish( + p_id, + autils.add_ranging_to_pub( + autils.create_discovery_config( + "CC", aconsts.PUBLISH_TYPE_UNSOLICITED), + enable_ranging=True), True) + autils.wait_for_event( + p_dut, + autils.decorate_event(aconsts.SESSION_CB_ON_PUBLISH_STARTED, + cc_p_id)) + dd_p_id = p_dut.droid.wifiAwarePublish( + p_id, + autils.add_ranging_to_pub( + autils.create_discovery_config( + "DD", aconsts.PUBLISH_TYPE_UNSOLICITED), + enable_ranging=True), True) + autils.wait_for_event( + p_dut, + autils.decorate_event(aconsts.SESSION_CB_ON_PUBLISH_STARTED, + dd_p_id)) + + # Subscriber: AA w/o ranging, BB w/ranging out-of-range, + # DD w /ranging in-range + aa_s_id = s_dut.droid.wifiAwareSubscribe( + s_id, + autils.create_discovery_config( + "AA", aconsts.SUBSCRIBE_TYPE_ACTIVE), True) + autils.wait_for_event( + s_dut, + autils.decorate_event(aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, + aa_s_id)) + bb_s_id = s_dut.droid.wifiAwareSubscribe( + s_id, + autils.add_ranging_to_sub( + autils.create_discovery_config("BB", + aconsts.SUBSCRIBE_TYPE_PASSIVE), + min_distance_mm=1000000, + max_distance_mm=1000001), True) + autils.wait_for_event( + s_dut, + autils.decorate_event(aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, + bb_s_id)) + dd_s_id = s_dut.droid.wifiAwareSubscribe( + s_id, + autils.add_ranging_to_sub( + autils.create_discovery_config("DD", + aconsts.SUBSCRIBE_TYPE_PASSIVE), + min_distance_mm=None, + max_distance_mm=1000000), True) + autils.wait_for_event( + s_dut, + autils.decorate_event(aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, + dd_s_id)) + + # verify: AA discovered, BB not discovered, DD discovery w/range + event = autils.wait_for_event( + s_dut, + autils.decorate_event(aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, + aa_s_id)) + asserts.assert_false( + aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], + "Discovery with ranging for AA NOT expected!") + aa_peer_id_on_sub = event['data'][aconsts.SESSION_CB_KEY_PEER_ID] + autils.fail_on_event( + s_dut, + autils.decorate_event(aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, + bb_s_id)) + event = autils.wait_for_event( + s_dut, + autils.decorate_event(aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, + dd_s_id)) + asserts.assert_true( + aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], + "Discovery with ranging for DD expected!") + + # start NDP in context of AA: + + # Publisher: request network (from ANY) + p_req_key = autils.request_network( + p_dut, p_dut.droid.wifiAwareCreateNetworkSpecifier(aa_p_id, None)) + + # Subscriber: request network + s_req_key = autils.request_network( + s_dut, + s_dut.droid.wifiAwareCreateNetworkSpecifier( + aa_s_id, aa_peer_id_on_sub)) + + # Publisher & Subscriber: wait for network formation + p_net_event = autils.wait_for_event_with_keys( + p_dut, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_TIMEOUT, + (cconsts.NETWORK_CB_KEY_EVENT, + cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), + (cconsts.NETWORK_CB_KEY_ID, p_req_key)) + s_net_event = autils.wait_for_event_with_keys( + s_dut, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_TIMEOUT, + (cconsts.NETWORK_CB_KEY_EVENT, + cconsts.NETWORK_CB_LINK_PROPERTIES_CHANGED), + (cconsts.NETWORK_CB_KEY_ID, s_req_key)) + + p_aware_if = p_net_event["data"][cconsts.NETWORK_CB_KEY_INTERFACE_NAME] + s_aware_if = s_net_event["data"][cconsts.NETWORK_CB_KEY_INTERFACE_NAME] + + p_ipv6 = p_dut.droid.connectivityGetLinkLocalIpv6Address( + p_aware_if).split("%")[0] + s_ipv6 = s_dut.droid.connectivityGetLinkLocalIpv6Address( + s_aware_if).split("%")[0] + + self.log.info("AA NDP Interface names: P=%s, S=%s", p_aware_if, + s_aware_if) + self.log.info("AA NDP Interface addresses (IPv6): P=%s, S=%s", p_ipv6, + s_ipv6) + + if self.RANGING_NDP_CONCURRENCY_LIMITATION: + # Expect BB to now discover w/o ranging + event = autils.wait_for_event( + s_dut, + autils.decorate_event(aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, + bb_s_id)) + asserts.assert_false( + aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], + "Discovery with ranging for BB NOT expected!") + + # Publishers: EE, FF w/ ranging + ee_p_id = p_dut.droid.wifiAwarePublish( + p_id, + autils.add_ranging_to_pub( + autils.create_discovery_config("EE", + aconsts.PUBLISH_TYPE_SOLICITED), + enable_ranging=True), True) + autils.wait_for_event( + p_dut, + autils.decorate_event(aconsts.SESSION_CB_ON_PUBLISH_STARTED, + ee_p_id)) + ff_p_id = p_dut.droid.wifiAwarePublish( + p_id, + autils.add_ranging_to_pub( + autils.create_discovery_config( + "FF", aconsts.PUBLISH_TYPE_UNSOLICITED), + enable_ranging=True), True) + autils.wait_for_event( + p_dut, + autils.decorate_event(aconsts.SESSION_CB_ON_PUBLISH_STARTED, + ff_p_id)) + + # Subscribers: EE out-of-range, FF in-range + ee_s_id = s_dut.droid.wifiAwareSubscribe( + s_id, + autils.add_ranging_to_sub( + autils.create_discovery_config("EE", + aconsts.SUBSCRIBE_TYPE_ACTIVE), + min_distance_mm=1000000, + max_distance_mm=1000001), True) + autils.wait_for_event( + s_dut, + autils.decorate_event(aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, + ee_s_id)) + ff_s_id = s_dut.droid.wifiAwareSubscribe( + s_id, + autils.add_ranging_to_sub( + autils.create_discovery_config("FF", + aconsts.SUBSCRIBE_TYPE_PASSIVE), + min_distance_mm=None, + max_distance_mm=1000000), True) + autils.wait_for_event( + s_dut, + autils.decorate_event(aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, + ff_s_id)) + + if self.RANGING_NDP_CONCURRENCY_LIMITATION: + # Expect EE & FF discovery w/o range + event = autils.wait_for_event( + s_dut, + autils.decorate_event(aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, + ee_s_id)) + asserts.assert_false( + aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], + "Discovery with ranging for EE NOT expected!") + event = autils.wait_for_event( + s_dut, + autils.decorate_event(aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, + ff_s_id)) + asserts.assert_false( + aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], + "Discovery with ranging for FF NOT expected!") + else: + event = autils.wait_for_event( + s_dut, + autils.decorate_event(aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, + ff_s_id)) + asserts.assert_true( + aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], + "Discovery with ranging for FF expected!") + + # tear down NDP + p_dut.droid.connectivityUnregisterNetworkCallback(p_req_key) + s_dut.droid.connectivityUnregisterNetworkCallback(s_req_key) + + time.sleep(5) # give time for NDP termination to finish + + # Subscriber: start CC out-of-range - no discovery expected! + cc_s_id = s_dut.droid.wifiAwareSubscribe( + s_id, + autils.add_ranging_to_sub( + autils.create_discovery_config("CC", + aconsts.SUBSCRIBE_TYPE_PASSIVE), + min_distance_mm=1000000, + max_distance_mm=1000001), True) + autils.wait_for_event( + s_dut, + autils.decorate_event(aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, + cc_s_id)) + autils.fail_on_event( + s_dut, + autils.decorate_event(aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, + cc_s_id)) + + # Subscriber: modify CC to in-range - expect discovery w/ range + s_dut.droid.wifiAwareUpdateSubscribe( + cc_s_id, + autils.add_ranging_to_sub( + autils.create_discovery_config("CC", + aconsts.SUBSCRIBE_TYPE_PASSIVE), + min_distance_mm=None, + max_distance_mm=1000001)) + autils.wait_for_event( + s_dut, + autils.decorate_event(aconsts.SESSION_CB_ON_SESSION_CONFIG_UPDATED, + cc_s_id)) + event = autils.wait_for_event( + s_dut, + autils.decorate_event(aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, + cc_s_id)) + asserts.assert_true( + aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], + "Discovery with ranging for CC expected!") + + @test_tracker_info(uuid="d94dac91-4090-4c03-a867-6dfac6558ba3") + def test_role_concurrency(self): + """Verify the behavior of Wi-Fi Aware Ranging (in the context of discovery) when the device has concurrency limitations which do not permit concurrent Initiator and Responder roles on the same device. In such case it is expected that normal discovery without ranging is executed AND that ranging @@ -1345,128 +1592,201 @@ class AwareDiscoveryWithRangingTest(AwareBaseTest, RttBaseTest): DUT2: Start Publish FF w/ ranging (solicited) DUT1: expect FF w/ ranging information - should finally be back up """ - dut1 = self.android_devices[0] - dut1.pretty_name = "DUT1" - dut2 = self.android_devices[1] - dut2.pretty_name = "DUT2" - - # Publisher+Subscriber: attach and wait for confirmation - dut1_id = dut1.droid.wifiAwareAttach(False) - autils.wait_for_event(dut1, aconsts.EVENT_CB_ON_ATTACHED) - time.sleep(self.device_startup_offset) - dut2_id = dut2.droid.wifiAwareAttach(False) - autils.wait_for_event(dut2, aconsts.EVENT_CB_ON_ATTACHED) - - # DUT1: initial service bringup - aa_p_id = dut1.droid.wifiAwarePublish(dut1_id, autils.add_ranging_to_pub( - autils.create_discovery_config("AA", aconsts.PUBLISH_TYPE_UNSOLICITED), - enable_ranging=True), True) - autils.wait_for_event(dut1, autils.decorate_event( - aconsts.SESSION_CB_ON_PUBLISH_STARTED, aa_p_id)) - bb_s_id = dut1.droid.wifiAwareSubscribe(dut1_id, autils.add_ranging_to_sub( - autils.create_discovery_config("BB", aconsts.SUBSCRIBE_TYPE_ACTIVE), - min_distance_mm=None, max_distance_mm=1000000), True) - autils.wait_for_event(dut1, autils.decorate_event( - aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, bb_s_id)) - cc_p_id = dut1.droid.wifiAwarePublish(dut1_id, autils.add_ranging_to_pub( - autils.create_discovery_config("CC", aconsts.PUBLISH_TYPE_UNSOLICITED), - enable_ranging=True), True) - autils.wait_for_event(dut1, autils.decorate_event( - aconsts.SESSION_CB_ON_PUBLISH_STARTED, cc_p_id)) - dd_p_id = dut1.droid.wifiAwarePublish(dut1_id, - autils.create_discovery_config("DD", aconsts.PUBLISH_TYPE_SOLICITED), - True) - autils.wait_for_event(dut1, autils.decorate_event( - aconsts.SESSION_CB_ON_PUBLISH_STARTED, dd_p_id)) - ee_s_id = dut1.droid.wifiAwareSubscribe(dut1_id, autils.add_ranging_to_sub( - autils.create_discovery_config("EE", aconsts.SUBSCRIBE_TYPE_PASSIVE), - min_distance_mm=None, max_distance_mm=1000000), True) - autils.wait_for_event(dut1, autils.decorate_event( - aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, ee_s_id)) - ff_s_id = dut1.droid.wifiAwareSubscribe(dut1_id, autils.add_ranging_to_sub( - autils.create_discovery_config("FF", aconsts.SUBSCRIBE_TYPE_ACTIVE), - min_distance_mm=None, max_distance_mm=1000000), True) - autils.wait_for_event(dut1, autils.decorate_event( - aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, ff_s_id)) - - # DUT2: initial service bringup - aa_s_id = dut2.droid.wifiAwareSubscribe(dut2_id, autils.add_ranging_to_sub( - autils.create_discovery_config("AA", aconsts.SUBSCRIBE_TYPE_PASSIVE), - min_distance_mm=None, max_distance_mm=1000000), True) - autils.wait_for_event(dut2, autils.decorate_event( - aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, aa_s_id)) - bb_p_id = dut2.droid.wifiAwarePublish(dut2_id, autils.add_ranging_to_pub( - autils.create_discovery_config("BB", aconsts.PUBLISH_TYPE_SOLICITED), - enable_ranging=True), True) - autils.wait_for_event(dut2, autils.decorate_event( - aconsts.SESSION_CB_ON_PUBLISH_STARTED, bb_p_id)) - dd_s_id = dut2.droid.wifiAwareSubscribe(dut2_id, - autils.create_discovery_config("AA", aconsts.SUBSCRIBE_TYPE_ACTIVE), - True) - autils.wait_for_event(dut2, autils.decorate_event( - aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, dd_s_id)) - - # Initial set of discovery events for AA, BB, and DD (which are up) - event = autils.wait_for_event(dut2, autils.decorate_event( - aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, aa_s_id)) - asserts.assert_true(aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], - "Discovery with ranging for AA expected!") - event = autils.wait_for_event(dut1, autils.decorate_event( - aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, bb_s_id)) - if self.RANGING_INITIATOR_RESPONDER_CONCURRENCY_LIMITATION: - asserts.assert_false(aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], - "Discovery with ranging for BB NOT expected!") - else: - asserts.assert_true(aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], - "Discovery with ranging for BB expected!") - event = autils.wait_for_event(dut2, autils.decorate_event( - aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, dd_s_id)) - asserts.assert_false(aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], - "Discovery with ranging for DD NOT expected!") - - # DUT1/DUT2: terminate AA - dut1.droid.wifiAwareDestroyDiscoverySession(aa_p_id) - dut2.droid.wifiAwareDestroyDiscoverySession(aa_s_id) - - time.sleep(5) # guarantee that session terminated (and host recovered?) - - # DUT2: try EE service - ranging still disabled - ee_p_id = dut2.droid.wifiAwarePublish(dut2_id, autils.add_ranging_to_pub( - autils.create_discovery_config("EE", aconsts.PUBLISH_TYPE_UNSOLICITED), - enable_ranging=True), True) - autils.wait_for_event(dut2, autils.decorate_event( - aconsts.SESSION_CB_ON_PUBLISH_STARTED, ee_p_id)) - - event = autils.wait_for_event(dut1, autils.decorate_event( - aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, ee_s_id)) - if self.RANGING_INITIATOR_RESPONDER_CONCURRENCY_LIMITATION: - asserts.assert_false(aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], - "Discovery with ranging for EE NOT expected!") - else: - asserts.assert_true(aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], - "Discovery with ranging for EE expected!") - - # DUT1: terminate CC - last publish w/ ranging on DUT! - dut1.droid.wifiAwareDestroyDiscoverySession(cc_p_id) - - time.sleep(5) # guarantee that session terminated (and host recovered?) - - # DUT2: try FF service - ranging should now function - ff_p_id = dut2.droid.wifiAwarePublish(dut2_id, autils.add_ranging_to_pub( - autils.create_discovery_config("FF", aconsts.PUBLISH_TYPE_SOLICITED), - enable_ranging=True), True) - autils.wait_for_event(dut2, autils.decorate_event( - aconsts.SESSION_CB_ON_PUBLISH_STARTED, ff_p_id)) - - event = autils.wait_for_event(dut1, autils.decorate_event( - aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, ff_s_id)) - asserts.assert_true(aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], - "Discovery with ranging for FF expected!") - - - @test_tracker_info(uuid="6700eab8-a172-43cd-aed3-e6577ce8fd89") - def test_discovery_direct_concurrency(self): - """Verify the behavior of Wi-Fi Aware Ranging used as part of discovery and + dut1 = self.android_devices[0] + dut1.pretty_name = "DUT1" + dut2 = self.android_devices[1] + dut2.pretty_name = "DUT2" + + # Publisher+Subscriber: attach and wait for confirmation + dut1_id = dut1.droid.wifiAwareAttach(False) + autils.wait_for_event(dut1, aconsts.EVENT_CB_ON_ATTACHED) + time.sleep(self.device_startup_offset) + dut2_id = dut2.droid.wifiAwareAttach(False) + autils.wait_for_event(dut2, aconsts.EVENT_CB_ON_ATTACHED) + + # DUT1: initial service bringup + aa_p_id = dut1.droid.wifiAwarePublish( + dut1_id, + autils.add_ranging_to_pub( + autils.create_discovery_config( + "AA", aconsts.PUBLISH_TYPE_UNSOLICITED), + enable_ranging=True), True) + autils.wait_for_event( + dut1, + autils.decorate_event(aconsts.SESSION_CB_ON_PUBLISH_STARTED, + aa_p_id)) + bb_s_id = dut1.droid.wifiAwareSubscribe( + dut1_id, + autils.add_ranging_to_sub( + autils.create_discovery_config("BB", + aconsts.SUBSCRIBE_TYPE_ACTIVE), + min_distance_mm=None, + max_distance_mm=1000000), True) + autils.wait_for_event( + dut1, + autils.decorate_event(aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, + bb_s_id)) + cc_p_id = dut1.droid.wifiAwarePublish( + dut1_id, + autils.add_ranging_to_pub( + autils.create_discovery_config( + "CC", aconsts.PUBLISH_TYPE_UNSOLICITED), + enable_ranging=True), True) + autils.wait_for_event( + dut1, + autils.decorate_event(aconsts.SESSION_CB_ON_PUBLISH_STARTED, + cc_p_id)) + dd_p_id = dut1.droid.wifiAwarePublish( + dut1_id, + autils.create_discovery_config( + "DD", aconsts.PUBLISH_TYPE_SOLICITED), True) + autils.wait_for_event( + dut1, + autils.decorate_event(aconsts.SESSION_CB_ON_PUBLISH_STARTED, + dd_p_id)) + ee_s_id = dut1.droid.wifiAwareSubscribe( + dut1_id, + autils.add_ranging_to_sub( + autils.create_discovery_config("EE", + aconsts.SUBSCRIBE_TYPE_PASSIVE), + min_distance_mm=None, + max_distance_mm=1000000), True) + autils.wait_for_event( + dut1, + autils.decorate_event(aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, + ee_s_id)) + ff_s_id = dut1.droid.wifiAwareSubscribe( + dut1_id, + autils.add_ranging_to_sub( + autils.create_discovery_config("FF", + aconsts.SUBSCRIBE_TYPE_ACTIVE), + min_distance_mm=None, + max_distance_mm=1000000), True) + autils.wait_for_event( + dut1, + autils.decorate_event(aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, + ff_s_id)) + + # DUT2: initial service bringup + aa_s_id = dut2.droid.wifiAwareSubscribe( + dut2_id, + autils.add_ranging_to_sub( + autils.create_discovery_config("AA", + aconsts.SUBSCRIBE_TYPE_PASSIVE), + min_distance_mm=None, + max_distance_mm=1000000), True) + autils.wait_for_event( + dut2, + autils.decorate_event(aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, + aa_s_id)) + bb_p_id = dut2.droid.wifiAwarePublish( + dut2_id, + autils.add_ranging_to_pub( + autils.create_discovery_config("BB", + aconsts.PUBLISH_TYPE_SOLICITED), + enable_ranging=True), True) + autils.wait_for_event( + dut2, + autils.decorate_event(aconsts.SESSION_CB_ON_PUBLISH_STARTED, + bb_p_id)) + dd_s_id = dut2.droid.wifiAwareSubscribe( + dut2_id, + autils.create_discovery_config( + "AA", aconsts.SUBSCRIBE_TYPE_ACTIVE), True) + autils.wait_for_event( + dut2, + autils.decorate_event(aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, + dd_s_id)) + + # Initial set of discovery events for AA, BB, and DD (which are up) + event = autils.wait_for_event( + dut2, + autils.decorate_event(aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, + aa_s_id)) + asserts.assert_true( + aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], + "Discovery with ranging for AA expected!") + event = autils.wait_for_event( + dut1, + autils.decorate_event(aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, + bb_s_id)) + if self.RANGING_INITIATOR_RESPONDER_CONCURRENCY_LIMITATION: + asserts.assert_false( + aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], + "Discovery with ranging for BB NOT expected!") + else: + asserts.assert_true( + aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], + "Discovery with ranging for BB expected!") + event = autils.wait_for_event( + dut2, + autils.decorate_event(aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, + dd_s_id)) + asserts.assert_false( + aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], + "Discovery with ranging for DD NOT expected!") + + # DUT1/DUT2: terminate AA + dut1.droid.wifiAwareDestroyDiscoverySession(aa_p_id) + dut2.droid.wifiAwareDestroyDiscoverySession(aa_s_id) + + time.sleep( + 5) # guarantee that session terminated (and host recovered?) + + # DUT2: try EE service - ranging still disabled + ee_p_id = dut2.droid.wifiAwarePublish( + dut2_id, + autils.add_ranging_to_pub( + autils.create_discovery_config( + "EE", aconsts.PUBLISH_TYPE_UNSOLICITED), + enable_ranging=True), True) + autils.wait_for_event( + dut2, + autils.decorate_event(aconsts.SESSION_CB_ON_PUBLISH_STARTED, + ee_p_id)) + + event = autils.wait_for_event( + dut1, + autils.decorate_event(aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, + ee_s_id)) + if self.RANGING_INITIATOR_RESPONDER_CONCURRENCY_LIMITATION: + asserts.assert_false( + aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], + "Discovery with ranging for EE NOT expected!") + else: + asserts.assert_true( + aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], + "Discovery with ranging for EE expected!") + + # DUT1: terminate CC - last publish w/ ranging on DUT! + dut1.droid.wifiAwareDestroyDiscoverySession(cc_p_id) + + time.sleep( + 5) # guarantee that session terminated (and host recovered?) + + # DUT2: try FF service - ranging should now function + ff_p_id = dut2.droid.wifiAwarePublish( + dut2_id, + autils.add_ranging_to_pub( + autils.create_discovery_config("FF", + aconsts.PUBLISH_TYPE_SOLICITED), + enable_ranging=True), True) + autils.wait_for_event( + dut2, + autils.decorate_event(aconsts.SESSION_CB_ON_PUBLISH_STARTED, + ff_p_id)) + + event = autils.wait_for_event( + dut1, + autils.decorate_event(aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, + ff_s_id)) + asserts.assert_true( + aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], + "Discovery with ranging for FF expected!") + + @test_tracker_info(uuid="6700eab8-a172-43cd-aed3-e6577ce8fd89") + def test_discovery_direct_concurrency(self): + """Verify the behavior of Wi-Fi Aware Ranging used as part of discovery and as direct ranging to a peer device. Process: @@ -1477,91 +1797,136 @@ class AwareDiscoveryWithRangingTest(AwareBaseTest, RttBaseTest): - Keep performing direct Ranging in context of YYY - Stop direct Ranging and look for XXX to discover """ - dut1 = self.android_devices[0] - dut1.pretty_name = "DUT1" - dut2 = self.android_devices[1] - dut2.pretty_name = "DUT2" - - # DUTs: attach and wait for confirmation - dut1_id = dut1.droid.wifiAwareAttach(False) - autils.wait_for_event(dut1, aconsts.EVENT_CB_ON_ATTACHED) - time.sleep(self.device_startup_offset) - dut2_id = dut2.droid.wifiAwareAttach(True) - event = autils.wait_for_event(dut2, aconsts.EVENT_CB_ON_IDENTITY_CHANGED) - dut2_mac = event['data']['mac'] - - # DUT1: publishers bring-up - xxx_p_id = dut1.droid.wifiAwarePublish(dut1_id, autils.add_ranging_to_pub( - autils.create_discovery_config("XXX", aconsts.PUBLISH_TYPE_UNSOLICITED), - enable_ranging=True), True) - autils.wait_for_event(dut1, autils.decorate_event( - aconsts.SESSION_CB_ON_PUBLISH_STARTED, xxx_p_id)) - yyy_p_id = dut1.droid.wifiAwarePublish(dut1_id, autils.add_ranging_to_pub( - autils.create_discovery_config("YYY", aconsts.PUBLISH_TYPE_UNSOLICITED), - enable_ranging=True), True) - autils.wait_for_event(dut1, autils.decorate_event( - aconsts.SESSION_CB_ON_PUBLISH_STARTED, yyy_p_id)) - - # DUT2: subscribers bring-up - xxx_s_id = dut2.droid.wifiAwareSubscribe(dut2_id, autils.add_ranging_to_sub( - autils.create_discovery_config("XXX", aconsts.SUBSCRIBE_TYPE_PASSIVE), - min_distance_mm=1000000, max_distance_mm=1000001), True) - autils.wait_for_event(dut2, autils.decorate_event( - aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, xxx_s_id)) - yyy_s_id = dut2.droid.wifiAwareSubscribe(dut2_id, autils.add_ranging_to_sub( - autils.create_discovery_config("YYY", aconsts.SUBSCRIBE_TYPE_PASSIVE), - min_distance_mm=None, max_distance_mm=1000000), True) - autils.wait_for_event(dut2, autils.decorate_event( - aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, yyy_s_id)) - - # Service discovery: YYY (with range info), but no XXX - event = autils.wait_for_event(dut2, autils.decorate_event( - aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, yyy_s_id)) - asserts.assert_true(aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], - "Discovery with ranging for YYY expected!") - yyy_peer_id_on_sub = event['data'][aconsts.SESSION_CB_KEY_PEER_ID] - - autils.fail_on_event(dut2, autils.decorate_event( - aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, xxx_s_id)) - - # Direct ranging - results21 = [] - for iter in range(10): - id = dut2.droid.wifiRttStartRangingToAwarePeerId(yyy_peer_id_on_sub) - event = autils.wait_for_event(dut2, rutils.decorate_event( - rconsts.EVENT_CB_RANGING_ON_RESULT, id)) - results21.append(event["data"][rconsts.EVENT_CB_RANGING_KEY_RESULTS][0]) - - time.sleep(5) # while switching roles - - results12 = [] - for iter in range(10): - id = dut1.droid.wifiRttStartRangingToAwarePeerMac(dut2_mac) - event = autils.wait_for_event(dut1, rutils.decorate_event( - rconsts.EVENT_CB_RANGING_ON_RESULT, id)) - results12.append(event["data"][rconsts.EVENT_CB_RANGING_KEY_RESULTS][0]) - - stats = [rutils.extract_stats(results12, 0, 0, 0), - rutils.extract_stats(results21, 0, 0, 0)] - - # Update XXX to be within range - dut2.droid.wifiAwareUpdateSubscribe(xxx_s_id, autils.add_ranging_to_sub( - autils.create_discovery_config("XXX", aconsts.SUBSCRIBE_TYPE_PASSIVE), - min_distance_mm=None, max_distance_mm=1000000)) - autils.wait_for_event(dut2, autils.decorate_event( - aconsts.SESSION_CB_ON_SESSION_CONFIG_UPDATED, xxx_s_id)) - - # Expect discovery on XXX - wait until discovery with ranging: - # - 0 or more: without ranging info (due to concurrency limitations) - # - 1 or more: with ranging (once concurrency limitation relieved) - num_events = 0 - while True: - event = autils.wait_for_event(dut2, autils.decorate_event( - aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, xxx_s_id)) - if aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"]: - break - num_events = num_events + 1 - asserts.assert_true(num_events < 10, # arbitrary safety valve - "Way too many discovery events without ranging!") - - asserts.explicit_pass("Discovery/Direct RTT Concurrency Pass", extras=stats)
\ No newline at end of file + dut1 = self.android_devices[0] + dut1.pretty_name = "DUT1" + dut2 = self.android_devices[1] + dut2.pretty_name = "DUT2" + + # DUTs: attach and wait for confirmation + dut1_id = dut1.droid.wifiAwareAttach(False) + autils.wait_for_event(dut1, aconsts.EVENT_CB_ON_ATTACHED) + time.sleep(self.device_startup_offset) + dut2_id = dut2.droid.wifiAwareAttach(True) + event = autils.wait_for_event(dut2, + aconsts.EVENT_CB_ON_IDENTITY_CHANGED) + dut2_mac = event['data']['mac'] + + # DUT1: publishers bring-up + xxx_p_id = dut1.droid.wifiAwarePublish( + dut1_id, + autils.add_ranging_to_pub( + autils.create_discovery_config( + "XXX", aconsts.PUBLISH_TYPE_UNSOLICITED), + enable_ranging=True), True) + autils.wait_for_event( + dut1, + autils.decorate_event(aconsts.SESSION_CB_ON_PUBLISH_STARTED, + xxx_p_id)) + yyy_p_id = dut1.droid.wifiAwarePublish( + dut1_id, + autils.add_ranging_to_pub( + autils.create_discovery_config( + "YYY", aconsts.PUBLISH_TYPE_UNSOLICITED), + enable_ranging=True), True) + autils.wait_for_event( + dut1, + autils.decorate_event(aconsts.SESSION_CB_ON_PUBLISH_STARTED, + yyy_p_id)) + + # DUT2: subscribers bring-up + xxx_s_id = dut2.droid.wifiAwareSubscribe( + dut2_id, + autils.add_ranging_to_sub( + autils.create_discovery_config("XXX", + aconsts.SUBSCRIBE_TYPE_PASSIVE), + min_distance_mm=1000000, + max_distance_mm=1000001), True) + autils.wait_for_event( + dut2, + autils.decorate_event(aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, + xxx_s_id)) + yyy_s_id = dut2.droid.wifiAwareSubscribe( + dut2_id, + autils.add_ranging_to_sub( + autils.create_discovery_config("YYY", + aconsts.SUBSCRIBE_TYPE_PASSIVE), + min_distance_mm=None, + max_distance_mm=1000000), True) + autils.wait_for_event( + dut2, + autils.decorate_event(aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED, + yyy_s_id)) + + # Service discovery: YYY (with range info), but no XXX + event = autils.wait_for_event( + dut2, + autils.decorate_event(aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, + yyy_s_id)) + asserts.assert_true( + aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"], + "Discovery with ranging for YYY expected!") + yyy_peer_id_on_sub = event['data'][aconsts.SESSION_CB_KEY_PEER_ID] + + autils.fail_on_event( + dut2, + autils.decorate_event(aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, + xxx_s_id)) + + # Direct ranging + results21 = [] + for iter in range(10): + id = dut2.droid.wifiRttStartRangingToAwarePeerId( + yyy_peer_id_on_sub) + event = autils.wait_for_event( + dut2, + rutils.decorate_event(rconsts.EVENT_CB_RANGING_ON_RESULT, id)) + results21.append( + event["data"][rconsts.EVENT_CB_RANGING_KEY_RESULTS][0]) + + time.sleep(5) # while switching roles + + results12 = [] + for iter in range(10): + id = dut1.droid.wifiRttStartRangingToAwarePeerMac(dut2_mac) + event = autils.wait_for_event( + dut1, + rutils.decorate_event(rconsts.EVENT_CB_RANGING_ON_RESULT, id)) + results12.append( + event["data"][rconsts.EVENT_CB_RANGING_KEY_RESULTS][0]) + + stats = [ + rutils.extract_stats(results12, 0, 0, 0), + rutils.extract_stats(results21, 0, 0, 0) + ] + + # Update XXX to be within range + dut2.droid.wifiAwareUpdateSubscribe( + xxx_s_id, + autils.add_ranging_to_sub( + autils.create_discovery_config("XXX", + aconsts.SUBSCRIBE_TYPE_PASSIVE), + min_distance_mm=None, + max_distance_mm=1000000)) + autils.wait_for_event( + dut2, + autils.decorate_event(aconsts.SESSION_CB_ON_SESSION_CONFIG_UPDATED, + xxx_s_id)) + + # Expect discovery on XXX - wait until discovery with ranging: + # - 0 or more: without ranging info (due to concurrency limitations) + # - 1 or more: with ranging (once concurrency limitation relieved) + num_events = 0 + while True: + event = autils.wait_for_event( + dut2, + autils.decorate_event(aconsts.SESSION_CB_ON_SERVICE_DISCOVERED, + xxx_s_id)) + if aconsts.SESSION_CB_KEY_DISTANCE_MM in event["data"]: + break + num_events = num_events + 1 + asserts.assert_true( + num_events < 10, # arbitrary safety valve + "Way too many discovery events without ranging!") + + asserts.explicit_pass( + "Discovery/Direct RTT Concurrency Pass", extras=stats) diff --git a/acts/tests/google/wifi/rtt/functional/RangeApMiscTest.py b/acts/tests/google/wifi/rtt/functional/RangeApMiscTest.py index dd5560d660..b265f00db4 100644 --- a/acts/tests/google/wifi/rtt/functional/RangeApMiscTest.py +++ b/acts/tests/google/wifi/rtt/functional/RangeApMiscTest.py @@ -22,64 +22,72 @@ from acts.test_utils.wifi.rtt.RttBaseTest import RttBaseTest class RangeApMiscTest(RttBaseTest): - """Test class for RTT ranging to Access Points - miscellaneous tests which + """Test class for RTT ranging to Access Points - miscellaneous tests which do not fit into the strict IEEE 802.11mc supporting or non-supporting test beds - e.g. a mixed test.""" - # Number of RTT iterations - NUM_ITER = 10 + # Number of RTT iterations + NUM_ITER = 10 - # Time gap (in seconds) between iterations - TIME_BETWEEN_ITERATIONS = 0 + # Time gap (in seconds) between iterations + TIME_BETWEEN_ITERATIONS = 0 - def __init__(self, controllers): - RttBaseTest.__init__(self, controllers) + def __init__(self, controllers): + RttBaseTest.__init__(self, controllers) - ############################################################################# + ############################################################################# - def test_rtt_mixed_80211mc_supporting_aps_wo_privilege(self): - """Scan for APs and perform RTT on one supporting and one non-supporting + 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) + 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'] <= + 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) + 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) diff --git a/acts/tests/google/wifi/rtt/functional/RangeApNonSupporting11McTest.py b/acts/tests/google/wifi/rtt/functional/RangeApNonSupporting11McTest.py index 65b67d29b2..b87a4ad960 100644 --- a/acts/tests/google/wifi/rtt/functional/RangeApNonSupporting11McTest.py +++ b/acts/tests/google/wifi/rtt/functional/RangeApNonSupporting11McTest.py @@ -23,115 +23,131 @@ from acts.test_utils.wifi.rtt.RttBaseTest import RttBaseTest class RangeApNonSupporting11McTest(WifiBaseTest, RttBaseTest): - """Test class for RTT ranging to Access Points which do not support IEEE + """Test class for RTT ranging to Access Points which do not support IEEE 802.11mc""" - # Number of RTT iterations - NUM_ITER = 10 + # Number of RTT iterations + NUM_ITER = 10 - # Time gap (in seconds) between iterations - TIME_BETWEEN_ITERATIONS = 0 + # Time gap (in seconds) between iterations + TIME_BETWEEN_ITERATIONS = 0 - def __init__(self, controllers): - WifiBaseTest.__init__(self, controllers) - RttBaseTest.__init__(self, controllers) - if "AccessPoint" in self.user_params: - self.legacy_configure_ap_and_start() + def __init__(self, controllers): + WifiBaseTest.__init__(self, controllers) + RttBaseTest.__init__(self, controllers) + if "AccessPoint" in self.user_params: + self.legacy_configure_ap_and_start() - ############################################################################# + ############################################################################# - @test_tracker_info(uuid="cde756e9-11f3-43da-b9ae-9edf85764f82") - def test_rtt_non_80211mc_supporting_aps(self): - """Scan for APs and perform RTT on non-IEEE 802.11mc supporting APs""" - 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!") - 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) + @test_tracker_info(uuid="cde756e9-11f3-43da-b9ae-9edf85764f82") + def test_rtt_non_80211mc_supporting_aps(self): + """Scan for APs and perform RTT on non-IEEE 802.11mc supporting APs""" + 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!") + 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_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) - asserts.assert_true(stat['num_range_out_of_margin'] <= - self.rtt_max_margin_exceeded_rate_one_sided_rtt_percentage - * stat['num_success_results'] / 100, + 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) + 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) + asserts.explicit_pass("RTT test done", extras=stats) - @test_tracker_info(uuid="c9e22185-16d4-4fe6-894f-5823587b3288") - 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 + @test_tracker_info(uuid="c9e22185-16d4-4fe6-894f-5823587b3288") + 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) + 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) + 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) - @test_tracker_info(uuid="e117af56-bd3f-40ae-a2fd-4175f0daa7fa") - def test_rtt_non_80211mc_supporting_ap_faked_as_supporting(self): - """Scan for APs which do not support IEEE 802.11mc, maliciously modify the + @test_tracker_info(uuid="e117af56-bd3f-40ae-a2fd-4175f0daa7fa") + 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) + 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) + 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) diff --git a/acts/tests/google/wifi/rtt/functional/RangeApSupporting11McTest.py b/acts/tests/google/wifi/rtt/functional/RangeApSupporting11McTest.py index d889a22c49..acd4b10821 100644 --- a/acts/tests/google/wifi/rtt/functional/RangeApSupporting11McTest.py +++ b/acts/tests/google/wifi/rtt/functional/RangeApSupporting11McTest.py @@ -25,163 +25,183 @@ from acts.test_utils.wifi.rtt.RttBaseTest import RttBaseTest class RangeApSupporting11McTest(RttBaseTest): - """Test class for RTT ranging to Access Points which support IEEE 802.11mc""" - - # Number of RTT iterations - NUM_ITER = 10 - - # Time gap (in seconds) between iterations - TIME_BETWEEN_ITERATIONS = 0 - - def __init__(self, controllers): - RttBaseTest.__init__(self, controllers) - - ############################################################################# - - @test_tracker_info(uuid="6705270f-924b-4bef-b50a-0f0a7eb9ce52") - def test_rtt_80211mc_supporting_aps(self): - """Scan for APs and perform RTT only to those which support 802.11mc""" - 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) - 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) - 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) - - ######################################################################### - # - # LEGACY API test code - # - ######################################################################### - - @test_tracker_info(uuid="18be9737-2f03-4e35-9a23-f722dea7b82d") - def test_legacy_rtt_80211mc_supporting_aps(self): - """Scan for APs and perform RTT only to those which support 802.11mc - using + """Test class for RTT ranging to Access Points which support IEEE 802.11mc""" + + # Number of RTT iterations + NUM_ITER = 10 + + # Time gap (in seconds) between iterations + TIME_BETWEEN_ITERATIONS = 0 + + def __init__(self, controllers): + RttBaseTest.__init__(self, controllers) + + ############################################################################# + + @test_tracker_info(uuid="6705270f-924b-4bef-b50a-0f0a7eb9ce52") + def test_rtt_80211mc_supporting_aps(self): + """Scan for APs and perform RTT only to those which support 802.11mc""" + 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) + 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) + 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) + + ######################################################################### + # + # LEGACY API test code + # + ######################################################################### + + @test_tracker_info(uuid="18be9737-2f03-4e35-9a23-f722dea7b82d") + 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 rtt_config_from_scan_result(self, scan_result): - """Creates an Rtt configuration based on the scan result of a network. + 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 rtt_config_from_scan_result(self, scan_result): + """Creates an Rtt configuration based on the scan result of a network. """ - WifiEnums = wutils.WifiEnums - ScanResult = WifiEnums.ScanResult - RttParam = WifiEnums.RttParam - RttBW = WifiEnums.RttBW - RttPreamble = WifiEnums.RttPreamble - RttType = WifiEnums.RttType - - scan_result_channel_width_to_rtt = { - ScanResult.CHANNEL_WIDTH_20MHZ: RttBW.BW_20_SUPPORT, - ScanResult.CHANNEL_WIDTH_40MHZ: RttBW.BW_40_SUPPORT, - ScanResult.CHANNEL_WIDTH_80MHZ: RttBW.BW_80_SUPPORT, - ScanResult.CHANNEL_WIDTH_160MHZ: RttBW.BW_160_SUPPORT, - ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ: RttBW.BW_160_SUPPORT - } - p = {} - freq = scan_result[RttParam.frequency] - p[RttParam.frequency] = freq - p[RttParam.BSSID] = scan_result[WifiEnums.BSSID_KEY] - if freq > 5000: - p[RttParam.preamble] = RttPreamble.PREAMBLE_VHT - else: - p[RttParam.preamble] = RttPreamble.PREAMBLE_HT - cf0 = scan_result[RttParam.center_freq0] - if cf0 > 0: - p[RttParam.center_freq0] = cf0 - cf1 = scan_result[RttParam.center_freq1] - if cf1 > 0: - p[RttParam.center_freq1] = cf1 - cw = scan_result["channelWidth"] - p[RttParam.channel_width] = cw - p[RttParam.bandwidth] = scan_result_channel_width_to_rtt[cw] - if scan_result["is80211McRTTResponder"]: - p[RttParam.request_type] = RttType.TYPE_TWO_SIDED - else: - p[RttParam.request_type] = RttType.TYPE_ONE_SIDED - return p + WifiEnums = wutils.WifiEnums + ScanResult = WifiEnums.ScanResult + RttParam = WifiEnums.RttParam + RttBW = WifiEnums.RttBW + RttPreamble = WifiEnums.RttPreamble + RttType = WifiEnums.RttType + + scan_result_channel_width_to_rtt = { + ScanResult.CHANNEL_WIDTH_20MHZ: RttBW.BW_20_SUPPORT, + ScanResult.CHANNEL_WIDTH_40MHZ: RttBW.BW_40_SUPPORT, + ScanResult.CHANNEL_WIDTH_80MHZ: RttBW.BW_80_SUPPORT, + ScanResult.CHANNEL_WIDTH_160MHZ: RttBW.BW_160_SUPPORT, + ScanResult.CHANNEL_WIDTH_80MHZ_PLUS_MHZ: RttBW.BW_160_SUPPORT + } + p = {} + freq = scan_result[RttParam.frequency] + p[RttParam.frequency] = freq + p[RttParam.BSSID] = scan_result[WifiEnums.BSSID_KEY] + if freq > 5000: + p[RttParam.preamble] = RttPreamble.PREAMBLE_VHT + else: + p[RttParam.preamble] = RttPreamble.PREAMBLE_HT + cf0 = scan_result[RttParam.center_freq0] + if cf0 > 0: + p[RttParam.center_freq0] = cf0 + cf1 = scan_result[RttParam.center_freq1] + if cf1 > 0: + p[RttParam.center_freq1] = cf1 + cw = scan_result["channelWidth"] + p[RttParam.channel_width] = cw + p[RttParam.bandwidth] = scan_result_channel_width_to_rtt[cw] + if scan_result["is80211McRTTResponder"]: + p[RttParam.request_type] = RttType.TYPE_TWO_SIDED + else: + p[RttParam.request_type] = RttType.TYPE_ONE_SIDED + return p diff --git a/acts/tests/google/wifi/rtt/functional/RangeAwareTest.py b/acts/tests/google/wifi/rtt/functional/RangeAwareTest.py index d4b7d41783..7eeecc2b20 100644 --- a/acts/tests/google/wifi/rtt/functional/RangeAwareTest.py +++ b/acts/tests/google/wifi/rtt/functional/RangeAwareTest.py @@ -28,38 +28,38 @@ from acts.test_utils.wifi.rtt.RttBaseTest import RttBaseTest class RangeAwareTest(AwareBaseTest, RttBaseTest): - """Test class for RTT ranging to Wi-Fi Aware peers""" - SERVICE_NAME = "GoogleTestServiceXY" + """Test class for RTT ranging to Wi-Fi Aware peers""" + SERVICE_NAME = "GoogleTestServiceXY" - # Number of RTT iterations - NUM_ITER = 10 + # Number of RTT iterations + NUM_ITER = 10 - # Time gap (in seconds) between iterations - TIME_BETWEEN_ITERATIONS = 0 + # Time gap (in seconds) between iterations + TIME_BETWEEN_ITERATIONS = 0 - # Time gap (in seconds) when switching between Initiator and Responder - TIME_BETWEEN_ROLES = 4 + # Time gap (in seconds) when switching between Initiator and Responder + TIME_BETWEEN_ROLES = 4 - def __init__(self, controllers): - AwareBaseTest.__init__(self, controllers) - RttBaseTest.__init__(self, controllers) + def __init__(self, controllers): + AwareBaseTest.__init__(self, controllers) + RttBaseTest.__init__(self, controllers) - def setup_test(self): - """Manual setup here due to multiple inheritance: explicitly execute the + def setup_test(self): + """Manual setup here due to multiple inheritance: explicitly execute the setup method from both parents.""" - AwareBaseTest.setup_test(self) - RttBaseTest.setup_test(self) + AwareBaseTest.setup_test(self) + RttBaseTest.setup_test(self) - def teardown_test(self): - """Manual teardown here due to multiple inheritance: explicitly execute the + def teardown_test(self): + """Manual teardown here due to multiple inheritance: explicitly execute the teardown method from both parents.""" - AwareBaseTest.teardown_test(self) - RttBaseTest.teardown_test(self) + AwareBaseTest.teardown_test(self) + RttBaseTest.teardown_test(self) - ############################################################################# + ############################################################################# - def run_rtt_discovery(self, init_dut, resp_mac=None, resp_peer_id=None): - """Perform single RTT measurement, using Aware, from the Initiator DUT to + def run_rtt_discovery(self, init_dut, resp_mac=None, resp_peer_id=None): + """Perform single RTT measurement, using Aware, from the Initiator DUT to a Responder. The RTT Responder can be specified using its MAC address (obtained using out- of-band discovery) or its Peer ID (using Aware discovery). @@ -69,28 +69,31 @@ class RangeAwareTest(AwareBaseTest, RttBaseTest): resp_mac: MAC address of the RTT Responder device resp_peer_id: Peer ID of the RTT Responder device """ - asserts.assert_true(resp_mac is not None or resp_peer_id is not None, - "One of the Responder specifications (MAC or Peer ID)" - " must be provided!") - if resp_mac is not None: - id = init_dut.droid.wifiRttStartRangingToAwarePeerMac(resp_mac) - else: - id = init_dut.droid.wifiRttStartRangingToAwarePeerId(resp_peer_id) - try: - event = init_dut.ed.pop_event(rutils.decorate_event( - rconsts.EVENT_CB_RANGING_ON_RESULT, id), rutils.EVENT_TIMEOUT) - result = event["data"][rconsts.EVENT_CB_RANGING_KEY_RESULTS][0] - if resp_mac is not None: - rutils.validate_aware_mac_result(result, resp_mac, "DUT") - else: - rutils.validate_aware_peer_id_result(result, resp_peer_id, "DUT") - return result - except queue.Empty: - return None - - def run_rtt_ib_discovery_set(self, do_both_directions, iter_count, - time_between_iterations, time_between_roles): - """Perform a set of RTT measurements, using in-band (Aware) discovery. + asserts.assert_true( + resp_mac is not None or resp_peer_id is not None, + "One of the Responder specifications (MAC or Peer ID)" + " must be provided!") + if resp_mac is not None: + id = init_dut.droid.wifiRttStartRangingToAwarePeerMac(resp_mac) + else: + id = init_dut.droid.wifiRttStartRangingToAwarePeerId(resp_peer_id) + try: + event = init_dut.ed.pop_event( + rutils.decorate_event(rconsts.EVENT_CB_RANGING_ON_RESULT, id), + rutils.EVENT_TIMEOUT) + result = event["data"][rconsts.EVENT_CB_RANGING_KEY_RESULTS][0] + if resp_mac is not None: + rutils.validate_aware_mac_result(result, resp_mac, "DUT") + else: + rutils.validate_aware_peer_id_result(result, resp_peer_id, + "DUT") + return result + except queue.Empty: + return None + + def run_rtt_ib_discovery_set(self, do_both_directions, iter_count, + time_between_iterations, time_between_roles): + """Perform a set of RTT measurements, using in-band (Aware) discovery. Args: do_both_directions: False - perform all measurements in one direction, @@ -105,43 +108,46 @@ class RangeAwareTest(AwareBaseTest, RttBaseTest): failed measurement). If both directions are tested then returns a list of 2 elements: one set for each direction. """ - p_dut = self.android_devices[0] - s_dut = self.android_devices[1] - - (p_id, s_id, p_disc_id, s_disc_id, - peer_id_on_sub, peer_id_on_pub) = autils.create_discovery_pair( - p_dut, - s_dut, - p_config=autils.add_ranging_to_pub(autils.create_discovery_config( - self.SERVICE_NAME, aconsts.PUBLISH_TYPE_UNSOLICITED), True), - s_config=autils.add_ranging_to_pub(autils.create_discovery_config( - self.SERVICE_NAME, aconsts.SUBSCRIBE_TYPE_PASSIVE), True), - device_startup_offset=self.device_startup_offset, - msg_id=self.get_next_msg_id()) - - resultsPS = [] - resultsSP = [] - for i in range(iter_count): - if i != 0 and time_between_iterations != 0: - time.sleep(time_between_iterations) - - # perform RTT from pub -> sub - resultsPS.append( - self.run_rtt_discovery(p_dut, resp_peer_id=peer_id_on_pub)) - - if do_both_directions: - if time_between_roles != 0: - time.sleep(time_between_roles) - - # perform RTT from sub -> pub - resultsSP.append( - self.run_rtt_discovery(s_dut, resp_peer_id=peer_id_on_sub)) - - return resultsPS if not do_both_directions else [resultsPS, resultsSP] - - def run_rtt_oob_discovery_set(self, do_both_directions, iter_count, - time_between_iterations, time_between_roles): - """Perform a set of RTT measurements, using out-of-band discovery. + p_dut = self.android_devices[0] + s_dut = self.android_devices[1] + + (p_id, s_id, p_disc_id, s_disc_id, peer_id_on_sub, + peer_id_on_pub) = autils.create_discovery_pair( + p_dut, + s_dut, + p_config=autils.add_ranging_to_pub( + autils.create_discovery_config( + self.SERVICE_NAME, aconsts.PUBLISH_TYPE_UNSOLICITED), + True), + s_config=autils.add_ranging_to_pub( + autils.create_discovery_config( + self.SERVICE_NAME, aconsts.SUBSCRIBE_TYPE_PASSIVE), True), + device_startup_offset=self.device_startup_offset, + msg_id=self.get_next_msg_id()) + + resultsPS = [] + resultsSP = [] + for i in range(iter_count): + if i != 0 and time_between_iterations != 0: + time.sleep(time_between_iterations) + + # perform RTT from pub -> sub + resultsPS.append( + self.run_rtt_discovery(p_dut, resp_peer_id=peer_id_on_pub)) + + if do_both_directions: + if time_between_roles != 0: + time.sleep(time_between_roles) + + # perform RTT from sub -> pub + resultsSP.append( + self.run_rtt_discovery(s_dut, resp_peer_id=peer_id_on_sub)) + + return resultsPS if not do_both_directions else [resultsPS, resultsSP] + + def run_rtt_oob_discovery_set(self, do_both_directions, iter_count, + time_between_iterations, time_between_roles): + """Perform a set of RTT measurements, using out-of-band discovery. Args: do_both_directions: False - perform all measurements in one direction, @@ -157,253 +163,274 @@ class RangeAwareTest(AwareBaseTest, RttBaseTest): failed measurement). If both directions are tested then returns a list of 2 elements: one set for each direction. """ - dut0 = self.android_devices[0] - dut1 = self.android_devices[1] - - id0, mac0 = autils.attach_with_identity(dut0) - id1, mac1 = autils.attach_with_identity(dut1) - - # wait for for devices to synchronize with each other - there are no other - # mechanisms to make sure this happens for OOB discovery (except retrying - # to execute the data-path request) - time.sleep(autils.WAIT_FOR_CLUSTER) - - # start publisher(s) on the Responder(s) with ranging enabled - p_config = autils.add_ranging_to_pub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.PUBLISH_TYPE_UNSOLICITED), - enable_ranging=True) - dut1.droid.wifiAwarePublish(id1, p_config) - autils.wait_for_event(dut1, aconsts.SESSION_CB_ON_PUBLISH_STARTED) - if do_both_directions: - dut0.droid.wifiAwarePublish(id0, p_config) - autils.wait_for_event(dut0, aconsts.SESSION_CB_ON_PUBLISH_STARTED) - - results01 = [] - results10 = [] - for i in range(iter_count): - if i != 0 and time_between_iterations != 0: - time.sleep(time_between_iterations) - - # perform RTT from dut0 -> dut1 - results01.append( - self.run_rtt_discovery(dut0, resp_mac=mac1)) - - if do_both_directions: - if time_between_roles != 0: - time.sleep(time_between_roles) - - # perform RTT from dut1 -> dut0 - results10.append( - self.run_rtt_discovery(dut1, resp_mac=mac0)) - - return results01 if not do_both_directions else [results01, results10] - - def verify_results(self, results, results_reverse_direction=None): - """Verifies the results of the RTT experiment. + dut0 = self.android_devices[0] + dut1 = self.android_devices[1] + + id0, mac0 = autils.attach_with_identity(dut0) + id1, mac1 = autils.attach_with_identity(dut1) + + # wait for for devices to synchronize with each other - there are no other + # mechanisms to make sure this happens for OOB discovery (except retrying + # to execute the data-path request) + time.sleep(autils.WAIT_FOR_CLUSTER) + + # start publisher(s) on the Responder(s) with ranging enabled + p_config = autils.add_ranging_to_pub( + autils.create_discovery_config(self.SERVICE_NAME, + aconsts.PUBLISH_TYPE_UNSOLICITED), + enable_ranging=True) + dut1.droid.wifiAwarePublish(id1, p_config) + autils.wait_for_event(dut1, aconsts.SESSION_CB_ON_PUBLISH_STARTED) + if do_both_directions: + dut0.droid.wifiAwarePublish(id0, p_config) + autils.wait_for_event(dut0, aconsts.SESSION_CB_ON_PUBLISH_STARTED) + + results01 = [] + results10 = [] + for i in range(iter_count): + if i != 0 and time_between_iterations != 0: + time.sleep(time_between_iterations) + + # perform RTT from dut0 -> dut1 + results01.append(self.run_rtt_discovery(dut0, resp_mac=mac1)) + + if do_both_directions: + if time_between_roles != 0: + time.sleep(time_between_roles) + + # perform RTT from dut1 -> dut0 + results10.append(self.run_rtt_discovery(dut1, resp_mac=mac0)) + + return results01 if not do_both_directions else [results01, results10] + + def verify_results(self, results, results_reverse_direction=None): + """Verifies the results of the RTT experiment. Args: results: List of RTT results. results_reverse_direction: List of RTT results executed in the reverse direction. Optional. """ - stats = rutils.extract_stats(results, self.rtt_reference_distance_mm, - self.rtt_reference_distance_margin_mm, - self.rtt_min_expected_rssi_dbm) - stats_reverse_direction = None - if results_reverse_direction is not None: - stats_reverse_direction = rutils.extract_stats(results_reverse_direction, - self.rtt_reference_distance_mm, self.rtt_reference_distance_margin_mm, - self.rtt_min_expected_rssi_dbm) - self.log.debug("Stats: %s", stats) - if stats_reverse_direction is not None: - self.log.debug("Stats in reverse direction: %s", stats_reverse_direction) - - extras = stats if stats_reverse_direction is None else { - "forward": stats, - "reverse": stats_reverse_direction} - - asserts.assert_true(stats['num_no_results'] == 0, - "Missing (timed-out) results", extras=extras) - asserts.assert_false(stats['any_lci_mismatch'], - "LCI mismatch", extras=extras) - asserts.assert_false(stats['any_lcr_mismatch'], - "LCR mismatch", extras=extras) - asserts.assert_false(stats['invalid_num_attempted'], - "Invalid (0) number of attempts", extras=stats) - asserts.assert_false(stats['invalid_num_successful'], - "Invalid (0) number of successes", extras=stats) - asserts.assert_equal(stats['num_invalid_rssi'], 0, "Invalid RSSI", - extras=extras) - asserts.assert_true( - stats['num_failures'] <= - self.rtt_max_failure_rate_two_sided_rtt_percentage - * stats['num_results'] / 100, - "Failure rate is too high", extras=extras) - asserts.assert_true( - stats['num_range_out_of_margin'] - <= self.rtt_max_margin_exceeded_rate_two_sided_rtt_percentage - * stats['num_success_results'] / 100, - "Results exceeding error margin rate is too high", extras=extras) - - if stats_reverse_direction is not None: - asserts.assert_true(stats_reverse_direction['num_no_results'] == 0, - "Missing (timed-out) results", - extras=extras) - asserts.assert_false(stats['any_lci_mismatch'], - "LCI mismatch", extras=extras) - asserts.assert_false(stats['any_lcr_mismatch'], - "LCR mismatch", extras=extras) - asserts.assert_equal(stats['num_invalid_rssi'], 0, "Invalid RSSI", - extras=extras) - asserts.assert_true( - stats_reverse_direction['num_failures'] - <= self.rtt_max_failure_rate_two_sided_rtt_percentage - * stats['num_results'] / 100, - "Failure rate is too high", extras=extras) - asserts.assert_true( - stats_reverse_direction['num_range_out_of_margin'] - <= self.rtt_max_margin_exceeded_rate_two_sided_rtt_percentage - * stats['num_success_results'] / 100, - "Results exceeding error margin rate is too high", - extras=extras) - - asserts.explicit_pass("RTT Aware test done", extras=extras) - - ############################################################################# - - @test_tracker_info(uuid="9e4e7ab4-2254-498c-9788-21e15ed9a370") - def test_rtt_oob_discovery_one_way(self): - """Perform RTT between 2 Wi-Fi Aware devices. Use out-of-band discovery + stats = rutils.extract_stats(results, self.rtt_reference_distance_mm, + self.rtt_reference_distance_margin_mm, + self.rtt_min_expected_rssi_dbm) + stats_reverse_direction = None + if results_reverse_direction is not None: + stats_reverse_direction = rutils.extract_stats( + results_reverse_direction, self.rtt_reference_distance_mm, + self.rtt_reference_distance_margin_mm, + self.rtt_min_expected_rssi_dbm) + self.log.debug("Stats: %s", stats) + if stats_reverse_direction is not None: + self.log.debug("Stats in reverse direction: %s", + stats_reverse_direction) + + extras = stats if stats_reverse_direction is None else { + "forward": stats, + "reverse": stats_reverse_direction + } + + asserts.assert_true( + stats['num_no_results'] == 0, + "Missing (timed-out) results", + extras=extras) + asserts.assert_false( + stats['any_lci_mismatch'], "LCI mismatch", extras=extras) + asserts.assert_false( + stats['any_lcr_mismatch'], "LCR mismatch", extras=extras) + asserts.assert_false( + stats['invalid_num_attempted'], + "Invalid (0) number of attempts", + extras=stats) + asserts.assert_false( + stats['invalid_num_successful'], + "Invalid (0) number of successes", + extras=stats) + asserts.assert_equal( + stats['num_invalid_rssi'], 0, "Invalid RSSI", extras=extras) + asserts.assert_true( + stats['num_failures'] <= + self.rtt_max_failure_rate_two_sided_rtt_percentage * + stats['num_results'] / 100, + "Failure rate is too high", + extras=extras) + asserts.assert_true( + stats['num_range_out_of_margin'] <= + self.rtt_max_margin_exceeded_rate_two_sided_rtt_percentage * + stats['num_success_results'] / 100, + "Results exceeding error margin rate is too high", + extras=extras) + + if stats_reverse_direction is not None: + asserts.assert_true( + stats_reverse_direction['num_no_results'] == 0, + "Missing (timed-out) results", + extras=extras) + asserts.assert_false( + stats['any_lci_mismatch'], "LCI mismatch", extras=extras) + asserts.assert_false( + stats['any_lcr_mismatch'], "LCR mismatch", extras=extras) + asserts.assert_equal( + stats['num_invalid_rssi'], 0, "Invalid RSSI", extras=extras) + asserts.assert_true( + stats_reverse_direction['num_failures'] <= + self.rtt_max_failure_rate_two_sided_rtt_percentage * + stats['num_results'] / 100, + "Failure rate is too high", + extras=extras) + asserts.assert_true( + stats_reverse_direction['num_range_out_of_margin'] <= + self.rtt_max_margin_exceeded_rate_two_sided_rtt_percentage * + stats['num_success_results'] / 100, + "Results exceeding error margin rate is too high", + extras=extras) + + asserts.explicit_pass("RTT Aware test done", extras=extras) + + ############################################################################# + + @test_tracker_info(uuid="9e4e7ab4-2254-498c-9788-21e15ed9a370") + def test_rtt_oob_discovery_one_way(self): + """Perform RTT between 2 Wi-Fi Aware devices. Use out-of-band discovery to communicate the MAC addresses to the peer. Test one-direction RTT only. """ - rtt_results = self.run_rtt_oob_discovery_set(do_both_directions=False, - iter_count=self.NUM_ITER, - time_between_iterations=self.TIME_BETWEEN_ITERATIONS, - time_between_roles=self.TIME_BETWEEN_ROLES) - self.verify_results(rtt_results) - - @test_tracker_info(uuid="22edba77-eeb2-43ee-875a-84437550ad84") - def test_rtt_oob_discovery_both_ways(self): - """Perform RTT between 2 Wi-Fi Aware devices. Use out-of-band discovery + rtt_results = self.run_rtt_oob_discovery_set( + do_both_directions=False, + iter_count=self.NUM_ITER, + time_between_iterations=self.TIME_BETWEEN_ITERATIONS, + time_between_roles=self.TIME_BETWEEN_ROLES) + self.verify_results(rtt_results) + + @test_tracker_info(uuid="22edba77-eeb2-43ee-875a-84437550ad84") + def test_rtt_oob_discovery_both_ways(self): + """Perform RTT between 2 Wi-Fi Aware devices. Use out-of-band discovery to communicate the MAC addresses to the peer. Test RTT both-ways: switching rapidly between Initiator and Responder. """ - rtt_results1, rtt_results2 = self.run_rtt_oob_discovery_set( - do_both_directions=True, iter_count=self.NUM_ITER, - time_between_iterations=self.TIME_BETWEEN_ITERATIONS, - time_between_roles=self.TIME_BETWEEN_ROLES) - self.verify_results(rtt_results1, rtt_results2) - - @test_tracker_info(uuid="18cef4be-95b4-4f7d-a140-5165874e7d1c") - def test_rtt_ib_discovery_one_way(self): - """Perform RTT between 2 Wi-Fi Aware devices. Use in-band (Aware) discovery + rtt_results1, rtt_results2 = self.run_rtt_oob_discovery_set( + do_both_directions=True, + iter_count=self.NUM_ITER, + time_between_iterations=self.TIME_BETWEEN_ITERATIONS, + time_between_roles=self.TIME_BETWEEN_ROLES) + self.verify_results(rtt_results1, rtt_results2) + + @test_tracker_info(uuid="18cef4be-95b4-4f7d-a140-5165874e7d1c") + def test_rtt_ib_discovery_one_way(self): + """Perform RTT between 2 Wi-Fi Aware devices. Use in-band (Aware) discovery to communicate the MAC addresses to the peer. Test one-direction RTT only. """ - rtt_results = self.run_rtt_ib_discovery_set(do_both_directions=False, - iter_count=self.NUM_ITER, - time_between_iterations=self.TIME_BETWEEN_ITERATIONS, - time_between_roles=self.TIME_BETWEEN_ROLES) - self.verify_results(rtt_results) - - @test_tracker_info(uuid="c67c8e70-c417-42d9-9bca-af3a89f1ddd9") - def test_rtt_ib_discovery_both_ways(self): - """Perform RTT between 2 Wi-Fi Aware devices. Use in-band (Aware) discovery + rtt_results = self.run_rtt_ib_discovery_set( + do_both_directions=False, + iter_count=self.NUM_ITER, + time_between_iterations=self.TIME_BETWEEN_ITERATIONS, + time_between_roles=self.TIME_BETWEEN_ROLES) + self.verify_results(rtt_results) + + @test_tracker_info(uuid="c67c8e70-c417-42d9-9bca-af3a89f1ddd9") + def test_rtt_ib_discovery_both_ways(self): + """Perform RTT between 2 Wi-Fi Aware devices. Use in-band (Aware) discovery to communicate the MAC addresses to the peer. Test RTT both-ways: switching rapidly between Initiator and Responder. """ - rtt_results1, rtt_results2 = self.run_rtt_ib_discovery_set( - do_both_directions=True, iter_count=self.NUM_ITER, - time_between_iterations=self.TIME_BETWEEN_ITERATIONS, - time_between_roles=self.TIME_BETWEEN_ROLES) - self.verify_results(rtt_results1, rtt_results2) - - @test_tracker_info(uuid="54f9693d-45e5-4979-adbb-1b875d217c0c") - def test_rtt_without_initiator_aware(self): - """Try to perform RTT operation when there is no local Aware session (on the + rtt_results1, rtt_results2 = self.run_rtt_ib_discovery_set( + do_both_directions=True, + iter_count=self.NUM_ITER, + time_between_iterations=self.TIME_BETWEEN_ITERATIONS, + time_between_roles=self.TIME_BETWEEN_ROLES) + self.verify_results(rtt_results1, rtt_results2) + + @test_tracker_info(uuid="54f9693d-45e5-4979-adbb-1b875d217c0c") + def test_rtt_without_initiator_aware(self): + """Try to perform RTT operation when there is no local Aware session (on the Initiator). The Responder is configured normally: Aware on and a Publisher with Ranging enable. Should FAIL.""" - init_dut = self.android_devices[0] - resp_dut = self.android_devices[1] - - # Enable a Responder and start a Publisher - resp_id = resp_dut.droid.wifiAwareAttach(True) - autils.wait_for_event(resp_dut, aconsts.EVENT_CB_ON_ATTACHED) - resp_ident_event = autils.wait_for_event(resp_dut, - aconsts.EVENT_CB_ON_IDENTITY_CHANGED) - resp_mac = resp_ident_event['data']['mac'] - - resp_config = autils.add_ranging_to_pub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.PUBLISH_TYPE_UNSOLICITED), - enable_ranging=True) - resp_dut.droid.wifiAwarePublish(resp_id, resp_config) - autils.wait_for_event(resp_dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED) - - # Initiate an RTT to Responder (no Aware started on Initiator!) - results = [] - num_no_responses = 0 - num_successes = 0 - for i in range(self.NUM_ITER): - result = self.run_rtt_discovery(init_dut, resp_mac=resp_mac) - self.log.debug("result: %s", result) - results.append(result) - if result is None: - num_no_responses = num_no_responses + 1 - elif (result[rconsts.EVENT_CB_RANGING_KEY_STATUS] - == rconsts.EVENT_CB_RANGING_STATUS_SUCCESS): - num_successes = num_successes + 1 - - asserts.assert_equal(num_no_responses, 0, "No RTT response?", - extras={"data":results}) - asserts.assert_equal(num_successes, 0, "Aware RTT w/o Aware should FAIL!", - extras={"data":results}) - asserts.explicit_pass("RTT Aware test done", extras={"data":results}) - - @test_tracker_info(uuid="87a69053-8261-4928-8ec1-c93aac7f3a8d") - def test_rtt_without_responder_aware(self): - """Try to perform RTT operation when there is no peer Aware session (on the + init_dut = self.android_devices[0] + resp_dut = self.android_devices[1] + + # Enable a Responder and start a Publisher + resp_id = resp_dut.droid.wifiAwareAttach(True) + autils.wait_for_event(resp_dut, aconsts.EVENT_CB_ON_ATTACHED) + resp_ident_event = autils.wait_for_event( + resp_dut, aconsts.EVENT_CB_ON_IDENTITY_CHANGED) + resp_mac = resp_ident_event['data']['mac'] + + resp_config = autils.add_ranging_to_pub( + autils.create_discovery_config(self.SERVICE_NAME, + aconsts.PUBLISH_TYPE_UNSOLICITED), + enable_ranging=True) + resp_dut.droid.wifiAwarePublish(resp_id, resp_config) + autils.wait_for_event(resp_dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED) + + # Initiate an RTT to Responder (no Aware started on Initiator!) + results = [] + num_no_responses = 0 + num_successes = 0 + for i in range(self.NUM_ITER): + result = self.run_rtt_discovery(init_dut, resp_mac=resp_mac) + self.log.debug("result: %s", result) + results.append(result) + if result is None: + num_no_responses = num_no_responses + 1 + elif (result[rconsts.EVENT_CB_RANGING_KEY_STATUS] == + rconsts.EVENT_CB_RANGING_STATUS_SUCCESS): + num_successes = num_successes + 1 + + asserts.assert_equal( + num_no_responses, 0, "No RTT response?", extras={"data": results}) + asserts.assert_equal( + num_successes, + 0, + "Aware RTT w/o Aware should FAIL!", + extras={"data": results}) + asserts.explicit_pass("RTT Aware test done", extras={"data": results}) + + @test_tracker_info(uuid="87a69053-8261-4928-8ec1-c93aac7f3a8d") + def test_rtt_without_responder_aware(self): + """Try to perform RTT operation when there is no peer Aware session (on the Responder). Should FAIL.""" - init_dut = self.android_devices[0] - resp_dut = self.android_devices[1] - - # Enable a Responder and start a Publisher - resp_id = resp_dut.droid.wifiAwareAttach(True) - autils.wait_for_event(resp_dut, aconsts.EVENT_CB_ON_ATTACHED) - resp_ident_event = autils.wait_for_event(resp_dut, - aconsts.EVENT_CB_ON_IDENTITY_CHANGED) - resp_mac = resp_ident_event['data']['mac'] - - resp_config = autils.add_ranging_to_pub( - autils.create_discovery_config(self.SERVICE_NAME, - aconsts.PUBLISH_TYPE_UNSOLICITED), - enable_ranging=True) - resp_dut.droid.wifiAwarePublish(resp_id, resp_config) - autils.wait_for_event(resp_dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED) - - # Disable Responder - resp_dut.droid.wifiAwareDestroy(resp_id) - - # Enable the Initiator - init_id = init_dut.droid.wifiAwareAttach() - autils.wait_for_event(init_dut, aconsts.EVENT_CB_ON_ATTACHED) - - # Initiate an RTT to Responder (no Aware started on Initiator!) - results = [] - num_no_responses = 0 - num_successes = 0 - for i in range(self.NUM_ITER): - result = self.run_rtt_discovery(init_dut, resp_mac=resp_mac) - self.log.debug("result: %s", result) - results.append(result) - if result is None: - num_no_responses = num_no_responses + 1 - elif (result[rconsts.EVENT_CB_RANGING_KEY_STATUS] - == rconsts.EVENT_CB_RANGING_STATUS_SUCCESS): - num_successes = num_successes + 1 - - asserts.assert_equal(num_no_responses, 0, "No RTT response?", - extras={"data":results}) - asserts.assert_equal(num_successes, 0, "Aware RTT w/o Aware should FAIL!", - extras={"data":results}) - asserts.explicit_pass("RTT Aware test done", extras={"data":results}) + init_dut = self.android_devices[0] + resp_dut = self.android_devices[1] + + # Enable a Responder and start a Publisher + resp_id = resp_dut.droid.wifiAwareAttach(True) + autils.wait_for_event(resp_dut, aconsts.EVENT_CB_ON_ATTACHED) + resp_ident_event = autils.wait_for_event( + resp_dut, aconsts.EVENT_CB_ON_IDENTITY_CHANGED) + resp_mac = resp_ident_event['data']['mac'] + + resp_config = autils.add_ranging_to_pub( + autils.create_discovery_config(self.SERVICE_NAME, + aconsts.PUBLISH_TYPE_UNSOLICITED), + enable_ranging=True) + resp_dut.droid.wifiAwarePublish(resp_id, resp_config) + autils.wait_for_event(resp_dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED) + + # Disable Responder + resp_dut.droid.wifiAwareDestroy(resp_id) + + # Enable the Initiator + init_id = init_dut.droid.wifiAwareAttach() + autils.wait_for_event(init_dut, aconsts.EVENT_CB_ON_ATTACHED) + + # Initiate an RTT to Responder (no Aware started on Initiator!) + results = [] + num_no_responses = 0 + num_successes = 0 + for i in range(self.NUM_ITER): + result = self.run_rtt_discovery(init_dut, resp_mac=resp_mac) + self.log.debug("result: %s", result) + results.append(result) + if result is None: + num_no_responses = num_no_responses + 1 + elif (result[rconsts.EVENT_CB_RANGING_KEY_STATUS] == + rconsts.EVENT_CB_RANGING_STATUS_SUCCESS): + num_successes = num_successes + 1 + + asserts.assert_equal( + num_no_responses, 0, "No RTT response?", extras={"data": results}) + asserts.assert_equal( + num_successes, + 0, + "Aware RTT w/o Aware should FAIL!", + extras={"data": results}) + asserts.explicit_pass("RTT Aware test done", extras={"data": results}) diff --git a/acts/tests/google/wifi/rtt/functional/RangeSoftApTest.py b/acts/tests/google/wifi/rtt/functional/RangeSoftApTest.py index f0c4f4cb84..0478be83c3 100644 --- a/acts/tests/google/wifi/rtt/functional/RangeSoftApTest.py +++ b/acts/tests/google/wifi/rtt/functional/RangeSoftApTest.py @@ -24,72 +24,83 @@ from acts.test_utils.wifi.rtt.RttBaseTest import RttBaseTest class RangeSoftApTest(RttBaseTest): - """Test class for RTT ranging to an Android Soft AP.""" + """Test class for RTT ranging to an Android Soft AP.""" - # Soft AP SSID - SOFT_AP_SSID = "RTT_TEST_SSID" + # Soft AP SSID + SOFT_AP_SSID = "RTT_TEST_SSID" - # Soft AP Password (irrelevant) - SOFT_AP_PASSWORD = "ABCDEFGH" + # Soft AP Password (irrelevant) + SOFT_AP_PASSWORD = "ABCDEFGH" - # Number of RTT iterations - NUM_ITER = 10 + # Number of RTT iterations + NUM_ITER = 10 - def __init__(self, controllers): - RttBaseTest.__init__(self, controllers) + def __init__(self, controllers): + RttBaseTest.__init__(self, controllers) - ######################################################################### + ######################################################################### - @test_tracker_info(uuid="578f0725-31e3-4e60-ad62-0212d93cf5b8") - def test_rtt_to_soft_ap(self): - """Set up a Soft AP on one device and try performing an RTT ranging to it + @test_tracker_info(uuid="578f0725-31e3-4e60-ad62-0212d93cf5b8") + def test_rtt_to_soft_ap(self): + """Set up a Soft AP on one device and try performing an RTT ranging to it from another device. The attempt must fail - RTT on Soft AP must be disabled.""" - sap = self.android_devices[0] - sap.pretty_name = "SoftAP" - client = self.android_devices[1] - client.pretty_name = "Client" - - # start Soft AP - wutils.start_wifi_tethering(sap, self.SOFT_AP_SSID, self.SOFT_AP_PASSWORD, - band=WIFI_CONFIG_APBAND_5G, hidden=False) - - try: - # start scanning on the client - wutils.start_wifi_connection_scan_and_ensure_network_found(client, - self.SOFT_AP_SSID) - scans = client.droid.wifiGetScanResults() - scanned_softap = None - for scanned_ap in scans: - if scanned_ap[wutils.WifiEnums.SSID_KEY] == self.SOFT_AP_SSID: - scanned_softap = scanned_ap - break - - asserts.assert_false(scanned_softap == None, "Soft AP not found in scan!", - extras=scans) - - # validate that Soft AP does not advertise 802.11mc support - asserts.assert_false( - rconsts.SCAN_RESULT_KEY_RTT_RESPONDER in scanned_softap and - scanned_softap[rconsts.SCAN_RESULT_KEY_RTT_RESPONDER], - "Soft AP advertises itself as supporting 802.11mc!", - extras=scanned_softap) - - # falsify the SoftAP's support for IEEE 802.11 so we try a 2-sided RTT - scanned_softap[rconsts.SCAN_RESULT_KEY_RTT_RESPONDER] = True # falsify - - # actually try ranging to the Soft AP - events = rutils.run_ranging(client, [scanned_softap], self.NUM_ITER, 0) - 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) - - asserts.assert_equal( - stats[scanned_ap[wutils.WifiEnums.BSSID_KEY]]['num_failures'], - self.NUM_ITER, "Some RTT operations to Soft AP succeed!?", - extras=stats) - - asserts.explicit_pass("SoftAP + RTT validation done", extras=events) - finally: - wutils.stop_wifi_tethering(sap) + sap = self.android_devices[0] + sap.pretty_name = "SoftAP" + client = self.android_devices[1] + client.pretty_name = "Client" + + # start Soft AP + wutils.start_wifi_tethering( + sap, + self.SOFT_AP_SSID, + self.SOFT_AP_PASSWORD, + band=WIFI_CONFIG_APBAND_5G, + hidden=False) + + try: + # start scanning on the client + wutils.start_wifi_connection_scan_and_ensure_network_found( + client, self.SOFT_AP_SSID) + scans = client.droid.wifiGetScanResults() + scanned_softap = None + for scanned_ap in scans: + if scanned_ap[wutils.WifiEnums.SSID_KEY] == self.SOFT_AP_SSID: + scanned_softap = scanned_ap + break + + asserts.assert_false( + scanned_softap == None, + "Soft AP not found in scan!", + extras=scans) + + # validate that Soft AP does not advertise 802.11mc support + asserts.assert_false( + rconsts.SCAN_RESULT_KEY_RTT_RESPONDER in scanned_softap + and scanned_softap[rconsts.SCAN_RESULT_KEY_RTT_RESPONDER], + "Soft AP advertises itself as supporting 802.11mc!", + extras=scanned_softap) + + # falsify the SoftAP's support for IEEE 802.11 so we try a 2-sided RTT + scanned_softap[ + rconsts.SCAN_RESULT_KEY_RTT_RESPONDER] = True # falsify + + # actually try ranging to the Soft AP + events = rutils.run_ranging(client, [scanned_softap], + self.NUM_ITER, 0) + 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) + + asserts.assert_equal( + stats[scanned_ap[wutils.WifiEnums.BSSID_KEY]]['num_failures'], + self.NUM_ITER, + "Some RTT operations to Soft AP succeed!?", + extras=stats) + + asserts.explicit_pass( + "SoftAP + RTT validation done", extras=events) + finally: + wutils.stop_wifi_tethering(sap) diff --git a/acts/tests/google/wifi/rtt/functional/RttDisableTest.py b/acts/tests/google/wifi/rtt/functional/RttDisableTest.py index 1816cd5f14..be6f36ff60 100644 --- a/acts/tests/google/wifi/rtt/functional/RttDisableTest.py +++ b/acts/tests/google/wifi/rtt/functional/RttDisableTest.py @@ -24,86 +24,91 @@ from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest class RttDisableTest(WifiBaseTest, RttBaseTest): - """Test class for RTT ranging enable/disable flows.""" + """Test class for RTT ranging enable/disable flows.""" - MODE_DISABLE_WIFI = 0 - MODE_ENABLE_DOZE = 1 - MODE_DISABLE_LOCATIONING = 2 + MODE_DISABLE_WIFI = 0 + MODE_ENABLE_DOZE = 1 + MODE_DISABLE_LOCATIONING = 2 - def __init__(self, controllers): - WifiBaseTest.__init__(self, controllers) - RttBaseTest.__init__(self, controllers) - if "AccessPoint" in self.user_params: - self.legacy_configure_ap_and_start() + def __init__(self, controllers): + WifiBaseTest.__init__(self, controllers) + RttBaseTest.__init__(self, controllers) + if "AccessPoint" in self.user_params: + self.legacy_configure_ap_and_start() - def run_disable_rtt(self, disable_mode): - """Validate the RTT disabled flows: whether by disabling Wi-Fi or entering + def run_disable_rtt(self, disable_mode): + """Validate the RTT disabled flows: whether by disabling Wi-Fi or entering doze mode. Args: disable_mode: The particular mechanism in which RTT is disabled. One of the MODE_* constants. """ - dut = self.android_devices[0] - - # validate start-up conditions - asserts.assert_true(dut.droid.wifiIsRttAvailable(), "RTT is not available") - - # scan to get some APs to be used later - all_aps = rutils.select_best_scan_results(rutils.scan_networks(dut), - select_count=1) - asserts.assert_true(len(all_aps) > 0, "Need at least one visible AP!") - - # disable RTT and validate broadcast & API - if disable_mode == self.MODE_DISABLE_WIFI: - # disabling Wi-Fi is not sufficient: since scan mode (and hence RTT) will - # remain enabled - we need to disable the Wi-Fi chip aka Airplane Mode - asserts.assert_true(utils.force_airplane_mode(dut, True), - "Can not turn on airplane mode on: %s" % dut.serial) - elif disable_mode == self.MODE_ENABLE_DOZE: - asserts.assert_true(utils.enable_doze(dut), "Can't enable doze") - elif disable_mode == self.MODE_DISABLE_LOCATIONING: - utils.set_location_service(dut, False) - - rutils.wait_for_event(dut, rconsts.BROADCAST_WIFI_RTT_NOT_AVAILABLE) - asserts.assert_false(dut.droid.wifiIsRttAvailable(), "RTT is available") - - # request a range and validate error - id = dut.droid.wifiRttStartRangingToAccessPoints(all_aps[0:1]) - event = rutils.wait_for_event(dut, rutils.decorate_event( - rconsts.EVENT_CB_RANGING_ON_FAIL, id)) - asserts.assert_equal(event["data"][rconsts.EVENT_CB_RANGING_KEY_STATUS], - rconsts.RANGING_FAIL_CODE_RTT_NOT_AVAILABLE, - "Invalid error code") - - # enable RTT and validate broadcast & API - if disable_mode == self.MODE_DISABLE_WIFI: - asserts.assert_true(utils.force_airplane_mode(dut, False), - "Can not turn off airplane mode on: %s" % dut.serial) - elif disable_mode == self.MODE_ENABLE_DOZE: - asserts.assert_true(utils.disable_doze(dut), "Can't disable doze") - elif disable_mode == self.MODE_DISABLE_LOCATIONING: - utils.set_location_service(dut, True) - - rutils.wait_for_event(dut, rconsts.BROADCAST_WIFI_RTT_AVAILABLE) - asserts.assert_true(dut.droid.wifiIsRttAvailable(), "RTT is not available") - - ############################################################################ - - @test_tracker_info(uuid="498c49ab-a188-4612-998d-c47b35ff285e") - def test_disable_wifi(self): - """Validate that getting expected broadcast when Wi-Fi is disabled and that + dut = self.android_devices[0] + + # validate start-up conditions + asserts.assert_true(dut.droid.wifiIsRttAvailable(), + "RTT is not available") + + # scan to get some APs to be used later + all_aps = rutils.select_best_scan_results( + rutils.scan_networks(dut), select_count=1) + asserts.assert_true(len(all_aps) > 0, "Need at least one visible AP!") + + # disable RTT and validate broadcast & API + if disable_mode == self.MODE_DISABLE_WIFI: + # disabling Wi-Fi is not sufficient: since scan mode (and hence RTT) will + # remain enabled - we need to disable the Wi-Fi chip aka Airplane Mode + asserts.assert_true( + utils.force_airplane_mode(dut, True), + "Can not turn on airplane mode on: %s" % dut.serial) + elif disable_mode == self.MODE_ENABLE_DOZE: + asserts.assert_true(utils.enable_doze(dut), "Can't enable doze") + elif disable_mode == self.MODE_DISABLE_LOCATIONING: + utils.set_location_service(dut, False) + + rutils.wait_for_event(dut, rconsts.BROADCAST_WIFI_RTT_NOT_AVAILABLE) + asserts.assert_false(dut.droid.wifiIsRttAvailable(), + "RTT is available") + + # request a range and validate error + id = dut.droid.wifiRttStartRangingToAccessPoints(all_aps[0:1]) + event = rutils.wait_for_event( + dut, rutils.decorate_event(rconsts.EVENT_CB_RANGING_ON_FAIL, id)) + asserts.assert_equal( + event["data"][rconsts.EVENT_CB_RANGING_KEY_STATUS], + rconsts.RANGING_FAIL_CODE_RTT_NOT_AVAILABLE, "Invalid error code") + + # enable RTT and validate broadcast & API + if disable_mode == self.MODE_DISABLE_WIFI: + asserts.assert_true( + utils.force_airplane_mode(dut, False), + "Can not turn off airplane mode on: %s" % dut.serial) + elif disable_mode == self.MODE_ENABLE_DOZE: + asserts.assert_true(utils.disable_doze(dut), "Can't disable doze") + elif disable_mode == self.MODE_DISABLE_LOCATIONING: + utils.set_location_service(dut, True) + + rutils.wait_for_event(dut, rconsts.BROADCAST_WIFI_RTT_AVAILABLE) + asserts.assert_true(dut.droid.wifiIsRttAvailable(), + "RTT is not available") + + ############################################################################ + + @test_tracker_info(uuid="498c49ab-a188-4612-998d-c47b35ff285e") + def test_disable_wifi(self): + """Validate that getting expected broadcast when Wi-Fi is disabled and that any range requests are rejected.""" - self.run_disable_rtt(self.MODE_DISABLE_WIFI) + self.run_disable_rtt(self.MODE_DISABLE_WIFI) - @test_tracker_info(uuid="f71f731f-4aaf-402b-8595-db94b625b544") - def test_enable_doze(self): - """Validate that getting expected broadcast when RTT is disabled due to doze + @test_tracker_info(uuid="f71f731f-4aaf-402b-8595-db94b625b544") + def test_enable_doze(self): + """Validate that getting expected broadcast when RTT is disabled due to doze mode and that any range requests are rejected.""" - self.run_disable_rtt(self.MODE_ENABLE_DOZE) + self.run_disable_rtt(self.MODE_ENABLE_DOZE) - @test_tracker_info(uuid="6a1c83a8-9eaf-49db-b547-5131cba0eafe") - def test_disable_location(self): - """Validate that getting expected broadcast when locationing is disabled and + @test_tracker_info(uuid="6a1c83a8-9eaf-49db-b547-5131cba0eafe") + def test_disable_location(self): + """Validate that getting expected broadcast when locationing is disabled and that any range requests are rejected.""" - self.run_disable_rtt(self.MODE_DISABLE_LOCATIONING) + self.run_disable_rtt(self.MODE_DISABLE_LOCATIONING) diff --git a/acts/tests/google/wifi/rtt/functional/RttRequestManagementTest.py b/acts/tests/google/wifi/rtt/functional/RttRequestManagementTest.py index 82c1058bc2..48fdf5f578 100644 --- a/acts/tests/google/wifi/rtt/functional/RttRequestManagementTest.py +++ b/acts/tests/google/wifi/rtt/functional/RttRequestManagementTest.py @@ -25,18 +25,18 @@ from acts.test_utils.wifi.rtt.RttBaseTest import RttBaseTest class RttRequestManagementTest(RttBaseTest): - """Test class for RTT request management flows.""" + """Test class for RTT request management flows.""" - SPAMMING_LIMIT = 20 + SPAMMING_LIMIT = 20 - def __init__(self, controllers): - RttBaseTest.__init__(self, controllers) + def __init__(self, controllers): + RttBaseTest.__init__(self, controllers) - ############################################################################# + ############################################################################# - @test_tracker_info(uuid="29ff4a02-2952-47df-bf56-64f30c963093") - def test_cancel_ranging(self): - """Request a 'large' number of range operations with various UIDs (using the + @test_tracker_info(uuid="29ff4a02-2952-47df-bf56-64f30c963093") + 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 @@ -51,90 +51,99 @@ class RttRequestManagementTest(RttBaseTest): 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])) - - @test_tracker_info(uuid="48297480-c026-4780-8c13-476e7bea440c") - def test_throttling(self): - """Request sequential range operations using a bogus UID (which will + 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])) + + @test_tracker_info(uuid="48297480-c026-4780-8c13-476e7bea440c") + 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)) + 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)) diff --git a/acts/tests/google/wifi/rtt/stress/StressRangeApTest.py b/acts/tests/google/wifi/rtt/stress/StressRangeApTest.py index 497c125dcd..9f649820b3 100644 --- a/acts/tests/google/wifi/rtt/stress/StressRangeApTest.py +++ b/acts/tests/google/wifi/rtt/stress/StressRangeApTest.py @@ -21,59 +21,66 @@ from acts.test_utils.wifi.rtt.RttBaseTest import RttBaseTest class StressRangeApTest(RttBaseTest): - """Test class for stress testing of RTT ranging to Access Points""" + """Test class for stress testing of RTT ranging to Access Points""" - def __init__(self, controllers): - BaseTestClass.__init__(self, controllers) + def __init__(self, controllers): + BaseTestClass.__init__(self, controllers) - ############################################################################# + ############################################################################# - def test_rtt_supporting_ap_only(self): - """Scan for APs and perform RTT only to those which support 802.11mc. + 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) + 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 + 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] + 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) + 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) diff --git a/acts/tests/google/wifi/rtt/stress/StressRangeAwareTest.py b/acts/tests/google/wifi/rtt/stress/StressRangeAwareTest.py index 3073898c50..e5a4099527 100644 --- a/acts/tests/google/wifi/rtt/stress/StressRangeAwareTest.py +++ b/acts/tests/google/wifi/rtt/stress/StressRangeAwareTest.py @@ -27,29 +27,29 @@ from acts.test_utils.wifi.rtt.RttBaseTest import RttBaseTest class StressRangeAwareTest(AwareBaseTest, RttBaseTest): - """Test class for stress testing of RTT ranging to Wi-Fi Aware peers.""" - SERVICE_NAME = "GoogleTestServiceXY" + """Test class for stress testing of RTT ranging to Wi-Fi Aware peers.""" + SERVICE_NAME = "GoogleTestServiceXY" - def __init__(self, controllers): - AwareBaseTest.__init__(self, controllers) - RttBaseTest.__init__(self, controllers) + def __init__(self, controllers): + AwareBaseTest.__init__(self, controllers) + RttBaseTest.__init__(self, controllers) - def setup_test(self): - """Manual setup here due to multiple inheritance: explicitly execute the + def setup_test(self): + """Manual setup here due to multiple inheritance: explicitly execute the setup method from both parents.""" - AwareBaseTest.setup_test(self) - RttBaseTest.setup_test(self) + AwareBaseTest.setup_test(self) + RttBaseTest.setup_test(self) - def teardown_test(self): - """Manual teardown here due to multiple inheritance: explicitly execute the + def teardown_test(self): + """Manual teardown here due to multiple inheritance: explicitly execute the teardown method from both parents.""" - AwareBaseTest.teardown_test(self) - RttBaseTest.teardown_test(self) + AwareBaseTest.teardown_test(self) + RttBaseTest.teardown_test(self) - ############################################################################# + ############################################################################# - def run_rtt_discovery(self, init_dut, resp_mac=None, resp_peer_id=None): - """Perform single RTT measurement, using Aware, from the Initiator DUT to + def run_rtt_discovery(self, init_dut, resp_mac=None, resp_peer_id=None): + """Perform single RTT measurement, using Aware, from the Initiator DUT to a Responder. The RTT Responder can be specified using its MAC address (obtained using out- of-band discovery) or its Peer ID (using Aware discovery). @@ -59,79 +59,93 @@ class StressRangeAwareTest(AwareBaseTest, RttBaseTest): resp_mac: MAC address of the RTT Responder device resp_peer_id: Peer ID of the RTT Responder device """ - asserts.assert_true(resp_mac is not None or resp_peer_id is not None, - "One of the Responder specifications (MAC or Peer ID)" - " must be provided!") - if resp_mac is not None: - id = init_dut.droid.wifiRttStartRangingToAwarePeerMac(resp_mac) - else: - id = init_dut.droid.wifiRttStartRangingToAwarePeerId(resp_peer_id) - try: - event = init_dut.ed.pop_event(rutils.decorate_event( - rconsts.EVENT_CB_RANGING_ON_RESULT, id), rutils.EVENT_TIMEOUT) - result = event["data"][rconsts.EVENT_CB_RANGING_KEY_RESULTS][0] - if resp_mac is not None: - rutils.validate_aware_mac_result(result, resp_mac, "DUT") - else: - rutils.validate_aware_peer_id_result(result, resp_peer_id, "DUT") - return result - except queue.Empty: - return None - - def test_stress_rtt_ib_discovery_set(self): - """Perform a set of RTT measurements, using in-band (Aware) discovery, and + asserts.assert_true( + resp_mac is not None or resp_peer_id is not None, + "One of the Responder specifications (MAC or Peer ID)" + " must be provided!") + if resp_mac is not None: + id = init_dut.droid.wifiRttStartRangingToAwarePeerMac(resp_mac) + else: + id = init_dut.droid.wifiRttStartRangingToAwarePeerId(resp_peer_id) + try: + event = init_dut.ed.pop_event( + rutils.decorate_event(rconsts.EVENT_CB_RANGING_ON_RESULT, id), + rutils.EVENT_TIMEOUT) + result = event["data"][rconsts.EVENT_CB_RANGING_KEY_RESULTS][0] + if resp_mac is not None: + rutils.validate_aware_mac_result(result, resp_mac, "DUT") + else: + rutils.validate_aware_peer_id_result(result, resp_peer_id, + "DUT") + return result + except queue.Empty: + return None + + def test_stress_rtt_ib_discovery_set(self): + """Perform a set of RTT measurements, using in-band (Aware) discovery, and switching Initiator and Responder roles repeatedly. Stress test: repeat ranging operations. Verify rate of success and stability of results. """ - p_dut = self.android_devices[0] - s_dut = self.android_devices[1] - - (p_id, s_id, p_disc_id, s_disc_id, - peer_id_on_sub, peer_id_on_pub) = autils.create_discovery_pair( - p_dut, - s_dut, - p_config=autils.add_ranging_to_pub(autils.create_discovery_config( - self.SERVICE_NAME, aconsts.PUBLISH_TYPE_UNSOLICITED), True), - s_config=autils.add_ranging_to_pub(autils.create_discovery_config( - self.SERVICE_NAME, aconsts.SUBSCRIBE_TYPE_PASSIVE), True), - device_startup_offset=self.device_startup_offset, - msg_id=self.get_next_msg_id()) - - results = [] - start_clock = time.time() - iterations_done = 0 - run_time = 0 - while iterations_done < self.stress_test_min_iteration_count or ( - self.stress_test_target_run_time_sec != 0 - and run_time < self.stress_test_target_run_time_sec): - results.append(self.run_rtt_discovery(p_dut, resp_peer_id=peer_id_on_pub)) - results.append(self.run_rtt_discovery(s_dut, resp_peer_id=peer_id_on_sub)) - - iterations_done = iterations_done + 1 - run_time = time.time() - start_clock - - stats = rutils.extract_stats(results, self.rtt_reference_distance_mm, - self.rtt_reference_distance_margin_mm, - self.rtt_min_expected_rssi_dbm, - summary_only=True) - self.log.debug("Stats: %s", stats) - asserts.assert_true(stats['num_no_results'] == 0, - "Missing (timed-out) results", extras=stats) - asserts.assert_false(stats['any_lci_mismatch'], - "LCI mismatch", extras=stats) - asserts.assert_false(stats['any_lcr_mismatch'], - "LCR mismatch", extras=stats) - asserts.assert_equal(stats['num_invalid_rssi'], 0, "Invalid RSSI", - extras=stats) - asserts.assert_true( - stats['num_failures'] <= - self.rtt_max_failure_rate_two_sided_rtt_percentage - * stats['num_results'] / 100, - "Failure rate is too high", extras=stats) - asserts.assert_true( - stats['num_range_out_of_margin'] - <= self.rtt_max_margin_exceeded_rate_two_sided_rtt_percentage - * stats['num_success_results'] / 100, - "Results exceeding error margin rate is too high", extras=stats) + p_dut = self.android_devices[0] + s_dut = self.android_devices[1] + + (p_id, s_id, p_disc_id, s_disc_id, peer_id_on_sub, + peer_id_on_pub) = autils.create_discovery_pair( + p_dut, + s_dut, + p_config=autils.add_ranging_to_pub( + autils.create_discovery_config( + self.SERVICE_NAME, aconsts.PUBLISH_TYPE_UNSOLICITED), + True), + s_config=autils.add_ranging_to_pub( + autils.create_discovery_config( + self.SERVICE_NAME, aconsts.SUBSCRIBE_TYPE_PASSIVE), True), + device_startup_offset=self.device_startup_offset, + msg_id=self.get_next_msg_id()) + + results = [] + start_clock = time.time() + iterations_done = 0 + run_time = 0 + while iterations_done < self.stress_test_min_iteration_count or ( + self.stress_test_target_run_time_sec != 0 + and run_time < self.stress_test_target_run_time_sec): + results.append( + self.run_rtt_discovery(p_dut, resp_peer_id=peer_id_on_pub)) + results.append( + self.run_rtt_discovery(s_dut, resp_peer_id=peer_id_on_sub)) + + iterations_done = iterations_done + 1 + run_time = time.time() - start_clock + + stats = rutils.extract_stats( + results, + self.rtt_reference_distance_mm, + self.rtt_reference_distance_margin_mm, + self.rtt_min_expected_rssi_dbm, + summary_only=True) + self.log.debug("Stats: %s", stats) + asserts.assert_true( + stats['num_no_results'] == 0, + "Missing (timed-out) results", + extras=stats) + asserts.assert_false( + stats['any_lci_mismatch'], "LCI mismatch", extras=stats) + asserts.assert_false( + stats['any_lcr_mismatch'], "LCR mismatch", extras=stats) + asserts.assert_equal( + stats['num_invalid_rssi'], 0, "Invalid RSSI", extras=stats) + asserts.assert_true( + stats['num_failures'] <= + self.rtt_max_failure_rate_two_sided_rtt_percentage * + stats['num_results'] / 100, + "Failure rate is too high", + extras=stats) + asserts.assert_true( + stats['num_range_out_of_margin'] <= + self.rtt_max_margin_exceeded_rate_two_sided_rtt_percentage * + stats['num_success_results'] / 100, + "Results exceeding error margin rate is too high", + extras=stats) |