diff options
Diffstat (limited to 'acts')
212 files changed, 5091 insertions, 36267 deletions
diff --git a/acts/README.md b/acts/README.md index a4e9950e11..55c69b8a74 100644 --- a/acts/README.md +++ b/acts/README.md @@ -5,7 +5,7 @@ devices. It provides a simple execution interface; a set of pluggable libraries for accessing commercially avilable devices, Android devices, and a collection of utility functions to further ease test development. It is an ideal desktop tool for a wireless stack developer or integrator whether exercising a new code -path, performing sanity testing, or running extended regression test suites. +path, performing confidence testing, or running extended regression test suites. Included in the tests/google directory are a bundle of tests, many of which can be run with as little as one or two Android devices with wifi, cellular, or @@ -76,7 +76,7 @@ displayed. Check the "Always" box and click "Yes". 2. Run "python3.4 setup.py install" with elevated permissions 3. To verify ACTS is ready to go, at the location for README, and run: cd framework/tests/ \ - && act.py -c acts_sanity_test_config.json -tc IntegrationTest + && act.py -c acts_confidence_test_config.json -tc IntegrationTest After installation, `act.py` will be in usr/bin and can be called as command line utilities. Components in ACTS are importable under the package "acts." @@ -90,11 +90,11 @@ $ python ## Breaking Down a Sample Command -Above, the command `act.py -c acts_sanity_test_config.json -tc IntegrationTest` +Above, the command `act.py -c acts_confidence_test_config.json -tc IntegrationTest` was run to verify ACTS was properly set up. Below are the components of that command: - `act.py`: is the script that runs the test -- -c acts_sanity_test_config: is the flag and name of the configuration file +- -c acts_confidence_test_config: is the flag and name of the configuration file to be used in the test - -tc IntegrationTest: is the name of the test case diff --git a/acts/framework/MANIFEST.in b/acts/framework/MANIFEST.in index f6607fdca6..03536f5be2 100644 --- a/acts/framework/MANIFEST.in +++ b/acts/framework/MANIFEST.in @@ -1,6 +1,5 @@ include setup.py README.txt sample_config.json -recursive-include acts *.py +recursive-include acts * recursive-include tests * global-exclude .DS_Store global-exclude *.pyc - diff --git a/acts/framework/acts/controllers/OWNERS b/acts/framework/acts/controllers/OWNERS index 9b32fd0c5d..ef0ddca385 100644 --- a/acts/framework/acts/controllers/OWNERS +++ b/acts/framework/acts/controllers/OWNERS @@ -1,2 +1,3 @@ per-file fuchsia_device.py = tturney@google.com,jmbrenna@google.com per-file bluetooth_pts_device.py = tturney@google.com +per-file cellular_simulator.py = iguarna@google.com, chaoyangf@google.com, codycaldwell@google.com, yixiang@google.com
\ No newline at end of file diff --git a/acts/framework/acts/controllers/__init__.py b/acts/framework/acts/controllers/__init__.py index 1c8ed4ca00..b805e9e206 100644 --- a/acts/framework/acts/controllers/__init__.py +++ b/acts/framework/acts/controllers/__init__.py @@ -26,5 +26,5 @@ def destroy(objs): __all__ = [ "android_device", "attenuator", "bluetooth_pts_device", "monsoon", "access_point", "iperf_server", "packet_sender", "arduino_wifi_dongle", - "packet_capture", "fuchsia_device", "pdu" + "packet_capture", "fuchsia_device", "pdu", "openwrt_ap" ] diff --git a/acts/framework/acts/controllers/access_point.py b/acts/framework/acts/controllers/access_point.py index 15a3ca05f1..38e59d7248 100755 --- a/acts/framework/acts/controllers/access_point.py +++ b/acts/framework/acts/controllers/access_point.py @@ -120,6 +120,7 @@ class AccessPoint(object): self.log = logger.create_logger(lambda msg: '[Access Point|%s] %s' % (self.ssh_settings.hostname, msg)) self.device_pdu_config = configs.get('PduDevice', None) + self.identifier = self.ssh_settings.hostname if 'ap_subnet' in configs: self._AP_2G_SUBNET_STR = configs['ap_subnet']['2g'] @@ -573,25 +574,38 @@ class AccessPoint(object): if ra_count_str: return int(ra_count_str.split()[1]) - def is_pingable(self): - """Attempts to ping the access point. - - Returns: - True if ping is successful, else False + def ping(self, + dest_ip, + count=3, + interval=1000, + timeout=1000, + size=56, + additional_ping_params=None): + """Pings from AP to dest_ip, returns dict of ping stats (see utils.ping) """ - return utils.is_pingable(self.ssh_settings.hostname) - - def is_sshable(self): - """Attempts to run command via ssh. - - Returns: - True if no exceptions, else False - """ - try: - self.ssh.run('echo') - except connection.Error: - return False - return True + return utils.ping(self.ssh, + dest_ip, + count=count, + interval=interval, + timeout=timeout, + size=size, + additional_ping_params=additional_ping_params) + + def can_ping(self, + dest_ip, + count=1, + interval=1000, + timeout=1000, + size=56, + additional_ping_params=None): + """Returns whether ap can ping dest_ip (see utils.can_ping)""" + return utils.can_ping(self.ssh, + dest_ip, + count=count, + interval=interval, + timeout=timeout, + size=size, + additional_ping_params=additional_ping_params) def hard_power_cycle(self, pdus, @@ -608,12 +622,12 @@ class AccessPoint(object): unreachable ping_timeout: int, time to wait for AccessPoint to responsd to pings ssh_timeout: int, time to wait for AccessPoint to allow SSH - hostapd_configs (optional): list, containing hostapd settings. If + hostapd_configs (optional): list, containing hostapd settings. If present, these networks will be spun up after the AP has rebooted. This list can either contain HostapdConfig objects, or - dictionaries with the start_ap params - (i.e { 'hostapd_config': <HostapdConfig>, - 'setup_bridge': <bool>, + dictionaries with the start_ap params + (i.e { 'hostapd_config': <HostapdConfig>, + 'setup_bridge': <bool>, 'additional_parameters': <dict> } ). Raise: Error, if no PduDevice is provided in AccessPoint config. @@ -637,7 +651,7 @@ class AccessPoint(object): self.log.info('Verifying AccessPoint is unreachable.') timeout = time.time() + unreachable_timeout while time.time() < timeout: - if not self.is_pingable(): + if not utils.can_ping(job, self.ssh_settings.hostname): self.log.info('AccessPoint is unreachable as expected.') break else: @@ -657,7 +671,7 @@ class AccessPoint(object): self.log.info('Waiting for AccessPoint to respond to pings.') timeout = time.time() + ping_timeout while time.time() < timeout: - if self.is_pingable(): + if utils.can_ping(job, self.ssh_settings.hostname): self.log.info('AccessPoint responded to pings.') break else: @@ -672,13 +686,15 @@ class AccessPoint(object): self.log.info('Waiting for AccessPoint to allow ssh connection.') timeout = time.time() + ssh_timeout while time.time() < timeout: - if self.is_sshable(): - self.log.info('AccessPoint available via ssh.') - break - else: + try: + self.ssh.run('echo') + except connection.Error: self.log.debug('AccessPoint is not allowing ssh connection. ' 'Retrying in 1 second.') time.sleep(1) + else: + self.log.info('AccessPoint available via ssh.') + break else: raise ConnectionError('Timed out waiting for AccessPoint (%s) to ' 'allow ssh connection.' % diff --git a/acts/framework/acts/controllers/adb.py b/acts/framework/acts/controllers/adb.py index ff1a2ab9b3..1d15e07e58 100644 --- a/acts/framework/acts/controllers/adb.py +++ b/acts/framework/acts/controllers/adb.py @@ -19,6 +19,7 @@ from builtins import str import logging import re import shlex +import shutil from acts.controllers.adb_lib.error import AdbError from acts.libs.proc import job @@ -73,7 +74,7 @@ class AdbProxy(object): """ self.serial = serial self._server_local_port = None - adb_path = job.run("which adb").stdout + adb_path = shutil.which('adb') adb_cmd = [shlex.quote(adb_path)] if serial: adb_cmd.append("-s %s" % serial) @@ -259,17 +260,12 @@ class AdbProxy(object): def shell_nb(self, command): return self._exec_adb_cmd_nb('shell', shlex.quote(command)) - def pull(self, - command, - ignore_status=False, - timeout=DEFAULT_ADB_PULL_TIMEOUT): - return self._exec_adb_cmd( - 'pull', command, ignore_status=ignore_status, timeout=timeout) - def __getattr__(self, name): def adb_call(*args, **kwargs): usage_metadata_logger.log_usage(self.__module__, name) clean_name = name.replace('_', '-') + if clean_name in ['pull', 'push'] and 'timeout' not in kwargs: + kwargs['timeout'] = DEFAULT_ADB_PULL_TIMEOUT arg_str = ' '.join(str(elem) for elem in args) return self._exec_adb_cmd(clean_name, arg_str, **kwargs) diff --git a/acts/framework/acts/controllers/anritsu_lib/OWNERS b/acts/framework/acts/controllers/anritsu_lib/OWNERS new file mode 100644 index 0000000000..e4010df218 --- /dev/null +++ b/acts/framework/acts/controllers/anritsu_lib/OWNERS @@ -0,0 +1,4 @@ +iguarna@google.com +chaoyangf@google.com +yixiang@google.com +codycaldwell@google.com
\ No newline at end of file diff --git a/acts/framework/acts/controllers/anritsu_lib/band_constants.py b/acts/framework/acts/controllers/anritsu_lib/band_constants.py new file mode 100644 index 0000000000..c7f5771e54 --- /dev/null +++ b/acts/framework/acts/controllers/anritsu_lib/band_constants.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python3 +# +# Copyright 2020 - The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# GSM BAND constants +GSM_BAND_GSM450 = "GSM450" +GSM_BAND_GSM480 = "GSM480" +GSM_BAND_GSM850 = "GSM850" +GSM_BAND_PGSM900 = "P-GSM900" +GSM_BAND_EGSM900 = "E-GSM900" +GSM_BAND_RGSM900 = "R-GSM900" +GSM_BAND_DCS1800 = "DCS1800" +GSM_BAND_PCS1900 = "PCS1900" + +LTE_BAND_2 = 2 +LTE_BAND_4 = 4 +LTE_BAND_12 = 12 +WCDMA_BAND_1 = 1 +WCDMA_BAND_2 = 2 diff --git a/acts/framework/acts/controllers/anritsu_lib/cell_configurations.py b/acts/framework/acts/controllers/anritsu_lib/cell_configurations.py index a8d79b5ebe..636b03f0a6 100644 --- a/acts/framework/acts/controllers/anritsu_lib/cell_configurations.py +++ b/acts/framework/acts/controllers/anritsu_lib/cell_configurations.py @@ -16,14 +16,14 @@ """ Sanity tests for voice tests in telephony """ +from acts.controllers.anritsu_lib.band_constants import GSM_BAND_PCS1900 +from acts.controllers.anritsu_lib.band_constants import GSM_BAND_GSM850 +from acts.controllers.anritsu_lib.band_constants import LTE_BAND_2 +from acts.controllers.anritsu_lib.band_constants import LTE_BAND_4 +from acts.controllers.anritsu_lib.band_constants import LTE_BAND_12 +from acts.controllers.anritsu_lib.band_constants import WCDMA_BAND_1 +from acts.controllers.anritsu_lib.band_constants import WCDMA_BAND_2 from acts.controllers.anritsu_lib.md8475a import BtsBandwidth -from acts.test_utils.tel.anritsu_utils import GSM_BAND_PCS1900 -from acts.test_utils.tel.anritsu_utils import GSM_BAND_GSM850 -from acts.test_utils.tel.anritsu_utils import LTE_BAND_2 -from acts.test_utils.tel.anritsu_utils import LTE_BAND_4 -from acts.test_utils.tel.anritsu_utils import LTE_BAND_12 -from acts.test_utils.tel.anritsu_utils import WCDMA_BAND_1 -from acts.test_utils.tel.anritsu_utils import WCDMA_BAND_2 # Different Cell configurations # TMO bands diff --git a/acts/framework/acts/controllers/anritsu_lib/md8475_cellular_simulator.py b/acts/framework/acts/controllers/anritsu_lib/md8475_cellular_simulator.py index 98a779a89f..eea1c8a291 100644 --- a/acts/framework/acts/controllers/anritsu_lib/md8475_cellular_simulator.py +++ b/acts/framework/acts/controllers/anritsu_lib/md8475_cellular_simulator.py @@ -18,7 +18,7 @@ import math import ntpath import time import acts.controllers.cellular_simulator as cc -from acts.test_utils.power.tel_simulations import LteSimulation +from acts.controllers.cellular_lib import LteSimulation from acts.controllers.anritsu_lib import md8475a from acts.controllers.anritsu_lib import _anritsu_utils as anritsu diff --git a/acts/framework/acts/controllers/ap_lib/hostapd.py b/acts/framework/acts/controllers/ap_lib/hostapd.py index f8c3734f57..92b5ca31a7 100644 --- a/acts/framework/acts/controllers/ap_lib/hostapd.py +++ b/acts/framework/acts/controllers/ap_lib/hostapd.py @@ -86,7 +86,8 @@ class Hostapd(object): hostapd_command = '%s -dd -t "%s"' % (self.PROGRAM_FILE, self._config_file) base_command = 'cd "%s"; %s' % (self._working_dir, hostapd_command) - job_str = '%s > "%s" 2>&1' % (base_command, self._log_file) + job_str = 'rfkill unblock all; %s > "%s" 2>&1' %\ + (base_command, self._log_file) self._runner.run_async(job_str) try: diff --git a/acts/framework/acts/controllers/buds_lib/apollo_lib.py b/acts/framework/acts/controllers/buds_lib/apollo_lib.py index 9b971ffa24..7b0f80f370 100644 --- a/acts/framework/acts/controllers/buds_lib/apollo_lib.py +++ b/acts/framework/acts/controllers/buds_lib/apollo_lib.py @@ -46,7 +46,7 @@ import subprocess import time import serial -from acts import tracelogger +from acts.controllers.buds_lib import tako_trace_logger from acts.controllers.buds_lib import logserial from acts.controllers.buds_lib.b29_lib import B29Device from acts.controllers.buds_lib.dev_utils import apollo_log_decoder @@ -55,7 +55,7 @@ from acts.controllers.buds_lib.dev_utils import apollo_sink_events from logging import Logger from retry import retry -logging = tracelogger.TakoTraceLogger(Logger('apollo')) +logging = tako_trace_logger.TakoTraceLogger(Logger('apollo')) BAUD_RATE = 115200 BYTE_SIZE = 8 diff --git a/acts/framework/acts/controllers/buds_lib/b29_lib.py b/acts/framework/acts/controllers/buds_lib/b29_lib.py index bb4ea7d76c..df6a16361c 100644 --- a/acts/framework/acts/controllers/buds_lib/b29_lib.py +++ b/acts/framework/acts/controllers/buds_lib/b29_lib.py @@ -28,12 +28,12 @@ fBvw0sXkgwCBkshU_l4SxWkKgAxVmk/edit for details about available operations. import os import re import time +from logging import Logger -from acts import tracelogger from acts import utils -from logging import Logger +from acts.controllers.buds_lib import tako_trace_logger -logging = tracelogger.TakoTraceLogger(Logger(__file__)) +logging = tako_trace_logger.TakoTraceLogger(Logger(__file__)) DEVICE_REGEX = ( r'_(?P<device_serial>[A-Z0-9]+)-(?P<interface>\w+)\s->\s' r'(\.\./){2}(?P<port>\w+)' diff --git a/acts/framework/acts/controllers/buds_lib/logserial.py b/acts/framework/acts/controllers/buds_lib/logserial.py index 58bf15431d..6b18e3cfc0 100644 --- a/acts/framework/acts/controllers/buds_lib/logserial.py +++ b/acts/framework/acts/controllers/buds_lib/logserial.py @@ -21,15 +21,15 @@ import subprocess import sys import time import uuid +from logging import Logger from threading import Thread import serial from serial.tools import list_ports -from acts import tracelogger -from logging import Logger +from acts.controllers.buds_lib import tako_trace_logger -logging = tracelogger.TakoTraceLogger(Logger(__file__)) +logging = tako_trace_logger.TakoTraceLogger(Logger(__file__)) RETRIES = 0 diff --git a/acts/framework/acts/controllers/buds_lib/tako_trace_logger.py b/acts/framework/acts/controllers/buds_lib/tako_trace_logger.py new file mode 100644 index 0000000000..ff3184056c --- /dev/null +++ b/acts/framework/acts/controllers/buds_lib/tako_trace_logger.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 +# +# Copyright 2019 - The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import logging + +from acts import tracelogger + + +class TakoTraceLogger(tracelogger.TraceLogger): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.d = self.debug + self.e = self.error + self.i = self.info + self.t = self.step + self.w = self.warning + + def _logger_level(self, level_name): + level = logging.getLevelName(level_name) + return lambda *args, **kwargs: self._logger.log(level, *args, **kwargs) + + def step(self, msg, *args, **kwargs): + """Delegate a step call to the underlying logger.""" + self._log_with(self._logger_level('STEP'), 1, msg, *args, **kwargs) + + def device(self, msg, *args, **kwargs): + """Delegate a device call to the underlying logger.""" + self._log_with(self._logger_level('DEVICE'), 1, msg, *args, **kwargs) + + def suite(self, msg, *args, **kwargs): + """Delegate a device call to the underlying logger.""" + self._log_with(self._logger_level('SUITE'), 1, msg, *args, **kwargs) + + def case(self, msg, *args, **kwargs): + """Delegate a case call to the underlying logger.""" + self._log_with(self._logger_level('CASE'), 1, msg, *args, **kwargs) + + def flush_log(self): + """This function exists for compatibility with Tako's logserial module. + + Note that flushing the log is handled automatically by python's logging + module. + """ + pass diff --git a/acts/framework/acts/controllers/buds_lib/test_actions/audio_utils.py b/acts/framework/acts/controllers/buds_lib/test_actions/audio_utils.py index 42f8c46309..e94fc52e4a 100644 --- a/acts/framework/acts/controllers/buds_lib/test_actions/audio_utils.py +++ b/acts/framework/acts/controllers/buds_lib/test_actions/audio_utils.py @@ -19,8 +19,8 @@ import datetime import time -from acts import tracelogger from acts import utils +from acts.controllers.buds_lib import tako_trace_logger class AudioUtilsError(Exception): @@ -36,7 +36,7 @@ class AudioUtils(object): """ def __init__(self): - self.logger = tracelogger.TakoTraceLogger() + self.logger = tako_trace_logger.TakoTraceLogger() def play_audio_into_device(self, audio_file_path, audio_player, dut): """Open mic on DUT, play audio into DUT, close mic on DUT. diff --git a/acts/framework/acts/controllers/buds_lib/test_actions/base_test_actions.py b/acts/framework/acts/controllers/buds_lib/test_actions/base_test_actions.py index 7b6cbc4c0d..8f4b37a1bb 100644 --- a/acts/framework/acts/controllers/buds_lib/test_actions/base_test_actions.py +++ b/acts/framework/acts/controllers/buds_lib/test_actions/base_test_actions.py @@ -22,7 +22,7 @@ import datetime import inspect import time -from acts import tracelogger +from acts.controllers.buds_lib import tako_trace_logger from acts.libs.utils.timer import TimeRecorder # All methods start with "_" are considered hidden. @@ -37,7 +37,7 @@ def timed_action(method): func_name = self._convert_default_action_name(method.__name__) if not func_name: func_name = method.__name__ - self.logger.step('%s...' % func_name) + self.log_step('%s...' % func_name) self.timer.start_timer(func_name, True) result = method(self, *args, **kw) # TODO: Method run time collected can be used for automatic KPI checks @@ -135,9 +135,11 @@ class BaseTestAction(object): def __init__(self, logger=None): if logger is None: - self.logger = tracelogger.TakoTraceLogger() + self.logger = tako_trace_logger.TakoTraceLogger() + self.log_step = self.logger.step else: self.logger = logger + self.log_step = self.logger.info self.timer = TimeRecorder() self._fill_default_action_map() @@ -172,15 +174,16 @@ class BaseTestAction(object): exceptions """ num_acts = len(self._action_map) - self.logger.i('I can do %d action%s:' % + + self.logger.info('I can do %d action%s:' % (num_acts, 's' if num_acts != 1 else '')) for act in self._action_map.keys(): - self.logger.i(' - %s' % act) + self.logger.info(' - %s' % act) return True @timed_action def sleep(self, seconds): - self.logger.i('%s seconds' % seconds) + self.logger.info('%s seconds' % seconds) time.sleep(seconds) diff --git a/acts/framework/acts/controllers/buds_lib/test_actions/bt_utils.py b/acts/framework/acts/controllers/buds_lib/test_actions/bt_utils.py index 258240228a..f0ac04140c 100644 --- a/acts/framework/acts/controllers/buds_lib/test_actions/bt_utils.py +++ b/acts/framework/acts/controllers/buds_lib/test_actions/bt_utils.py @@ -31,11 +31,12 @@ device that supports the following calls: """ import queue import time +from logging import Logger -from acts import tracelogger -from acts.utils import wait_until +from acts import asserts +from acts.controllers.buds_lib import tako_trace_logger from acts.utils import TimeoutError -from logging import Logger +from acts.utils import wait_until # Add connection profile for future devices in this dictionary WEARABLE_BT_PROTOCOLS = { @@ -69,7 +70,7 @@ class BTUtils(object): def __init__(self): self.default_timeout = 60 - self.logger = tracelogger.TakoTraceLogger(Logger(__file__)) + self.logger = tako_trace_logger.TakoTraceLogger(Logger(__file__)) def bt_pair_and_connect(self, pri_device, sec_device): """Pair and connect a pri_device to a sec_device. @@ -198,8 +199,9 @@ class BTUtils(object): return True, 0 self.logger.debug('Unpairing from %s' % target_address) start_time = end_time = time.time() - assert (True is pri_device.droid.bluetoothUnbond(target_address), - 'Failed to request device unpairing.') + asserts.assert_true( + pri_device.droid.bluetoothUnbond(target_address), + 'Failed to request device unpairing.') # Check that devices have unpaired successfully. self.logger.debug('Verifying devices are unpaired') @@ -290,4 +292,3 @@ class BTUtils(object): if expected[key] != actual[key]: return False return True - diff --git a/acts/framework/acts/controllers/cellular_lib/AndroidCellularDut.py b/acts/framework/acts/controllers/cellular_lib/AndroidCellularDut.py new file mode 100644 index 0000000000..aaef6f5a0a --- /dev/null +++ b/acts/framework/acts/controllers/cellular_lib/AndroidCellularDut.py @@ -0,0 +1,95 @@ +#!/usr/bin/env python3 +# +# Copyright 2020 - The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from acts.controllers.cellular_lib import BaseCellularDut +from acts.test_utils.tel import tel_test_utils as tel_utils +from acts.test_utils.tel import tel_defines + + +class AndroidCellularDut(BaseCellularDut.BaseCellularDut): + """ Android implementation of the cellular DUT class.""" + def __init__(self, ad, logger): + """ Keeps a handler to the android device. + + Args: + ad: Android device handler + logger: a handler to the logger object + """ + self.ad = ad + self.log = logger + + def toggle_airplane_mode(self, new_state=True): + """ Turns airplane mode on / off. + + Args: + new_state: True if airplane mode needs to be enabled. + """ + tel_utils.toggle_airplane_mode(self.log, self.ad, new_state) + + def toggle_data_roaming(self, new_state=True): + """ Enables or disables cellular data roaming. + + Args: + new_state: True if data roaming needs to be enabled. + """ + tel_utils.toggle_cell_data_roaming(self.ad, new_state) + + def get_rx_tx_power_levels(self): + """ Obtains Rx and Tx power levels measured from the DUT. + + Returns: + A tuple where the first element is an array with the RSRP value + in each Rx chain, and the second element is the Tx power in dBm. + Values for invalid or disabled Rx / Tx chains are set to None. + """ + return tel_utils.get_rx_tx_power_levels(self.log, self.ad) + + def set_apn(self, name, apn, type='default'): + """ Sets the Access Point Name. + + Args: + name: the APN name + apn: the APN + type: the APN type + """ + self.ad.droid.telephonySetAPN(name, apn, type) + + def set_preferred_network_type(self, type): + """ Sets the preferred RAT. + + Args: + type: an instance of class PreferredNetworkType + """ + if type == BaseCellularDut.PreferredNetworkType.LTE_ONLY: + formatted_type = tel_defines.NETWORK_MODE_LTE_ONLY + elif type == BaseCellularDut.PreferredNetworkType.WCDMA_ONLY: + formatted_type = tel_defines.NETWORK_MODE_WCDMA_ONLY + elif type == BaseCellularDut.PreferredNetworkType.GSM_ONLY: + formatted_type = tel_defines.NETWORK_MODE_GSM_ONLY + else: + raise ValueError('Invalid RAT type.') + + if not self.ad.droid.telephonySetPreferredNetworkTypesForSubscription( + formatted_type, self.ad.droid.subscriptionGetDefaultSubId()): + self.log.error("Could not set preferred network type.") + else: + self.log.info("Preferred network type set.") + + def get_telephony_signal_strength(self): + """ Wrapper for the method with the same name in tel_utils. + + Will be deprecated and replaced by get_rx_tx_power_levels. """ + tel_utils.get_telephony_signal_strength(self.ad) diff --git a/acts/framework/acts/controllers/cellular_lib/BaseCellularDut.py b/acts/framework/acts/controllers/cellular_lib/BaseCellularDut.py new file mode 100644 index 0000000000..31c19fa9c5 --- /dev/null +++ b/acts/framework/acts/controllers/cellular_lib/BaseCellularDut.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python3 +# +# Copyright 2020 - The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from enum import Enum + + +class PreferredNetworkType(Enum): + """ Available preferred network types that can be passed to + set_preferred_network_type""" + LTE_ONLY = 'lte-only' + GSM_ONLY = 'gsm-only' + WCDMA_ONLY = 'wcdma-only' + + +class BaseCellularDut(): + """ Base class for DUTs used with cellular simulators. """ + def toggle_airplane_mode(self, new_state=True): + """ Turns airplane mode on / off. + + Args: + new_state: True if airplane mode needs to be enabled. + """ + raise NotImplementedError() + + def toggle_data_roaming(self, new_state=True): + """ Enables or disables cellular data roaming. + + Args: + new_state: True if data roaming needs to be enabled. + """ + raise NotImplementedError() + + def get_rx_tx_power_levels(self): + """ Obtains Rx and Tx power levels measured from the DUT. + + Returns: + A tuple where the first element is an array with the RSRP value + in each Rx chain, and the second element is the Tx power in dBm. + Values for invalid or disabled Rx / Tx chains are set to None. + """ + raise NotImplementedError() + + def set_apn(self, name, apn, type='default'): + """ Sets the Access Point Name. + + Args: + name: the APN name + apn: the APN + type: the APN type + """ + raise NotImplementedError() + + def set_preferred_network_type(self, type): + """ Sets the preferred RAT. + + Args: + type: an instance of class PreferredNetworkType + """ + raise NotImplementedError() + + def get_telephony_signal_strength(self): + """ Wrapper for the method with the same name in tel_utils. + + Will be deprecated and replaced by get_rx_tx_power_levels. """ + raise NotImplementedError() diff --git a/acts/framework/acts/test_utils/power/tel_simulations/BaseSimulation.py b/acts/framework/acts/controllers/cellular_lib/BaseSimulation.py index 7d38caeb95..9cc091f2a0 100644 --- a/acts/framework/acts/test_utils/power/tel_simulations/BaseSimulation.py +++ b/acts/framework/acts/controllers/cellular_lib/BaseSimulation.py @@ -19,10 +19,6 @@ from enum import Enum import numpy as np from acts.controllers import cellular_simulator -from acts.test_utils.tel.tel_test_utils import get_telephony_signal_strength -from acts.test_utils.tel.tel_test_utils import toggle_airplane_mode -from acts.test_utils.tel.tel_test_utils import toggle_cell_data_roaming -from acts.test_utils.tel.tel_test_utils import get_rx_tx_power_levels class BaseSimulation(): @@ -106,7 +102,7 @@ class BaseSimulation(): Args: simulator: a cellular simulator controller log: a logger handle - dut: the android device handler + dut: a device handler implementing BaseCellularDut test_config: test configuration obtained from the config file calibration_table: a dictionary containing path losses for different bands. @@ -168,13 +164,13 @@ class BaseSimulation(): # Set to default APN log.info("Configuring APN.") - dut.droid.telephonySetAPN("test", "test", "default") + self.dut.set_apn('test', 'test') # Enable roaming on the phone - toggle_cell_data_roaming(self.dut, True) + self.dut.toggle_data_roaming(True) # Make sure airplane mode is on so the phone won't attach right away - toggle_airplane_mode(self.log, self.dut, True) + self.dut.toggle_airplane_mode(True) # Wait for airplane mode setting to propagate time.sleep(2) @@ -197,7 +193,7 @@ class BaseSimulation(): """ # Turn on airplane mode - toggle_airplane_mode(self.log, self.dut, True) + self.dut.toggle_airplane_mode(True) # Wait for airplane mode setting to propagate time.sleep(2) @@ -215,7 +211,7 @@ class BaseSimulation(): try: # Turn off airplane mode - toggle_airplane_mode(self.log, self.dut, False) + self.dut.toggle_airplane_mode(False) # Wait for the phone to attach. self.simulator.wait_until_attached(timeout=self.attach_timeout) @@ -227,7 +223,7 @@ class BaseSimulation(): "UE failed to attach on attempt number {}.".format(i + 1)) # Turn airplane mode on to prepare the phone for a retry. - toggle_airplane_mode(self.log, self.dut, True) + self.dut.toggle_airplane_mode(True) # Wait for APM to propagate time.sleep(3) @@ -256,7 +252,7 @@ class BaseSimulation(): # Set the DUT to airplane mode so it doesn't see the # cellular network going off - toggle_airplane_mode(self.log, self.dut, True) + self.dut.toggle_airplane_mode(True) # Wait for APM to propagate time.sleep(2) @@ -271,7 +267,7 @@ class BaseSimulation(): # Set the DUT to airplane mode so it doesn't see the # cellular network going off - toggle_airplane_mode(self.log, self.dut, True) + self.dut.toggle_airplane_mode(True) # Wait for APM to propagate time.sleep(2) @@ -312,7 +308,7 @@ class BaseSimulation(): # Verify signal level try: - rx_power, tx_power = get_rx_tx_power_levels(self.log, self.dut) + rx_power, tx_power = self.dut.get_rx_tx_power_levels() if not tx_power or not rx_power[0]: raise RuntimeError('The method return invalid Tx/Rx values.') @@ -617,35 +613,24 @@ class BaseSimulation(): restoration_config.output_power = self.primary_config.output_power # Set BTS to a good output level to minimize measurement error - initial_screen_timeout = self.dut.droid.getScreenTimeout() new_config = self.BtsConfig() new_config.output_power = self.simulator.MAX_DL_POWER - 5 self.simulator.configure_bts(new_config) - # Set phone sleep time out - self.dut.droid.setScreenTimeout(1800) - self.dut.droid.goToSleepNow() - time.sleep(2) - # Starting IP traffic self.start_traffic_for_calibration() down_power_measured = [] for i in range(0, self.NUM_DL_CAL_READS): # For some reason, the RSRP gets updated on Screen ON event - self.dut.droid.wakeUpNow() - time.sleep(4) - signal_strength = get_telephony_signal_strength(self.dut) + signal_strength = self.dut.get_telephony_signal_strength() down_power_measured.append(signal_strength[rat]) - self.dut.droid.goToSleepNow() time.sleep(5) # Stop IP traffic self.stop_traffic_for_calibration() - # Reset phone and bts to original settings - self.dut.droid.goToSleepNow() - self.dut.droid.setScreenTimeout(initial_screen_timeout) + # Reset bts to original settings self.simulator.configure_bts(restoration_config) time.sleep(2) @@ -691,16 +676,10 @@ class BaseSimulation(): # Set BTS1 to maximum input allowed in order to perform # uplink calibration target_power = self.MAX_PHONE_OUTPUT_POWER - initial_screen_timeout = self.dut.droid.getScreenTimeout() new_config = self.BtsConfig() new_config.input_power = self.MAX_BTS_INPUT_POWER self.simulator.configure_bts(new_config) - # Set phone sleep time out - self.dut.droid.setScreenTimeout(1800) - self.dut.droid.wakeUpNow() - time.sleep(2) - # Start IP traffic self.start_traffic_for_calibration() @@ -729,9 +708,7 @@ class BaseSimulation(): # Stop IP traffic self.stop_traffic_for_calibration() - # Reset phone and bts to original settings - self.dut.droid.goToSleepNow() - self.dut.droid.setScreenTimeout(initial_screen_timeout) + # Reset bts to original settings self.simulator.configure_bts(restoration_config) time.sleep(2) diff --git a/acts/framework/acts/test_utils/power/tel_simulations/GsmSimulation.py b/acts/framework/acts/controllers/cellular_lib/GsmSimulation.py index 6dc2082cd6..b7237f354c 100644 --- a/acts/framework/acts/test_utils/power/tel_simulations/GsmSimulation.py +++ b/acts/framework/acts/controllers/cellular_lib/GsmSimulation.py @@ -17,15 +17,15 @@ import ntpath import time +from acts.controllers.anritsu_lib.band_constants import GSM_BAND_DCS1800 +from acts.controllers.anritsu_lib.band_constants import GSM_BAND_EGSM900 +from acts.controllers.anritsu_lib.band_constants import GSM_BAND_GSM850 +from acts.controllers.anritsu_lib.band_constants import GSM_BAND_RGSM900 from acts.controllers.anritsu_lib.md8475a import BtsGprsMode from acts.controllers.anritsu_lib.md8475a import BtsNumber from acts.controllers.anritsu_lib import md8475_cellular_simulator as anritsusim -from acts.test_utils.power.tel_simulations.BaseSimulation import BaseSimulation -from acts.test_utils.tel.anritsu_utils import GSM_BAND_DCS1800 -from acts.test_utils.tel.anritsu_utils import GSM_BAND_EGSM900 -from acts.test_utils.tel.anritsu_utils import GSM_BAND_GSM850 -from acts.test_utils.tel.anritsu_utils import GSM_BAND_RGSM900 -from acts.test_utils.tel.tel_defines import NETWORK_MODE_GSM_ONLY +from acts.controllers.cellular_lib import BaseCellularDut +from acts.controllers.cellular_lib.BaseSimulation import BaseSimulation class GsmSimulation(BaseSimulation): @@ -63,7 +63,7 @@ class GsmSimulation(BaseSimulation): Args: simulator: a cellular simulator controller log: a logger handle - dut: the android device handler + dut: a device handler implementing BaseCellularDut test_config: test configuration obtained from the config file calibration_table: a dictionary containing path losses for different bands. @@ -82,12 +82,8 @@ class GsmSimulation(BaseSimulation): super().__init__(simulator, log, dut, test_config, calibration_table) - if not dut.droid.telephonySetPreferredNetworkTypesForSubscription( - NETWORK_MODE_GSM_ONLY, - dut.droid.subscriptionGetDefaultSubId()): - log.error("Coold not set preferred network type.") - else: - log.info("Preferred network type set.") + self.dut.set_preferred_network_type( + BaseCellularDut.PreferredNetworkType.GSM_ONLY) def setup_simulator(self): """ Do initial configuration in the simulator. """ diff --git a/acts/framework/acts/test_utils/power/tel_simulations/LteCaSimulation.py b/acts/framework/acts/controllers/cellular_lib/LteCaSimulation.py index addc3a8aab..3f98a34e60 100644 --- a/acts/framework/acts/test_utils/power/tel_simulations/LteCaSimulation.py +++ b/acts/framework/acts/controllers/cellular_lib/LteCaSimulation.py @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. import re -from acts.test_utils.power.tel_simulations import LteSimulation +from acts.controllers.cellular_lib import LteSimulation class LteCaSimulation(LteSimulation.LteSimulation): @@ -80,7 +80,7 @@ class LteCaSimulation(LteSimulation.LteSimulation): Args: simulator: the cellular instrument controller log: a logger handle - dut: the android device handler + dut: a device handler implementing BaseCellularDut test_config: test configuration obtained from the config file calibration_table: a dictionary containing path losses for different bands. diff --git a/acts/framework/acts/test_utils/power/tel_simulations/LteImsSimulation.py b/acts/framework/acts/controllers/cellular_lib/LteImsSimulation.py index 71102463cf..e13eb297ba 100644 --- a/acts/framework/acts/test_utils/power/tel_simulations/LteImsSimulation.py +++ b/acts/framework/acts/controllers/cellular_lib/LteImsSimulation.py @@ -13,7 +13,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -from acts.test_utils.power.tel_simulations.LteSimulation import LteSimulation +from acts.controllers.cellular_lib.LteSimulation import LteSimulation import acts.test_utils.tel.anritsu_utils as anritsu_utils import acts.controllers.anritsu_lib.md8475a as md8475a diff --git a/acts/framework/acts/test_utils/power/tel_simulations/LteSimulation.py b/acts/framework/acts/controllers/cellular_lib/LteSimulation.py index 44bcbf67dd..9627e9fa26 100644 --- a/acts/framework/acts/test_utils/power/tel_simulations/LteSimulation.py +++ b/acts/framework/acts/controllers/cellular_lib/LteSimulation.py @@ -17,8 +17,8 @@ import math from enum import Enum -from acts.test_utils.power.tel_simulations.BaseSimulation import BaseSimulation -from acts.test_utils.tel.tel_defines import NETWORK_MODE_LTE_ONLY +from acts.controllers.cellular_lib.BaseSimulation import BaseSimulation +from acts.controllers.cellular_lib import BaseCellularDut class TransmissionMode(Enum): @@ -459,7 +459,7 @@ class LteSimulation(BaseSimulation): Args: simulator: a cellular simulator controller log: a logger handle - dut: the android device handler + dut: a device handler implementing BaseCellularDut test_config: test configuration obtained from the config file calibration_table: a dictionary containing path losses for different bands. @@ -468,12 +468,8 @@ class LteSimulation(BaseSimulation): super().__init__(simulator, log, dut, test_config, calibration_table) - if not dut.droid.telephonySetPreferredNetworkTypesForSubscription( - NETWORK_MODE_LTE_ONLY, - dut.droid.subscriptionGetDefaultSubId()): - log.error("Couldn't set preferred network type.") - else: - log.info("Preferred network type set.") + self.dut.set_preferred_network_type( + BaseCellularDut.PreferredNetworkType.LTE_ONLY) # Get TBS pattern setting from the test configuration if self.KEY_TBS_PATTERN not in test_config: diff --git a/acts/framework/acts/controllers/cellular_lib/OWNERS b/acts/framework/acts/controllers/cellular_lib/OWNERS new file mode 100644 index 0000000000..e4010df218 --- /dev/null +++ b/acts/framework/acts/controllers/cellular_lib/OWNERS @@ -0,0 +1,4 @@ +iguarna@google.com +chaoyangf@google.com +yixiang@google.com +codycaldwell@google.com
\ No newline at end of file diff --git a/acts/framework/acts/test_utils/power/tel_simulations/UmtsSimulation.py b/acts/framework/acts/controllers/cellular_lib/UmtsSimulation.py index 4d4aeebf8b..b301a6b6f5 100644 --- a/acts/framework/acts/test_utils/power/tel_simulations/UmtsSimulation.py +++ b/acts/framework/acts/controllers/cellular_lib/UmtsSimulation.py @@ -20,8 +20,8 @@ import time from acts.controllers.anritsu_lib import md8475_cellular_simulator as anritsusim from acts.controllers.anritsu_lib.md8475a import BtsNumber from acts.controllers.anritsu_lib.md8475a import BtsPacketRate -from acts.test_utils.power.tel_simulations.BaseSimulation import BaseSimulation -from acts.test_utils.tel.tel_defines import NETWORK_MODE_WCDMA_ONLY +from acts.controllers.cellular_lib.BaseSimulation import BaseSimulation +from acts.controllers.cellular_lib import BaseCellularDut class UmtsSimulation(BaseSimulation): @@ -98,7 +98,7 @@ class UmtsSimulation(BaseSimulation): Args: simulator: a cellular simulator controller log: a logger handle - dut: the android device handler + dut: a device handler implementing BaseCellularDut test_config: test configuration obtained from the config file calibration_table: a dictionary containing path losses for different bands. @@ -117,12 +117,8 @@ class UmtsSimulation(BaseSimulation): super().__init__(simulator, log, dut, test_config, calibration_table) - if not dut.droid.telephonySetPreferredNetworkTypesForSubscription( - NETWORK_MODE_WCDMA_ONLY, - dut.droid.subscriptionGetDefaultSubId()): - log.error("Coold not set preferred network type.") - else: - log.info("Preferred network type set.") + self.dut.set_preferred_network_type( + BaseCellularDut.PreferredNetworkType.WCDMA_ONLY) self.release_version = None self.packet_rate = None diff --git a/acts/framework/acts/test_utils/power/tel_simulations/__init__.py b/acts/framework/acts/controllers/cellular_lib/__init__.py index e69de29bb2..e69de29bb2 100644 --- a/acts/framework/acts/test_utils/power/tel_simulations/__init__.py +++ b/acts/framework/acts/controllers/cellular_lib/__init__.py diff --git a/acts/framework/acts/controllers/cellular_simulator.py b/acts/framework/acts/controllers/cellular_simulator.py index 2408611996..99adbd87be 100644 --- a/acts/framework/acts/controllers/cellular_simulator.py +++ b/acts/framework/acts/controllers/cellular_simulator.py @@ -14,7 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. from acts import logger -from acts.test_utils.power import tel_simulations as sims +from acts.controllers import cellular_lib as sims class AbstractCellularSimulator: diff --git a/acts/framework/acts/controllers/fuchsia_device.py b/acts/framework/acts/controllers/fuchsia_device.py index 322b653a32..12ce3f5289 100644 --- a/acts/framework/acts/controllers/fuchsia_device.py +++ b/acts/framework/acts/controllers/fuchsia_device.py @@ -51,6 +51,7 @@ from acts.controllers.fuchsia_lib.kernel_lib import FuchsiaKernelLib from acts.controllers.fuchsia_lib.location.regulatory_region_lib import FuchsiaRegulatoryRegionLib from acts.controllers.fuchsia_lib.logging_lib import FuchsiaLoggingLib from acts.controllers.fuchsia_lib.netstack.netstack_lib import FuchsiaNetstackLib +from acts.controllers.fuchsia_lib.ram_lib import FuchsiaRamLib from acts.controllers.fuchsia_lib.syslog_lib import FuchsiaSyslogError from acts.controllers.fuchsia_lib.syslog_lib import start_syslog from acts.controllers.fuchsia_lib.sysinfo_lib import FuchsiaSysInfoLib @@ -60,7 +61,7 @@ from acts.controllers.fuchsia_lib.wlan_deprecated_configuration_lib import Fuchs from acts.controllers.fuchsia_lib.wlan_lib import FuchsiaWlanLib from acts.controllers.fuchsia_lib.wlan_ap_policy_lib import FuchsiaWlanApPolicyLib from acts.controllers.fuchsia_lib.wlan_policy_lib import FuchsiaWlanPolicyLib -from acts.libs.proc.job import Error +from acts.libs.proc import job MOBLY_CONTROLLER_CONFIG_NAME = "FuchsiaDevice" ACTS_CONTROLLER_REFERENCE_NAME = "fuchsia_devices" @@ -280,6 +281,10 @@ class FuchsiaDevice: self.netstack_lib = FuchsiaNetstackLib(self.address, self.test_counter, self.client_id) + # Grab commands from FuchsiaLightLib + self.ram_lib = FuchsiaRamLib(self.address, self.test_counter, + self.client_id) + # Grab commands from FuchsiaProfileServerLib self.sdp_lib = FuchsiaProfileServerLib(self.address, self.test_counter, self.client_id) @@ -343,52 +348,6 @@ class FuchsiaDevice: """ return self.client_id + "." + str(test_id) - def verify_ping(self, timeout=30): - """Verify the fuchsia device can be pinged. - - Args: - timeout: int, seconds to retry before raising an exception - - Raise: - ConnecitonError, if device still can't be pinged after timeout. - """ - end_time = time.time() + timeout - while time.time() < end_time: - if utils.is_pingable(self.ip): - break - else: - self.log.debug('Device is not pingable. Retrying in 1 second.') - time.sleep(1) - else: - raise ConnectionError('Device never came back online.') - - def verify_ssh(self, timeout=30): - """Verify the fuchsia device can be reached via ssh. - - In self.reboot, this function is used to verify SSH is up before - attempting to restart SL4F, as that has more risky thread implications - if it fails. Also, create_ssh_connection has a short backoff loop, - but was not intended for waiting for SSH to come up. - - Args: - timeout: int, seconds to retry before raising an exception - - Raise: - ConnecitonError, if device still can't reached after timeout. - """ - end_time = time.time() + timeout - while time.time() < end_time: - try: - self.send_command_ssh('\n') - except Exception: - self.log.debug( - 'Could not SSH to device. Retrying in 1 second.') - time.sleep(1) - else: - break - else: - raise ConnectionError('Failed to connect to device via SSH.') - def reboot(self, use_ssh=False, unreachable_timeout=30, @@ -455,7 +414,7 @@ class FuchsiaDevice: self.log.info('Verifying device is unreachable.') timeout = time.time() + unreachable_timeout while (time.time() < timeout): - if utils.is_pingable(self.ip): + if utils.can_ping(job, self.ip): self.log.debug('Device is still pingable. Retrying.') else: if reboot_type == FUCHSIA_REBOOT_TYPE_HARD: @@ -475,11 +434,30 @@ class FuchsiaDevice: device_pdu.on(str(device_pdu_port)) self.log.info('Waiting for device to respond to pings.') - self.verify_ping(timeout=ping_timeout) + end_time = time.time() + ping_timeout + while time.time() < end_time: + if utils.can_ping(job, self.ip): + break + else: + self.log.debug('Device is not pingable. Retrying in 1 second.') + time.sleep(1) + else: + raise ConnectionError('Device never came back online.') self.log.info('Device responded to pings.') self.log.info('Waiting for device to allow ssh connection.') - self.verify_ssh(timeout=ssh_timeout) + end_time = time.time() + ssh_timeout + while time.time() < end_time: + try: + self.send_command_ssh('\n') + except Exception: + self.log.debug( + 'Could not SSH to device. Retrying in 1 second.') + time.sleep(1) + else: + break + else: + raise ConnectionError('Failed to connect to device via SSH.') self.log.info('Device now available via ssh.') # Creating new log process, start it, start new persistent ssh session, @@ -545,7 +523,13 @@ class FuchsiaDevice: ssh_conn.close() return command_result - def ping(self, dest_ip, count=3, interval=1000, timeout=1000, size=25): + def ping(self, + dest_ip, + count=3, + interval=1000, + timeout=1000, + size=25, + additional_ping_params=None): """Pings from a Fuchsia device to an IPv4 address or hostname Args: @@ -555,6 +539,8 @@ class FuchsiaDevice: timeout: (int) How long to wait before having the icmp packet timeout (ms). size: (int) Size of the icmp packet. + additional_ping_params: (str) command option flags to + append to the command string Returns: A dictionary for the results of the ping. The dictionary contains @@ -570,10 +556,12 @@ class FuchsiaDevice: rtt_max = None rtt_avg = None self.log.debug("Pinging %s..." % dest_ip) + if not additional_ping_params: + additional_ping_params = '' ping_result = self.send_command_ssh( - 'ping -c %s -i %s -t %s -s %s %s' % - (count, interval, timeout, size, dest_ip)) - if isinstance(ping_result, Error): + 'ping -c %s -i %s -t %s -s %s %s %s' % + (count, interval, timeout, size, additional_ping_params, dest_ip)) + if isinstance(ping_result, job.Error): ping_result = ping_result.result if ping_result.stderr: @@ -595,6 +583,22 @@ class FuchsiaDevice: 'stderr': ping_result.stderr } + def can_ping(self, + dest_ip, + count=1, + interval=1000, + timeout=1000, + size=25, + additional_ping_params=None): + """Returns whether fuchsia device can ping a given dest address""" + ping_result = self.ping(dest_ip, + count=count, + interval=interval, + timeout=timeout, + size=size, + additional_ping_params=additional_ping_params) + return ping_result['status'] + def print_clients(self): """Gets connected clients from SL4F server""" self.log.debug("Request to print clients") @@ -860,10 +864,23 @@ class FuchsiaDevice: acts_logger.epoch_to_log_line_timestamp(begin_time)) out_name = "FuchsiaDevice%s_%s" % ( self.serial, time_stamp.replace(" ", "_").replace(":", "-")) + bugreport_out_name = f"{out_name}.zip" out_name = "%s.txt" % out_name full_out_path = os.path.join(br_path, out_name) + full_br_out_path = os.path.join(br_path, bugreport_out_name) self.log.info("Taking bugreport for %s on FuchsiaDevice%s." % (test_name, self.serial)) + if self.ssh_config is not None: + try: + subprocess.run([ + f"ssh -F {self.ssh_config} {self.ip} bugreport > {full_br_out_path}" + ], + shell=True) + self.log.info( + "Bugreport saved at: {}".format(full_br_out_path)) + except Exception as err: + self.log.error("Failed to take bugreport with: {}".format(err)) + system_objects = self.send_command_ssh('iquery --find /hub').stdout system_objects = system_objects.split() diff --git a/acts/framework/acts/controllers/fuchsia_lib/base_lib.py b/acts/framework/acts/controllers/fuchsia_lib/base_lib.py index 9576e6850d..23035fca8e 100644 --- a/acts/framework/acts/controllers/fuchsia_lib/base_lib.py +++ b/acts/framework/acts/controllers/fuchsia_lib/base_lib.py @@ -28,6 +28,7 @@ import time from urllib.parse import urlparse from acts import utils +from acts.libs.proc import job class DeviceOffline(Exception): @@ -61,7 +62,7 @@ class BaseLib(): Returns: Dictionary, Result of sl4f command executed. """ - if not utils.is_pingable(urlparse(self.address).hostname): + if not utils.can_ping(job, urlparse(self.address).hostname): raise DeviceOffline("FuchsiaDevice %s is not reachable via the " "network." % urlparse(self.address).hostname) test_data = json.dumps({ @@ -75,12 +76,12 @@ class BaseLib(): data=test_data, timeout=response_timeout).json() except requests.exceptions.Timeout as e: - if not utils.is_pingable(urlparse(self.address).hostname): + if not utils.can_ping(job, urlparse(self.address).hostname): raise DeviceOffline( "FuchsiaDevice %s is not reachable via the " "network." % urlparse(self.address).hostname) else: logging.debug( - 'FuchsiaDevice is online but SL4f call timed out.' % + 'FuchsiaDevice %s is online but SL4f call timed out.' % urlparse(self.address).hostname) raise e diff --git a/acts/framework/acts/controllers/fuchsia_lib/ram_lib.py b/acts/framework/acts/controllers/fuchsia_lib/ram_lib.py new file mode 100644 index 0000000000..ce8bb73afd --- /dev/null +++ b/acts/framework/acts/controllers/fuchsia_lib/ram_lib.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 +# +# Copyright 2020 - The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from acts.controllers.fuchsia_lib.base_lib import BaseLib + + +class FuchsiaRamLib(BaseLib): + def __init__(self, addr, tc, client_id): + self.address = addr + self.test_counter = tc + self.client_id = client_id + + def measureBandwidth(self, cycles_to_measure, channels): + """ Measures the DDR bandwidth on the specified channels. + + Args: + cycles_to_measure: How many bus cycles to perform the measurement over. + channels: An array of 8 uint64, specifying which ports to aggregate + for each channel. + + Returns: + BandwidthInfo struct, prints an error message if error. + """ + test_cmd = "ram_facade.MeasureBandwidth" + test_args = { + "values": { + "cycles_to_measure": cycles_to_measure, + "channels": channels + } + } + test_id = self.build_id(self.test_counter) + self.test_counter += 1 + + return self.send_command(test_id, test_cmd, test_args) + + def getDdrWindowingResults(self): + """ Retrieves the results from the DDR Windowing tool, which runs in + the bootloader. + + Returns: + The register value, prints an error message if error. + """ + test_cmd = "ram_facade.GetDdrWindowingResults" + test_args = {} + test_id = self.build_id(self.test_counter) + self.test_counter += 1 + + return self.send_command(test_id, test_cmd, test_args) diff --git a/acts/framework/acts/controllers/fuchsia_lib/syslog_lib.py b/acts/framework/acts/controllers/fuchsia_lib/syslog_lib.py index a8c102d0c6..2b2f024b07 100644 --- a/acts/framework/acts/controllers/fuchsia_lib/syslog_lib.py +++ b/acts/framework/acts/controllers/fuchsia_lib/syslog_lib.py @@ -102,8 +102,9 @@ class FuchsiaSyslogProcess(object): def start(self): """Starts reading the data from the syslog ssh connection.""" if self._started: - raise FuchsiaSyslogError('Syslog has already started for ' - 'FuchsiaDevice (%s).' % self.ip_address) + logging.info('Syslog has already started for FuchsiaDevice (%s).' % + self.ip_address) + return None self._started = True self._listening_thread = Thread(target=self._exec_loop) @@ -122,8 +123,9 @@ class FuchsiaSyslogProcess(object): threads. """ if self._stopped: - raise FuchsiaSyslogError('Syslog is already being stopped for ' - 'FuchsiaDevice (%s).' % self.ip_address) + logging.info('Syslog is already stopped for FuchsiaDevice (%s).' % + self.ip_address) + return None self._stopped = True try: diff --git a/acts/framework/acts/controllers/fuchsia_lib/utils_lib.py b/acts/framework/acts/controllers/fuchsia_lib/utils_lib.py index 782d96e631..96a71319be 100644 --- a/acts/framework/acts/controllers/fuchsia_lib/utils_lib.py +++ b/acts/framework/acts/controllers/fuchsia_lib/utils_lib.py @@ -23,6 +23,7 @@ import time from acts import utils from acts.controllers.fuchsia_lib.base_lib import DeviceOffline +from acts.libs.proc import job logging.getLogger("paramiko").setLevel(logging.WARNING) # paramiko-ng will throw INFO messages when things get disconnect or cannot @@ -87,7 +88,7 @@ def create_ssh_connection(ip_address, Returns: A paramiko ssh object """ - if not utils.is_pingable(ip_address): + if not utils.can_ping(job, ip_address): raise DeviceOffline("Device %s is not reachable via " "the network." % ip_address) ssh_key = get_private_key(ip_address=ip_address, ssh_config=ssh_config) diff --git a/acts/framework/acts/controllers/fuchsia_lib/wlan_policy_lib.py b/acts/framework/acts/controllers/fuchsia_lib/wlan_policy_lib.py index 61122208b3..5ca778b703 100644 --- a/acts/framework/acts/controllers/fuchsia_lib/wlan_policy_lib.py +++ b/acts/framework/acts/controllers/fuchsia_lib/wlan_policy_lib.py @@ -25,6 +25,7 @@ COMMAND_STOP_CLIENT_CONNECTIONS = "wlan_policy.stop_client_connections" COMMAND_SCAN_FOR_NETWORKS = "wlan_policy.scan_for_networks" COMMAND_SAVE_NETWORK = "wlan_policy.save_network" COMMAND_REMOVE_NETWORK = "wlan_policy.remove_network" +COMMAND_REMOVE_ALL_NETWORKS = "wlan_policy.remove_all_networks" COMMAND_GET_SAVED_NETWORKS = "wlan_policy.get_saved_networks" COMMAND_CONNECT = "wlan_policy.connect" COMMAND_CREATE_CLIENT_CONTROLLER = "wlan_policy.create_client_controller" @@ -76,7 +77,7 @@ class FuchsiaWlanPolicyLib(BaseLib): return self.send_command(test_id, test_cmd, {}) - def wlanSaveNetwork(self, target_ssid, security_type, target_pwd=""): + def wlanSaveNetwork(self, target_ssid, security_type, target_pwd=None): """ Saveds a network to the device for future connections Args: target_ssid: the network to attempt a connection to @@ -87,7 +88,8 @@ class FuchsiaWlanPolicyLib(BaseLib): Returns: boolean indicating if the connection was successful """ - + if not target_pwd: + target_pwd = '' test_cmd = COMMAND_SAVE_NETWORK test_id = self.build_id(self.test_counter) self.test_counter += 1 @@ -99,7 +101,7 @@ class FuchsiaWlanPolicyLib(BaseLib): return self.send_command(test_id, test_cmd, test_args) - def wlanRemoveNetwork(self, target_ssid, security_type, target_pwd=""): + def wlanRemoveNetwork(self, target_ssid, security_type, target_pwd=None): """ Removes or "forgets" a network from saved networks Args: target_ssid: the network to attempt a connection to @@ -107,7 +109,8 @@ class FuchsiaWlanPolicyLib(BaseLib): target_pwd: (optional) credential of the network to remove. No password and empty string are equivalent. """ - + if not target_pwd: + target_pwd = '' test_cmd = COMMAND_REMOVE_NETWORK test_id = self.build_id(self.test_counter) self.test_counter += 1 @@ -119,6 +122,18 @@ class FuchsiaWlanPolicyLib(BaseLib): return self.send_command(test_id, test_cmd, test_args) + def wlanRemoveAllNetworks(self): + """ Removes or "forgets" all networks from saved networks + Returns: + A boolean indicating if the action was successful + """ + + test_cmd = COMMAND_REMOVE_ALL_NETWORKS + test_id = self.build_id(self.test_counter) + self.test_counter += 1 + + return self.send_command(test_id, test_cmd, {}) + def wlanGetSavedNetworks(self): """ Gets networks saved on device Returns: diff --git a/acts/framework/acts/controllers/iperf_server.py b/acts/framework/acts/controllers/iperf_server.py index 2b7d970442..78cb787458 100755 --- a/acts/framework/acts/controllers/iperf_server.py +++ b/acts/framework/acts/controllers/iperf_server.py @@ -243,8 +243,8 @@ class IPerfResult(object): """ if not self._has_data(): return None - instantaneous_rates = self.instantaneous_rates[ - iperf_ignored_interval:-1] + instantaneous_rates = self.instantaneous_rates[iperf_ignored_interval: + -1] avg_rate = math.fsum(instantaneous_rates) / len(instantaneous_rates) sqd_deviations = ([(rate - avg_rate)**2 for rate in instantaneous_rates]) @@ -295,25 +295,6 @@ class IPerfServerBase(object): """ raise NotImplementedError('stop() must be specified.') - def get_interface_ip_addresses(self, interface): - """Gets all of the ip addresses, ipv4 and ipv6, associated with a - particular interface name. - - Args: - interface: The interface name on the device, ie eth0 - - Returns: - A list of dictionaries of the the various IP addresses: - ipv4_private_local_addresses: Any 192.168, 172.16, or 10 - addresses - ipv4_public_addresses: Any IPv4 public addresses - ipv6_link_local_addresses: Any fe80:: addresses - ipv6_private_local_addresses: Any fd00:: addresses - ipv6_public_addresses: Any publicly routable addresses - """ - raise NotImplementedError('get_interface_ip_addresses' - ' must be specified.') - def _get_full_file_path(self, tag=None): """Returns the full file path for the IPerfServer log file. @@ -432,24 +413,6 @@ class IPerfServer(IPerfServerBase): return self._current_log_file - def get_interface_ip_addresses(self, interface): - """Gets all of the ip addresses, ipv4 and ipv6, associated with a - particular interface name. - - Args: - interface: The interface name on the device, ie eth0 - - Returns: - A list of dictionaries of the the various IP addresses: - ipv4_private_local_addresses: Any 192.168, 172.16, or 10 - addresses - ipv4_public_addresses: Any IPv4 public addresses - ipv6_link_local_addresses: Any fe80:: addresses - ipv6_private_local_addresses: Any fd00:: addresses - ipv6_public_addresses: Any publicly routable addresses - """ - return utils.get_interface_ip_addresses(job, interface) - def __del__(self): self.stop() @@ -523,6 +486,7 @@ class IPerfServerOverSsh(IPerfServerBase): """ if not self._ssh_session: self.start_ssh() + return utils.get_interface_ip_addresses(self._ssh_session, interface) def renew_test_interface_ip_address(self): @@ -748,22 +712,3 @@ class IPerfServerOverAdb(IPerfServerBase): self._iperf_process = None return log_file - - def get_interface_ip_addresses(self, interface): - """Gets all of the ip addresses, ipv4 and ipv6, associated with a - particular interface name. - - Args: - interface: The interface name on the device, ie eth0 - - Returns: - A list of dictionaries of the the various IP addresses: - ipv4_private_local_addresses: Any 192.168, 172.16, or 10 - addresses - ipv4_public_addresses: Any IPv4 public addresses - ipv6_link_local_addresses: Any fe80:: addresses - ipv6_private_local_addresses: Any fd00:: addresses - ipv6_public_addresses: Any publicly routable addresses - """ - return utils.get_interface_ip_addresses(self._android_device_or_serial, - interface) diff --git a/acts/framework/acts/controllers/monsoon_lib/api/common.py b/acts/framework/acts/controllers/monsoon_lib/api/common.py index f932535467..277598e0a1 100644 --- a/acts/framework/acts/controllers/monsoon_lib/api/common.py +++ b/acts/framework/acts/controllers/monsoon_lib/api/common.py @@ -42,33 +42,33 @@ PASSTHROUGH_STATES = { class MonsoonDataRecord(object): """A data class for Monsoon data points.""" - def __init__(self, time, current): + def __init__(self, sample_time, relative_time, current): """Creates a new MonsoonDataRecord. Args: - time: the string '{time}s', where time is measured in seconds since - the beginning of the data collection. + sample_time: the unix timestamp of the sample. + relative_time: the time since the start of the measurement. current: The current in Amperes as a string. """ - self._time = float(time[:-1]) - self._current = float(current) + self._sample_time = sample_time + self._relative_time = relative_time + self._current = current @property def time(self): """The time the record was fetched.""" - return self._time + return self._sample_time + + @property + def relative_time(self): + """The time the record was fetched, relative to collection start.""" + return self._relative_time @property def current(self): """The amount of current in Amperes measured for the given record.""" return self._current - @classmethod - def create_from_record_line(cls, line): - """Creates a data record from the line passed in from the output file. - """ - return cls(*line.split(' ')) - class MonsoonResult(object): """An object that contains aggregated data collected during sampling. @@ -107,10 +107,16 @@ class MonsoonResult(object): def __iter__(self): with open(self.file, 'r') as f: + start_time = None for line in f: # Remove the newline character. line.strip() - yield MonsoonDataRecord.create_from_record_line(line) + sample_time, current = map(float, line.split(' ')) + if start_time is None: + start_time = sample_time + yield MonsoonDataRecord(sample_time, + sample_time - start_time, + current) return MonsoonDataIterator(self.tag) diff --git a/acts/framework/acts/controllers/monsoon_lib/api/lvpm_stock/monsoon_proxy.py b/acts/framework/acts/controllers/monsoon_lib/api/lvpm_stock/monsoon_proxy.py index 615d69aa82..7d94d36972 100644 --- a/acts/framework/acts/controllers/monsoon_lib/api/lvpm_stock/monsoon_proxy.py +++ b/acts/framework/acts/controllers/monsoon_lib/api/lvpm_stock/monsoon_proxy.py @@ -214,7 +214,8 @@ class MonsoonProxy(object): self._flush_input() # discard stale input status = self.get_status() except Exception as e: - logging.exception('Error opening device %s: %s', dev, e) + logging.warning('Error opening device %s: %s', dev, e, + exc_info=True) continue if not status: diff --git a/acts/framework/acts/controllers/monsoon_lib/sampling/engine/transformers.py b/acts/framework/acts/controllers/monsoon_lib/sampling/engine/transformers.py index dc5e6f0455..debe82cbaf 100644 --- a/acts/framework/acts/controllers/monsoon_lib/sampling/engine/transformers.py +++ b/acts/framework/acts/controllers/monsoon_lib/sampling/engine/transformers.py @@ -41,6 +41,8 @@ class Tee(SequentialTransformer): self._filename = filename self._fd = None self.measure_after_seconds = measure_after_seconds + # The time of the first sample gathered. + self._start_time = None def on_begin(self): self._fd = open(self._filename, 'w+') @@ -55,11 +57,74 @@ class Tee(SequentialTransformer): buffer: A list of HvpmReadings. """ for sample in buffer: - if sample.sample_time < self.measure_after_seconds: + if self._start_time is None: + self._start_time = sample.sample_time + if (sample.sample_time - self._start_time < + self.measure_after_seconds): continue - self._fd.write('%.9fs %.12f\n' % - (sample.sample_time - self.measure_after_seconds, - sample.main_current)) + self._fd.write('%0.9f %.12f\n' % + (sample.sample_time, sample.main_current)) + self._fd.flush() + return BufferList([buffer]) + + +class PerfgateTee(SequentialTransformer): + """Outputs records of nanoseconds,current,voltage to the specified file. + + Similar to Tee, but this version includes voltage, which may help with + accuracy in the power calculations. + + This output type can be enabled by passing this transformer to the + transformers kwarg in Monsoon.measure_power(): + + # Uses the default Tee + > monsoon.measure_power(..., output_path=filename]) + + # Uses PerfgateTee + > monsoon.measure_power(..., transformers=[PerfgateTee(filename)]) + + Attributes: + _filename: the name of the file to open. + _fd: the filestream written to. + """ + + def __init__(self, filename, measure_after_seconds=0): + """Creates an OutputStream. + + Args: + filename: the path to the file to write the collected data to. + measure_after_seconds: the number of seconds to skip before logging + data as part of the measurement. + """ + super().__init__() + self._filename = filename + self._fd = None + self.measure_after_seconds = measure_after_seconds + # The time of the first sample gathered. + self._start_time = None + + def on_begin(self): + self._fd = open(self._filename, 'w+') + + def on_end(self): + self._fd.close() + + def _transform_buffer(self, buffer): + """Writes the reading values to a file. + + Args: + buffer: A list of HvpmReadings. + """ + for sample in buffer: + if self._start_time is None: + self._start_time = sample.sample_time + if (sample.sample_time - self._start_time < + self.measure_after_seconds): + continue + self._fd.write( + '%i,%.6f,%.6f\n' % + (sample.sample_time * 1e9, sample.main_current, + sample.main_voltage)) self._fd.flush() return BufferList([buffer]) @@ -79,6 +144,8 @@ class SampleAggregator(ParallelTransformer): self._num_samples = 0 self._sum_currents = 0 self.start_after_seconds = start_after_seconds + # The time of the first sample gathered. + self._start_time = None def _transform_buffer(self, buffer): """Aggregates the sample data. @@ -87,7 +154,9 @@ class SampleAggregator(ParallelTransformer): buffer: A buffer of H/LvpmReadings. """ for sample in buffer: - if sample.sample_time < self.start_after_seconds: + if self._start_time is None: + self._start_time = sample.sample_time + if sample.sample_time - self._start_time < self.start_after_seconds: continue self._num_samples += 1 self._sum_currents += sample.main_current diff --git a/acts/framework/acts/controllers/monsoon_lib/sampling/hvpm/packet.py b/acts/framework/acts/controllers/monsoon_lib/sampling/hvpm/packet.py index 223337054d..3319c3447e 100644 --- a/acts/framework/acts/controllers/monsoon_lib/sampling/hvpm/packet.py +++ b/acts/framework/acts/controllers/monsoon_lib/sampling/hvpm/packet.py @@ -150,11 +150,9 @@ class Packet(object): Attributes: _packet_data: The raw data received from the packet. - time_since_start: The timestamp (relative to start) this packet was - collected. + time_of_read: The unix timestamp this packet was collected at. time_since_last_sample: The differential between this packet's - time_since_start and the previous packet's. Note that for the first - packet, this value will be equal to time_since_start. + time_of_read and the previous packet's. """ FIRST_MEASUREMENT_OFFSET = 8 @@ -174,7 +172,7 @@ class Packet(object): (str(HvpmMeasurement.SIZE) + 's') * self.num_measurements) # yapf: disable. Yapf forces these to try to fit one after the other. - (self.time_since_start, + (self.time_of_read, self.time_since_last_sample, self.dropped_count, self.flags, @@ -195,7 +193,7 @@ class Packet(object): sample the values. """ time_per_sample = self.time_since_last_sample / self.num_measurements - return time_per_sample * (index + 1) + self.time_since_start + return time_per_sample * (index + 1) + self.time_of_read @property def packet_counter(self): diff --git a/acts/framework/acts/controllers/monsoon_lib/sampling/hvpm/transformers.py b/acts/framework/acts/controllers/monsoon_lib/sampling/hvpm/transformers.py index 5ddc23c13d..8525149435 100644 --- a/acts/framework/acts/controllers/monsoon_lib/sampling/hvpm/transformers.py +++ b/acts/framework/acts/controllers/monsoon_lib/sampling/hvpm/transformers.py @@ -126,7 +126,6 @@ class PacketCollector(SourceTransformer): A BufferList of a single buffer if collection is not yet finished. None if sampling is complete. """ - index = 0 if (self.sampling_duration and self.sampling_duration < time.time() - self.start_time): return None @@ -144,7 +143,7 @@ class PacketCollector(SourceTransformer): logging.warning(e) continue time_after_read = time.time() - time_data = struct.pack('dd', time_after_read - self.start_time, + time_data = struct.pack('dd', time_after_read, time_after_read - time_before_read) buffer[index] = time_data + data.tobytes() @@ -182,6 +181,7 @@ class PacketReader(ParallelTransformer): over it's maximum value (2^16-1). previous_dropped_count: The dropped count read from the last packet. Used for determining the true number of dropped samples. + start_time: The time of the first packet ever read. """ """The number of seconds before considering dropped_count to be meaningful. @@ -194,12 +194,18 @@ class PacketReader(ParallelTransformer): super().__init__() self.rollover_count = 0 self.previous_dropped_count = 0 + self.start_time = 0 def _transform_buffer(self, buffer): """Reads raw sample data and converts it into packet objects.""" + for i in range(len(buffer)): buffer[i] = Packet(buffer[i]) - if (buffer[i].time_since_start > + + if buffer and not self.start_time and i == 0: + self.start_time = buffer[0].time_of_read + + if (buffer[i].time_of_read - self.start_time > PacketReader.DROP_COUNT_TIMER_THRESHOLD): self._process_dropped_count(buffer[i]) @@ -216,7 +222,7 @@ class PacketReader(ParallelTransformer): self.previous_dropped_count = packet.dropped_count log_function = logging.info if __debug__ else logging.warning log_function('At %9f, total dropped count: %s' % - (packet.time_since_start, self.total_dropped_count)) + (packet.time_of_read, self.total_dropped_count)) @property def total_dropped_count(self): diff --git a/acts/framework/acts/controllers/monsoon_lib/sampling/lvpm_stock/packet.py b/acts/framework/acts/controllers/monsoon_lib/sampling/lvpm_stock/packet.py index b0f88394af..2fcdec8ce9 100644 --- a/acts/framework/acts/controllers/monsoon_lib/sampling/lvpm_stock/packet.py +++ b/acts/framework/acts/controllers/monsoon_lib/sampling/lvpm_stock/packet.py @@ -164,20 +164,18 @@ class Packet(object): Attributes: _packet_data: The raw data received from the packet. - time_since_start: The timestamp (relative to start) this packet was - collected. - time_since_last_sample: The differential between this packet's - time_since_start and the previous packet's. Note that for the first - packet, this value will be equal to time_since_start. + time_of_read: The unix timestamp this packet was collected at. + time_since_last_sample: The difference between this packet's + time_of_read and the previous packet's. """ # The number of bytes before the first packet. FIRST_MEASUREMENT_OFFSET = 4 - def __init__(self, sampled_bytes, time_since_start, + def __init__(self, sampled_bytes, time_of_read, time_since_last_sample): self._packet_data = sampled_bytes - self.time_since_start = time_since_start + self.time_of_read = time_of_read self.time_since_last_sample = time_since_last_sample num_data_bytes = len(sampled_bytes) - Packet.FIRST_MEASUREMENT_OFFSET @@ -207,7 +205,7 @@ class Packet(object): index: the index of the individual reading from within the sample. """ time_per_sample = self.time_since_last_sample / len(self.measurements) - return time_per_sample * (index + 1) + self.time_since_start + return time_per_sample * (index + 1) + self.time_of_read @property def packet_counter(self): diff --git a/acts/framework/acts/controllers/monsoon_lib/sampling/lvpm_stock/stock_transformers.py b/acts/framework/acts/controllers/monsoon_lib/sampling/lvpm_stock/stock_transformers.py index becc4ee99c..e0098bfba8 100644 --- a/acts/framework/acts/controllers/monsoon_lib/sampling/lvpm_stock/stock_transformers.py +++ b/acts/framework/acts/controllers/monsoon_lib/sampling/lvpm_stock/stock_transformers.py @@ -94,7 +94,7 @@ class PacketCollector(SourceTransformer): if data is None: continue time_after_read = time.time() - time_data = struct.pack('dd', time_after_read - self.start_time, + time_data = struct.pack('dd', time_after_read, time_after_read - time_before_read) buffer[index] = time_data + data @@ -169,7 +169,7 @@ class PacketReader(ParallelTransformer): for i, packet in enumerate(buffer): time_bytes_size = struct.calcsize('dd') # Unpacks the two time.time() values sent by PacketCollector. - time_since_start, time_of_read = struct.unpack( + time_of_read, time_since_last_read = struct.unpack( 'dd', packet[:time_bytes_size]) packet = packet[time_bytes_size:] # Magic number explanation: @@ -182,7 +182,7 @@ class PacketReader(ParallelTransformer): buffer[i] = None continue - buffer[i] = Packet(packet, time_since_start, time_of_read) + buffer[i] = Packet(packet, time_of_read, time_since_last_read) return buffer diff --git a/acts/framework/acts/controllers/openwrt_ap.py b/acts/framework/acts/controllers/openwrt_ap.py new file mode 100644 index 0000000000..05bd38c271 --- /dev/null +++ b/acts/framework/acts/controllers/openwrt_ap.py @@ -0,0 +1,253 @@ +"""Controller for Open WRT access point.""" + +import time + +from acts import logger +from acts.controllers.ap_lib import hostapd_constants +from acts.controllers.openwrt_lib import wireless_config +from acts.controllers.openwrt_lib import wireless_settings_applier +from acts.controllers.utils_lib.ssh import connection +from acts.controllers.utils_lib.ssh import settings + +MOBLY_CONTROLLER_CONFIG_NAME = "OpenWrtAP" +ACTS_CONTROLLER_REFERENCE_NAME = "access_points" +OPEN_SECURITY = "none" +PSK_SECURITY = "psk2" +WEP_SECURITY = "wep" +ENT_SECURITY = "wpa2" +ENABLE_RADIO = "0" +WIFI_2G = "wifi2g" +WIFI_5G = "wifi5g" + + +def create(configs): + """Creates ap controllers from a json config. + + Creates an ap controller from either a list, or a single element. The element + can either be just the hostname or a dictionary containing the hostname and + username of the AP to connect to over SSH. + + Args: + configs: The json configs that represent this controller. + + Returns: + AccessPoint object + + Example: + Below is the config file entry for OpenWrtAP as a list. A testbed can have + 1 or more APs to configure. Each AP has a "ssh_config" key to provide SSH + login information. OpenWrtAP#__init__() uses this to create SSH object. + + "OpenWrtAP": [ + { + "ssh_config": { + "user" : "root", + "host" : "192.168.1.1" + } + }, + { + "ssh_config": { + "user" : "root", + "host" : "192.168.1.2" + } + } + ] + """ + return [OpenWrtAP(c) for c in configs] + + +def destroy(aps): + """Destroys a list of AccessPoints. + + Args: + aps: The list of AccessPoints to destroy. + """ + for ap in aps: + ap.close() + ap.close_ssh() + + +def get_info(aps): + """Get information on a list of access points. + + Args: + aps: A list of AccessPoints. + + Returns: + A list of all aps hostname. + """ + return [ap.ssh_settings.hostname for ap in aps] + + +class OpenWrtAP(object): + """An AccessPoint controller. + + Attributes: + log: Logging object for AccessPoint. + ssh: The ssh connection to the AP. + ssh_settings: The ssh settings being used by the ssh connection. + wireless_setting: object holding wireless configuration. + """ + + def __init__(self, config): + """Initialize AP.""" + self.ssh_settings = settings.from_config(config["ssh_config"]) + self.ssh = connection.SshConnection(self.ssh_settings) + self.log = logger.create_logger( + lambda msg: "[OpenWrtAP|%s] %s" % (self.ssh_settings.hostname, msg)) + self.wireless_setting = None + + def configure_ap(self, wifi_configs, channel_2g, channel_5g): + """Configure AP with the required settings. + + Each test class inherits WifiBaseTest. Based on the test, we may need to + configure PSK, WEP, OPEN, ENT networks on 2G and 5G bands in any + combination. We call WifiBaseTest methods get_psk_network(), + get_open_network(), get_wep_network() and get_ent_network() to create + dictionaries which contains this information. 'wifi_configs' is a list of + such dictionaries. Example below configures 2 WiFi networks - 1 PSK 2G and + 1 Open 5G on one AP. configure_ap() is called from WifiBaseTest to + configure the APs. + + wifi_configs = [ + { + '2g': { + 'SSID': '2g_AkqXWPK4', + 'security': 'psk2', + 'password': 'YgYuXqDO9H', + 'hiddenSSID': False + }, + }, + { + '5g': { + 'SSID': '5g_8IcMR1Sg', + 'security': 'none', + 'hiddenSSID': False + }, + } + ] + + Args: + wifi_configs: list of network settings for 2G and 5G bands. + channel_2g: channel for 2G band. + channel_5g: channel for 5G band. + """ + # generate wifi configs to configure + wireless_configs = self.generate_wireless_configs(wifi_configs) + self.wireless_setting = wireless_settings_applier.WirelessSettingsApplier( + self.ssh, wireless_configs, channel_2g, channel_5g) + self.wireless_setting.apply_wireless_settings() + + def start_ap(self): + """Starts the AP with the settings in /etc/config/wireless.""" + self.ssh.run("wifi up") + time.sleep(9) # wait for sometime for AP to come up + + def stop_ap(self): + """Stops the AP.""" + self.ssh.run("wifi down") + time.sleep(9) # wait for sometime for AP to go down + + def generate_wireless_configs(self, wifi_configs): + """Generate wireless configs to configure. + + Converts wifi_configs from configure_ap() to a list of 'WirelessConfig' + objects. Each object represents a wifi network to configure on the AP. + + Args: + wifi_configs: Network list of different security types and bands. + + Returns: + wireless configuration for openwrt AP. + """ + num_2g = 1 + num_5g = 1 + wireless_configs = [] + + for i in range(len(wifi_configs)): + if hostapd_constants.BAND_2G in wifi_configs[i]: + config = wifi_configs[i][hostapd_constants.BAND_2G] + if config["security"] == PSK_SECURITY: + wireless_configs.append( + wireless_config.WirelessConfig("%s%s" % (WIFI_2G, num_2g), + config["SSID"], + config["security"], + hostapd_constants.BAND_2G, + password=config["password"], + hidden=config["hiddenSSID"])) + elif config["security"] == WEP_SECURITY: + wireless_configs.append( + wireless_config.WirelessConfig("%s%s" % (WIFI_2G, num_2g), + config["SSID"], + config["security"], + hostapd_constants.BAND_2G, + wep_key=config["wepKeys"][0], + hidden=config["hiddenSSID"])) + elif config["security"] == OPEN_SECURITY: + wireless_configs.append( + wireless_config.WirelessConfig("%s%s" % (WIFI_2G, num_2g), + config["SSID"], + config["security"], + hostapd_constants.BAND_2G, + hidden=config["hiddenSSID"])) + elif config["security"] == ENT_SECURITY: + wireless_configs.append( + wireless_config.WirelessConfig( + "%s%s" % (WIFI_2G, num_2g), + config["SSID"], + config["security"], + hostapd_constants.BAND_2G, + radius_server_ip=config["radius_server_ip"], + radius_server_port=config["radius_server_port"], + radius_server_secret=config["radius_server_secret"], + hidden=config["hiddenSSID"])) + num_2g += 1 + if hostapd_constants.BAND_5G in wifi_configs[i]: + config = wifi_configs[i][hostapd_constants.BAND_5G] + if config["security"] == PSK_SECURITY: + wireless_configs.append( + wireless_config.WirelessConfig("%s%s" % (WIFI_5G, num_5g), + config["SSID"], + config["security"], + hostapd_constants.BAND_5G, + password=config["password"], + hidden=config["hiddenSSID"])) + elif config["security"] == WEP_SECURITY: + wireless_configs.append( + wireless_config.WirelessConfig("%s%s" % (WIFI_5G, num_5g), + config["SSID"], + config["security"], + hostapd_constants.BAND_5G, + wep_key=config["wepKeys"][0], + hidden=config["hiddenSSID"])) + elif config["security"] == OPEN_SECURITY: + wireless_configs.append( + wireless_config.WirelessConfig("%s%s" % (WIFI_5G, num_5g), + config["SSID"], + config["security"], + hostapd_constants.BAND_5G, + hidden=config["hiddenSSID"])) + elif config["security"] == ENT_SECURITY: + wireless_configs.append( + wireless_config.WirelessConfig( + "%s%s" % (WIFI_5G, num_5g), + config["SSID"], + config["security"], + hostapd_constants.BAND_5G, + radius_server_ip=config["radius_server_ip"], + radius_server_port=config["radius_server_port"], + radius_server_secret=config["radius_server_secret"], + hidden=config["hiddenSSID"])) + num_5g += 1 + + return wireless_configs + + def close(self): + """Reset wireless settings to default and stop AP.""" + if self.wireless_setting: + self.wireless_setting.cleanup_wireless_settings() + + def close_ssh(self): + """Close SSH connection to AP.""" + self.ssh.close() + diff --git a/acts/tests/google/__init__.py b/acts/framework/acts/controllers/openwrt_lib/__init__.py index e69de29bb2..e69de29bb2 100644 --- a/acts/tests/google/__init__.py +++ b/acts/framework/acts/controllers/openwrt_lib/__init__.py diff --git a/acts/framework/acts/controllers/openwrt_lib/wireless_config.py b/acts/framework/acts/controllers/openwrt_lib/wireless_config.py new file mode 100644 index 0000000000..ea89636e2d --- /dev/null +++ b/acts/framework/acts/controllers/openwrt_lib/wireless_config.py @@ -0,0 +1,50 @@ +"""Class for Wireless config.""" + +NET_IFACE = "lan" + + +class WirelessConfig(object): + """Creates an object to hold wireless config. + + Attributes: + name: name of the wireless config + ssid: SSID of the network. + security: security of the wifi network. + band: band of the wifi network. + iface: network interface of the wifi network. + password: password for psk network. + wep_key: wep keys for wep network. + wep_key_num: key number for wep network. + radius_server_ip: IP address of radius server. + radius_server_port: Port number of radius server. + radius_server_secret: Secret key of radius server. + hidden: Boolean, if the wifi network is hidden. + """ + + def __init__( + self, + name, + ssid, + security, + band, + iface=NET_IFACE, + password=None, + wep_key=None, + wep_key_num=1, + radius_server_ip=None, + radius_server_port=None, + radius_server_secret=None, + hidden=False): + self.name = name + self.ssid = ssid + self.security = security + self.band = band + self.iface = iface + self.password = password + self.wep_key = wep_key + self.wep_key_num = wep_key_num + self.radius_server_ip = radius_server_ip + self.radius_server_port = radius_server_port + self.radius_server_secret = radius_server_secret + self.hidden = hidden + diff --git a/acts/framework/acts/controllers/openwrt_lib/wireless_settings_applier.py b/acts/framework/acts/controllers/openwrt_lib/wireless_settings_applier.py new file mode 100644 index 0000000000..cfb94d1503 --- /dev/null +++ b/acts/framework/acts/controllers/openwrt_lib/wireless_settings_applier.py @@ -0,0 +1,124 @@ +"""Class to configure wireless settings.""" + +import time +from acts.controllers.ap_lib import hostapd_constants + +LEASE_FILE = "/tmp/dhcp.leases" +DNSMASQ_RESTART = "/etc/init.d/dnsmasq restart" +OPEN_SECURITY = "none" +PSK_SECURITY = "psk2" +WEP_SECURITY = "wep" +ENT_SECURITY = "wpa2" +ENABLE_RADIO = "0" +DISABLE_RADIO = "1" +ENABLE_HIDDEN = "1" + + +class WirelessSettingsApplier(object): + """Class for wireless settings. + + Attributes: + ssh: ssh object for the AP. + wireless_configs: a list of + acts.controllers.openwrt_lib.wireless_config.WirelessConfig. + channel_2g: channel for 2G band. + channel_5g: channel for 5G band. + """ + + def __init__(self, ssh, configs, channel_2g, channel_5g): + """Initialize wireless settings. + + Args: + ssh: ssh connection object. + configs: a list of + acts.controllers.openwrt_lib.wireless_config.WirelessConfig. + channel_2g: channel for 2G band. + channel_5g: channel for 5G band. + """ + self.ssh = ssh + self.wireless_configs = configs + self.channel_2g = channel_2g + self.channel_5g = channel_5g + + def apply_wireless_settings(self): + """Configure wireless settings from a list of configs.""" + + # set channels for 2G and 5G bands + self.ssh.run("uci set wireless.radio1.channel='%s'" % self.channel_2g) + self.ssh.run("uci set wireless.radio0.channel='%s'" % self.channel_5g) + + # disable default OpenWrt SSID + self.ssh.run("uci set wireless.default_radio1.disabled='%s'" % + DISABLE_RADIO) + self.ssh.run("uci set wireless.default_radio0.disabled='%s'" % + DISABLE_RADIO) + + # Enable radios + self.ssh.run("uci set wireless.radio1.disabled='%s'" % ENABLE_RADIO) + self.ssh.run("uci set wireless.radio0.disabled='%s'" % ENABLE_RADIO) + + for config in self.wireless_configs: + + # configure open network + if config.security == OPEN_SECURITY: + if config.band == hostapd_constants.BAND_2G: + self.ssh.run("uci set wireless.default_radio1.ssid='%s'" % + config.ssid) + self.ssh.run("uci set wireless.default_radio1.disabled='%s'" % + ENABLE_RADIO) + if config.hidden: + self.ssh.run("uci set wireless.default_radio1.hidden='%s'" % + ENABLE_HIDDEN) + elif config.band == hostapd_constants.BAND_5G: + self.ssh.run("uci set wireless.default_radio0.ssid='%s'" % + config.ssid) + self.ssh.run("uci set wireless.default_radio0.disabled='%s'" % + ENABLE_RADIO) + if config.hidden: + self.ssh.run("uci set wireless.default_radio0.hidden='%s'" % + ENABLE_HIDDEN) + continue + + self.ssh.run("uci set wireless.%s='wifi-iface'" % config.name) + if config.band == hostapd_constants.BAND_2G: + self.ssh.run("uci set wireless.%s.device='radio1'" % config.name) + else: + self.ssh.run("uci set wireless.%s.device='radio0'" % config.name) + self.ssh.run("uci set wireless.%s.network='%s'" % + (config.name, config.iface)) + self.ssh.run("uci set wireless.%s.mode='ap'" % config.name) + self.ssh.run("uci set wireless.%s.ssid='%s'" % + (config.name, config.ssid)) + self.ssh.run("uci set wireless.%s.encryption='%s'" % + (config.name, config.security)) + if config.security == PSK_SECURITY: + self.ssh.run("uci set wireless.%s.key='%s'" % + (config.name, config.password)) + elif config.security == WEP_SECURITY: + self.ssh.run("uci set wireless.%s.key%s='%s'" % + (config.name, config.wep_key_num, config.wep_key)) + self.ssh.run("uci set wireless.%s.key='%s'" % + (config.name, config.wep_key_num)) + elif config.security == ENT_SECURITY: + self.ssh.run("uci set wireless.%s.auth_secret='%s'" % + (config.name, config.radius_server_secret)) + self.ssh.run("uci set wireless.%s.auth_server='%s'" % + (config.name, config.radius_server_ip)) + self.ssh.run("uci set wireless.%s.auth_port='%s'" % + (config.name, config.radius_server_port)) + if config.hidden: + self.ssh.run("uci set wireless.%s.hidden='%s'" % + (config.name, ENABLE_HIDDEN)) + + self.ssh.run("uci commit wireless") + self.ssh.run("cp %s %s.tmp" % (LEASE_FILE, LEASE_FILE)) + + def cleanup_wireless_settings(self): + """Reset wireless settings to default.""" + self.ssh.run("wifi down") + self.ssh.run("rm -f /etc/config/wireless") + self.ssh.run("wifi config") + self.ssh.run("cp %s.tmp %s" % (LEASE_FILE, LEASE_FILE)) + self.ssh.run(DNSMASQ_RESTART) + time.sleep(9) + diff --git a/acts/framework/acts/controllers/power_metrics.py b/acts/framework/acts/controllers/power_metrics.py new file mode 100644 index 0000000000..f68edccbfc --- /dev/null +++ b/acts/framework/acts/controllers/power_metrics.py @@ -0,0 +1,420 @@ +#!/usr/bin/env python3 +# +# Copyright 2019 - The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import math + +# Metrics timestamp keys +START_TIMESTAMP = 'start' +END_TIMESTAMP = 'end' + +# Unit type constants +CURRENT = 'current' +POWER = 'power' +TIME = 'time' +VOLTAGE = 'voltage' + +# Unit constants +MILLIVOLT = 'mV' +VOLT = 'V' +MILLIAMP = 'mA' +AMP = 'A' +AMPERE = AMP +MILLIWATT = 'mW' +WATT = 'W' +MILLISECOND = 'ms' +SECOND = 's' +MINUTE = 'm' +HOUR = 'h' + +CONVERSION_TABLES = { + CURRENT: { + MILLIAMP: 0.001, + AMP: 1 + }, + POWER: { + MILLIWATT: 0.001, + WATT: 1 + }, + TIME: { + MILLISECOND: 0.001, + SECOND: 1, + MINUTE: 60, + HOUR: 3600 + }, + VOLTAGE: { + MILLIVOLT: 0.001, + VOLT : 1 + } +} + + +class AbsoluteThresholds(object): + """Class to represent thresholds in absolute (non-relative) values. + + Attributes: + lower: Lower limit of the threshold represented by a measurement. + upper: Upper limit of the threshold represented by a measurement. + unit_type: Type of the unit (current, power, etc). + unit: The unit for this threshold (W, mW, uW). + """ + + def __init__(self, lower, upper, unit_type, unit): + self.unit_type = unit_type + self.unit = unit + self.lower = Metric(lower, unit_type, unit) + self.upper = Metric(upper, unit_type, unit) + + @staticmethod + def from_percentual_deviation(expected, percentage, unit_type, unit): + """Creates an AbsoluteThresholds object from an expected value and its + allowed percentual deviation (also in terms of the expected value). + + For example, if the expected value is 20 and the deviation 25%, this + would imply that the absolute deviation is 20 * 0.25 = 5 and therefore + the absolute threshold would be from (20-5, 20+5) or (15, 25). + + Args: + expected: Central value from which the deviation will be estimated. + percentage: Percentage of allowed deviation, the percentage itself + is in terms of the expected value. + unit_type: Type of the unit (current, power, etc). + unit: Unit for this threshold (W, mW, uW). + """ + return AbsoluteThresholds(expected * (1 - percentage / 100), + expected * (1 + percentage / 100), + unit_type, + unit) + + @staticmethod + def from_threshold_conf(thresholds_conf): + """Creates a AbsoluteThresholds object from a ConfigWrapper describing + a threshold (either absolute or percentual). + + Args: + thresholds_conf: ConfigWrapper object that describes a threshold. + Returns: + AbsolutesThresholds object. + Raises: + ValueError if configuration is incorrect or incomplete. + """ + if 'unit_type' not in thresholds_conf: + raise ValueError( + 'A threshold config must contain a unit_type. %s is incorrect' + % str(thresholds_conf)) + + if 'unit' not in thresholds_conf: + raise ValueError( + 'A threshold config must contain a unit. %s is incorrect' + % str(thresholds_conf)) + + unit_type = thresholds_conf['unit_type'] + unit = thresholds_conf['unit'] + + is_relative = ( + 'expected_value' in thresholds_conf and + 'percent_deviation' in thresholds_conf) + + is_almost_relative = ( + 'expected_value' in thresholds_conf or + 'percent_deviation' in thresholds_conf) + + is_absolute = ('lower_limit' in thresholds_conf or + 'upper_limit' in thresholds_conf) + + if is_absolute and is_almost_relative: + raise ValueError( + 'Thresholds can either be absolute (with lower_limit and' + 'upper_limit defined) or by percentual deviation (with' + 'expected_value and percent_deviation defined), but never' + 'a mixture of both. %s is incorrect' + % str(thresholds_conf)) + + if is_almost_relative and not is_relative: + if 'expected_value' not in thresholds_conf: + raise ValueError( + 'Incomplete definition of a threshold by percentual ' + 'deviation. percent_deviation given, but missing ' + 'expected_value. %s is incorrect' + % str(thresholds_conf)) + + if 'percent_deviation' not in thresholds_conf: + raise ValueError( + 'Incomplete definition of a threshold by percentual ' + 'deviation. expected_value given, but missing ' + 'percent_deviation. %s is incorrect' + % str(thresholds_conf)) + + if not is_absolute and not is_relative: + raise ValueError( + 'Thresholds must be either absolute (with lower_limit and' + 'upper_limit defined) or defined by percentual deviation (with' + 'expected_value and percent_deviation defined). %s is incorrect' + % str(thresholds_conf)) + + if is_relative: + expected = thresholds_conf.get_numeric('expected_value') + percent = thresholds_conf.get_numeric('percent_deviation') + + thresholds = ( + AbsoluteThresholds.from_percentual_deviation( + expected, + percent, + unit_type, unit)) + + else: + lower_value = thresholds_conf.get_numeric('lower_limit', + float('-inf')) + upper_value = thresholds_conf.get_numeric('upper_limit', + float('inf')) + thresholds = AbsoluteThresholds(lower_value, upper_value, unit_type, + unit) + return thresholds + + +class Metric(object): + """Base class for describing power measurement values. Each object contains + an value and a unit. Enables some basic arithmetic operations with other + measurements of the same unit type. + + Attributes: + value: Numeric value of the measurement + _unit_type: Unit type of the measurement (e.g. current, power) + unit: Unit of the measurement (e.g. W, mA) + """ + + def __init__(self, value, unit_type, unit, name=None): + if unit_type not in CONVERSION_TABLES: + raise TypeError( + '%s is not a valid unit type, valid unit types are %s' % ( + unit_type, str(CONVERSION_TABLES.keys))) + self.value = value + self.unit = unit + self.name = name + self._unit_type = unit_type + + # Convenience constructor methods + @staticmethod + def amps(amps, name=None): + """Create a new current measurement, in amps.""" + return Metric(amps, CURRENT, AMP, name=name) + + @staticmethod + def watts(watts, name=None): + """Create a new power measurement, in watts.""" + return Metric(watts, POWER, WATT, name=name) + + @staticmethod + def seconds(seconds, name=None): + """Create a new time measurement, in seconds.""" + return Metric(seconds, TIME, SECOND, name=name) + + # Comparison methods + + def __eq__(self, other): + return self.value == other.to_unit(self.unit).value + + def __lt__(self, other): + return self.value < other.to_unit(self.unit).value + + def __le__(self, other): + return self == other or self < other + + # Addition and subtraction with other measurements + + def __add__(self, other): + """Adds measurements of compatible unit types. The result will be in the + same units as self. + """ + return Metric(self.value + other.to_unit(self.unit).value, + self._unit_type, self.unit, name=self.name) + + def __sub__(self, other): + """Subtracts measurements of compatible unit types. The result will be + in the same units as self. + """ + return Metric(self.value - other.to_unit(self.unit).value, + self._unit_type, self.unit, name=self.name) + + # String representation + + def __str__(self): + return '%g%s' % (self.value, self.unit) + + def __repr__(self): + return str(self) + + def to_unit(self, new_unit): + """Create an equivalent measurement under a different unit. + e.g. 0.5W -> 500mW + + Args: + new_unit: Target unit. Must be compatible with current unit. + + Returns: A new measurement with the converted value and unit. + """ + try: + new_value = self.value * ( + CONVERSION_TABLES[self._unit_type][self.unit] / + CONVERSION_TABLES[self._unit_type][new_unit]) + except KeyError: + raise TypeError('Incompatible units: %s, %s' % + (self.unit, new_unit)) + return Metric(new_value, self._unit_type, new_unit, self.name) + + +def import_raw_data(path): + """Create a generator from a Monsoon data file. + + Args: + path: path to raw data file + + Returns: generator that yields (timestamp, sample) per line + """ + with open(path, 'r') as f: + for line in f: + time, sample = line.split() + yield float(time[:-1]), float(sample) + + +def generate_test_metrics(raw_data, timestamps=None, + voltage=None): + """Split the data into individual test metrics, based on the timestamps + given as a dict. + + Args: + raw_data: raw data as list or generator of (timestamp, sample) + timestamps: dict following the output format of + instrumentation_proto_parser.get_test_timestamps() + voltage: voltage used during measurements + """ + + # Initialize metrics for each test + if timestamps is None: + timestamps = {} + test_starts = {} + test_ends = {} + test_metrics = {} + for seg_name, times in timestamps.items(): + test_metrics[seg_name] = PowerMetrics(voltage) + try: + test_starts[seg_name] = Metric( + times[START_TIMESTAMP], TIME, MILLISECOND).to_unit( + SECOND).value + except KeyError: + raise ValueError( + 'Missing start timestamp for test scenario "%s". Refer to ' + 'instrumentation_proto.txt for details.' % seg_name) + try: + test_ends[seg_name] = Metric( + times[END_TIMESTAMP], TIME, MILLISECOND).to_unit( + SECOND).value + except KeyError: + raise ValueError( + 'Missing end timestamp for test scenario "%s". Test ' + 'scenario may have terminated with errors. Refer to ' + 'instrumentation_proto.txt for details.' % seg_name) + + # Assign data to tests based on timestamps + for timestamp, amps in raw_data: + for seg_name in timestamps: + if test_starts[seg_name] <= timestamp <= test_ends[seg_name]: + test_metrics[seg_name].update_metrics(amps) + + result = {} + for seg_name, power_metrics in test_metrics.items(): + result[seg_name] = [ + power_metrics.avg_current, + power_metrics.max_current, + power_metrics.min_current, + power_metrics.stdev_current, + power_metrics.avg_power] + return result + + +class PowerMetrics(object): + """Class for processing raw power metrics generated by Monsoon measurements. + Provides useful metrics such as average current, max current, and average + power. Can generate individual test metrics. + + See section "Numeric metrics" below for available metrics. + """ + + def __init__(self, voltage): + """Create a PowerMetrics. + + Args: + voltage: Voltage of the measurement + """ + self._voltage = voltage + self._num_samples = 0 + self._sum_currents = 0 + self._sum_squares = 0 + self._max_current = None + self._min_current = None + self.test_metrics = {} + + def update_metrics(self, sample): + """Update the running metrics with the current sample. + + Args: + sample: A current sample in Amps. + """ + self._num_samples += 1 + self._sum_currents += sample + self._sum_squares += sample ** 2 + if self._max_current is None or sample > self._max_current: + self._max_current = sample + if self._min_current is None or sample < self._min_current: + self._min_current = sample + + # Numeric metrics + @property + def avg_current(self): + """Average current, in milliamps.""" + if not self._num_samples: + return Metric.amps(0).to_unit(MILLIAMP) + return (Metric.amps(self._sum_currents / self._num_samples, + 'avg_current') + .to_unit(MILLIAMP)) + + @property + def max_current(self): + """Max current, in milliamps.""" + return Metric.amps(self._max_current or 0, 'max_current').to_unit( + MILLIAMP) + + @property + def min_current(self): + """Min current, in milliamps.""" + return Metric.amps(self._min_current or 0, 'min_current').to_unit( + MILLIAMP) + + @property + def stdev_current(self): + """Standard deviation of current values, in milliamps.""" + if self._num_samples < 2: + return Metric.amps(0, 'stdev_current').to_unit(MILLIAMP) + stdev = math.sqrt( + (self._sum_squares - ( + self._num_samples * self.avg_current.to_unit(AMP).value ** 2)) + / (self._num_samples - 1)) + return Metric.amps(stdev, 'stdev_current').to_unit(MILLIAMP) + + @property + def avg_power(self): + """Average power, in milliwatts.""" + return Metric.watts(self.avg_current.to_unit(AMP).value * self._voltage, + 'avg_power').to_unit(MILLIWATT) diff --git a/acts/framework/acts/controllers/power_monitor.py b/acts/framework/acts/controllers/power_monitor.py index eb13f54c00..694edd0208 100644 --- a/acts/framework/acts/controllers/power_monitor.py +++ b/acts/framework/acts/controllers/power_monitor.py @@ -14,6 +14,11 @@ # See the License for the specific language governing permissions and # limitations under the License. +import tempfile +import logging +from acts.controllers.monsoon_lib.api.common import MonsoonError +from acts.controllers import power_metrics + class ResourcesRegistryError(Exception): pass @@ -45,3 +50,130 @@ def update_registry(registry): def get_registry(): return _REGISTRY + + +def _write_raw_data_in_standard_format(raw_data, path, start_time): + """Writes the raw data to a file in (seconds since epoch, amps). + + TODO(b/155294049): Deprecate this once Monsoon controller output + format is updated. + + Args: + start_time: Measurement start time in seconds since epoch + raw_data: raw data as list or generator of (timestamp, sample) + path: path to write output + """ + with open(path, 'w') as f: + for timestamp, amps in raw_data: + f.write('%s %s\n' % + (timestamp + start_time, amps)) + + +class BasePowerMonitor(object): + + def setup(self, **kwargs): + raise NotImplementedError() + + def connect_usb(self, **kwargs): + raise NotImplementedError() + + def measure(self, **kwargs): + raise NotImplementedError() + + def release_resources(self, **kwargs): + raise NotImplementedError() + + def disconnect_usb(self, **kwargs): + raise NotImplementedError() + + def get_metrics(self, **kwargs): + raise NotImplementedError() + + def teardown(self, **kwargs): + raise NotImplementedError() + + +class PowerMonitorMonsoonFacade(BasePowerMonitor): + + def __init__(self, monsoon): + """Constructs a PowerMonitorFacade. + + Args: + monsoon: delegate monsoon object, either + acts.controllers.monsoon_lib.api.hvpm.monsoon.Monsoon or + acts.controllers.monsoon_lib.api.lvpm_stock.monsoon.Monsoon. + """ + self.monsoon = monsoon + self._log = logging.getLogger() + + def setup(self, monsoon_config=None, **__): + """Set up the Monsoon controller for this testclass/testcase.""" + + if monsoon_config is None: + raise MonsoonError('monsoon_config can not be None') + + self._log.info('Setting up Monsoon %s' % self.monsoon.serial) + voltage = monsoon_config.get_numeric('voltage', 4.2) + self.monsoon.set_voltage_safe(voltage) + if 'max_current' in monsoon_config: + self.monsoon.set_max_current( + monsoon_config.get_numeric('max_current')) + + def connect_usb(self, **__): + self.monsoon.usb('on') + + def measure(self, measurement_args=None, start_time=None, + output_path=None, **__): + if measurement_args is None: + raise MonsoonError('measurement_args can not be None') + + with tempfile.NamedTemporaryFile(prefix='monsoon_') as tmon: + self.monsoon.measure_power(**measurement_args, + output_path=tmon.name) + + if output_path and start_time is not None: + _write_raw_data_in_standard_format( + power_metrics.import_raw_data(tmon.name), + output_path, + start_time) + + def release_resources(self, **__): + # nothing to do + pass + + def disconnect_usb(self, **__): + self.monsoon.usb('off') + + def get_metrics(self, start_time=None, voltage=None, monsoon_file_path=None, + timestamps=None, **__): + """Parses a monsoon_file_path to compute the consumed power and other + power related metrics. + + Args: + start_time: Time when the measurement started, this is used to + correlate timestamps from the device and from the power samples. + voltage: Voltage used when the measurement started. Used to compute + power from current. + monsoon_file_path: Path to a monsoon file. + timestamps: Named timestamps delimiting the segments of interest. + **__: + + Returns: + A list of power_metrics.Metric. + """ + if start_time is None: + raise MonsoonError('start_time can not be None') + if voltage is None: + raise MonsoonError('voltage can not be None') + if monsoon_file_path is None: + raise MonsoonError('monsoon_file_path can not be None') + if timestamps is None: + raise MonsoonError('timestamps can not be None') + + return power_metrics.generate_test_metrics( + power_metrics.import_raw_data(monsoon_file_path), + timestamps=timestamps, voltage=voltage) + + def teardown(self, **__): + # nothing to do + pass diff --git a/acts/framework/acts/controllers/rohdeschwarz_lib/OWNERS b/acts/framework/acts/controllers/rohdeschwarz_lib/OWNERS new file mode 100644 index 0000000000..e4010df218 --- /dev/null +++ b/acts/framework/acts/controllers/rohdeschwarz_lib/OWNERS @@ -0,0 +1,4 @@ +iguarna@google.com +chaoyangf@google.com +yixiang@google.com +codycaldwell@google.com
\ No newline at end of file diff --git a/acts/framework/acts/controllers/rohdeschwarz_lib/cmw500_cellular_simulator.py b/acts/framework/acts/controllers/rohdeschwarz_lib/cmw500_cellular_simulator.py index 91e71b767a..6a6c3ffd0a 100644 --- a/acts/framework/acts/controllers/rohdeschwarz_lib/cmw500_cellular_simulator.py +++ b/acts/framework/acts/controllers/rohdeschwarz_lib/cmw500_cellular_simulator.py @@ -17,7 +17,7 @@ import time from acts.controllers.rohdeschwarz_lib import cmw500 from acts.controllers import cellular_simulator as cc -from acts.test_utils.power.tel_simulations import LteSimulation +from acts.controllers.cellular_lib import LteSimulation CMW_TM_MAPPING = { LteSimulation.TransmissionMode.TM1: cmw500.TransmissionModes.TM1, diff --git a/acts/framework/acts/controllers/sl4a_lib/event_dispatcher.py b/acts/framework/acts/controllers/sl4a_lib/event_dispatcher.py index c37635e188..e8a49ff166 100644 --- a/acts/framework/acts/controllers/sl4a_lib/event_dispatcher.py +++ b/acts/framework/acts/controllers/sl4a_lib/event_dispatcher.py @@ -215,8 +215,10 @@ class EventDispatcher: # Block forever on event wait return e_queue.get(True) except queue.Empty: - raise queue.Empty('Timeout after {}s waiting for event: {}'.format( - timeout, event_name)) + msg = 'Timeout after {}s waiting for event: {}'.format( + timeout, event_name) + self.log.error(msg) + raise queue.Empty(msg) def wait_for_event(self, event_name, @@ -273,9 +275,10 @@ class EventDispatcher: if time.time() > deadline: for ignored_event in ignored_events: self.get_event_q(event_name).put(ignored_event) - raise queue.Empty( - 'Timeout after {}s waiting for event: {}'.format( - timeout, event_name)) + msg = 'Timeout after {}s waiting for event: {}'.format( + timeout, event_name) + self.log.error(msg) + raise queue.Empty(msg) def pop_events(self, regex_pattern, timeout, freq=1): """Pop events whose names match a regex pattern. @@ -312,8 +315,10 @@ class EventDispatcher: break time.sleep(freq) if len(results) == 0: - raise queue.Empty('Timeout after {}s waiting for event: {}'.format( - timeout, regex_pattern)) + msg = 'Timeout after {}s waiting for event: {}'.format( + timeout, regex_pattern) + self.log.error(msg) + raise queue.Empty(msg) return sorted(results, key=lambda event: event['time']) diff --git a/acts/tests/google/wifi/__init__.py b/acts/framework/acts/controllers/spectracom_lib/__init__.py index e69de29bb2..e69de29bb2 100644 --- a/acts/tests/google/wifi/__init__.py +++ b/acts/framework/acts/controllers/spectracom_lib/__init__.py diff --git a/acts/framework/acts/controllers/spectracom_lib/gsg6.py b/acts/framework/acts/controllers/spectracom_lib/gsg6.py new file mode 100644 index 0000000000..6b96456f3d --- /dev/null +++ b/acts/framework/acts/controllers/spectracom_lib/gsg6.py @@ -0,0 +1,120 @@ +#!/usr/bin/env python3 +# +# Copyright 2019 - The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Python module for Spectracom/Orolia GSG-6 GNSS simulator.""" + +from acts.controllers import abstract_inst + + +class GSG6Error(abstract_inst.SocketInstrumentError): + """GSG-6 Instrument Error Class.""" + + +class GSG6(abstract_inst.SocketInstrument): + """GSG-6 Class, inherted from abstract_inst SocketInstrument.""" + + def __init__(self, ip_addr, ip_port): + """Init method for GSG-6. + + Args: + ip_addr: IP Address. + Type, str. + ip_port: TCPIP Port. + Type, str. + """ + super(GSG6, self).__init__(ip_addr, ip_port) + + self.idn = '' + + def connect(self): + """Init and Connect to GSG-6.""" + self._connect_socket() + + self.get_idn() + + infmsg = 'Connected to GSG-6, with ID: {}'.format(self.idn) + self._logger.debug(infmsg) + + def close(self): + """Close GSG-6.""" + self._close_socket() + + self._logger.debug('Closed connection to GSG-6') + + def get_idn(self): + """Get the Idenification of GSG-6. + + Returns: + GSG-6 Identifier + """ + self.idn = self._query('*IDN?') + + return self.idn + + def start_scenario(self, scenario=''): + """Start to run scenario. + + Args: + scenario: Scenario to run. + Type, str. + Default, '', which will run current selected one. + """ + if scenario: + cmd = 'SOUR:SCEN:LOAD ' + scenario + self._send(cmd) + + self._send('SOUR:SCEN:CONT START') + + if scenario: + infmsg = 'Started running scenario {}'.format(scenario) + else: + infmsg = 'Started running current scenario' + + self._logger.debug(infmsg) + + def stop_scenario(self): + """Stop the running scenario.""" + + self._send('SOUR:SCEN:CONT STOP') + + self._logger.debug('Stopped running scenario') + + def preset(self): + """Preset GSG-6 to default status.""" + self._send('*RST') + + self._logger.debug('Reset GSG-6') + + def set_power(self, power_level): + """set GSG-6 transmit power on all bands. + + Args: + power_level: transmit power level + Type, float. + Decimal, unit [dBm] + + Raises: + GSG6Error: raise when power level is not in [-160, -65] range. + """ + if not -160 <= power_level <= -65: + errmsg = ('"power_level" must be within [-160, -65], ' + 'current input is {}').format(str(power_level)) + raise GSG6Error(error=errmsg, command='set_power') + + self._send(':SOUR:POW ' + str(round(power_level, 1))) + + infmsg = 'Set GSG-6 transmit power to "{}"'.format( + round(power_level, 1)) + self._logger.debug(infmsg) diff --git a/acts/framework/acts/controllers/spirent_lib/__init__.py b/acts/framework/acts/controllers/spirent_lib/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/acts/framework/acts/controllers/spirent_lib/__init__.py diff --git a/acts/framework/acts/controllers/spirent_lib/gss6450.py b/acts/framework/acts/controllers/spirent_lib/gss6450.py new file mode 100644 index 0000000000..aa84575b5a --- /dev/null +++ b/acts/framework/acts/controllers/spirent_lib/gss6450.py @@ -0,0 +1,381 @@ +#!/usr/bin/env python3 +# +# Copyright 2019 - The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Python module for Spirent GSS6450 GNSS RPS.""" + +import datetime +import numbers +from acts.controllers import abstract_inst + + +class GSS6450Error(abstract_inst.SocketInstrumentError): + """GSS6450 Instrument Error Class.""" + + +class GSS6450(abstract_inst.RequestInstrument): + """GSS6450 Class, inherted from abstract_inst RequestInstrument.""" + + def __init__(self, ip_addr): + """Init method for GSS6450. + + Args: + ip_addr: IP Address. + Type, str. + """ + super(GSS6450, self).__init__(ip_addr) + + self.idn = 'Spirent-GSS6450' + + def _put(self, cmd): + """Send put command via GSS6450 HTTP Request and get response. + + Args: + cmd: parameters listed in SHM_PUT. + Type, Str. + + Returns: + resp: Response from the _query method. + Type, Str. + """ + put_cmd = 'shm_put.shtml?' + cmd + resp = self._query(put_cmd) + + return resp + + def _get(self, cmd): + """Send get command via GSS6450 HTTP Request and get response. + + Args: + cmd: parameters listed in SHM_GET. + Type, Str. + + Returns: + resp: Response from the _query method. + Type, Str. + """ + get_cmd = 'shm_get.shtml?' + cmd + resp = self._query(get_cmd) + + return resp + + def get_scenario_filename(self): + """Get the scenario filename of GSS6450. + + Returns: + filename: RPS Scenario file name. + Type, Str. + """ + resp_raw = self._get('-f') + filename = resp_raw.split(':')[-1].strip(' ') + self._logger.debug('Got scenario file name: "%s".', filename) + + return filename + + def get_scenario_description(self): + """Get the scenario description of GSS6450. + + Returns: + description: RPS Scenario description. + Type, Str. + """ + resp_raw = self._get('-d') + description = resp_raw.split('-d')[-1].strip(' ') + + if description: + self._logger.debug('Got scenario description: "%s".', description) + else: + self._logger.warning('Got scenario description with empty string.') + + return description + + def get_scenario_location(self): + """Get the scenario location of GSS6450. + + Returns: + location: RPS Scenario location. + Type, Str. + """ + resp_raw = self._get('-i') + location = resp_raw.split('-i')[-1].strip(' ') + + if location: + self._logger.debug('Got scenario location: "%s".', location) + else: + self._logger.warning('Got scenario location with empty string.') + + return location + + def get_operation_mode(self): + """Get the operation mode of GSS6450. + + Returns: + mode: RPS Operation Mode. + Type, Str. + Option, STOPPED/PLAYING/RECORDING + """ + resp_raw = self._get('-m') + mode = resp_raw.split('-m')[-1].strip(' ') + self._logger.debug('Got operation mode: "%s".', mode) + + return mode + + def get_battery_level(self): + """Get the battery level of GSS6450. + + Returns: + batterylevel: RPS Battery Level. + Type, float. + """ + resp_raw = self._get('-l') + batterylevel = float(resp_raw.split('-l')[-1].strip(' ')) + self._logger.debug('Got battery level: %s%%.', batterylevel) + + return batterylevel + + def get_rfport_voltage(self): + """Get the RF port voltage of GSS6450. + + Returns: + voltageout: RPS RF port voltage. + Type, str + """ + resp_raw = self._get('-v') + voltageout = resp_raw.split('-v')[-1].strip(' ') + self._logger.debug('Got RF port voltage: "%s".', voltageout) + + return voltageout + + def get_storage_media(self): + """Get the storage media of GSS6450. + + Returns: + media: RPS storage. + Type, str + + Raises: + GSS6450Error: raise when request response is not support. + """ + resp_raw = self._get('-M') + resp_num = resp_raw.split('-M')[-1].strip(' ') + + if resp_num == '1': + media = '1-INTERNAL' + elif resp_num == '2': + media = '2-REMOVABLE' + else: + errmsg = ('"{}" is not recognized as GSS6450 valid storage media' + ' type'.format(resp_num)) + raise GSS6450Error(error=errmsg, command='get_storage_media') + + self._logger.debug('Got current storage media: %s.', media) + + return media + + def get_attenuation(self): + """Get the attenuation of GSS6450. + + Returns: + attenuation: RPS attenuation level, in dB. + Type, list of float. + """ + resp_raw = self._get('-a') + resp_str = resp_raw.split('-a')[-1].strip(' ') + self._logger.debug('Got attenuation: %s dB.', resp_str) + attenuation = [float(itm) for itm in resp_str.split(',')] + + return attenuation + + def get_elapsed_time(self): + """Get the running scenario elapsed time of GSS6450. + + Returns: + etime: RPS elapsed time. + Type, datetime.timedelta. + """ + resp_raw = self._get('-e') + resp_str = resp_raw.split('-e')[-1].strip(' ') + self._logger.debug('Got senario elapsed time: "%s".', resp_str) + etime_tmp = datetime.datetime.strptime(resp_str, '%H:%M:%S') + etime = datetime.timedelta(hours=etime_tmp.hour, + minutes=etime_tmp.minute, + seconds=etime_tmp.second) + + return etime + + def get_playback_offset(self): + """Get the running scenario playback offset of GSS6450. + + Returns: + offset: RPS playback offset. + Type, datetime.timedelta. + """ + resp_raw = self._get('-o') + offset_tmp = float(resp_raw.split('-o')[-1].strip(' ')) + self._logger.debug('Got senario playback offset: %s sec.', offset_tmp) + offset = datetime.timedelta(seconds=offset_tmp) + + return offset + + def play_scenario(self, scenario=''): + """Start to play scenario in GSS6450. + + Args: + scenario: Scenario to play. + Type, str. + Default, '', which will run current selected one. + """ + if scenario: + cmd = '-f{},-wP'.format(scenario) + else: + cmd = '-wP' + + _ = self._put(cmd) + + if scenario: + infmsg = 'Started playing scenario: "{}".'.format(scenario) + else: + infmsg = 'Started playing current scenario.' + + self._logger.debug(infmsg) + + def record_scenario(self, scenario=''): + """Start to record scenario in GSS6450. + + Args: + scenario: Scenario to record. + Type, str. + Default, '', which will run current selected one. + """ + if scenario: + cmd = '-f{},-wR'.format(scenario) + else: + cmd = '-wR' + + _ = self._put(cmd) + + if scenario: + infmsg = 'Started recording scenario: "{}".'.format(scenario) + else: + infmsg = 'Started recording scenario.' + + self._logger.debug(infmsg) + + def stop_scenario(self): + """Start to stop playing/recording scenario in GSS6450.""" + _ = self._put('-wS') + + self._logger.debug('Stopped playing/recording scanrio.') + + def set_rfport_voltage(self, voltageout): + """Set the RF port voltage of GSS6450. + + Args: + voltageout: RPS RF port voltage. + Type, str + + Raises: + GSS6450Error: raise when voltageout input is not valid. + """ + if voltageout == 'OFF': + voltage_cmd = '0' + elif voltageout == '3.3V': + voltage_cmd = '3' + elif voltageout == '5V': + voltage_cmd = '5' + else: + errmsg = ('"{}" is not recognized as GSS6450 valid RF port voltage' + ' type'.format(voltageout)) + raise GSS6450Error(error=errmsg, command='set_rfport_voltage') + + _ = self._put('-v{},-wV'.format(voltage_cmd)) + self._logger.debug('Set RF port voltage: "%s".', voltageout) + + def set_attenuation(self, attenuation): + """Set the attenuation of GSS6450. + + Args: + attenuation: RPS attenuation level, in dB. + Type, numerical. + + Raises: + GSS6450Error: raise when attenuation is not in range. + """ + if not 0 <= attenuation <= 31: + errmsg = ('"attenuation" must be within [0, 31], ' + 'current input is {}').format(str(attenuation)) + raise GSS6450Error(error=errmsg, command='set_attenuation') + + attenuation_raw = round(attenuation) + + if attenuation_raw != attenuation: + warningmsg = ('"attenuation" must be integer, current input ' + 'will be rounded to {}'.format(attenuation_raw)) + self._logger.warning(warningmsg) + + _ = self._put('-a{},-wA'.format(attenuation_raw)) + + self._logger.debug('Set attenuation: %s dB.', attenuation_raw) + + def set_playback_offset(self, offset): + """Set the playback offset of GSS6450. + + Args: + offset: RPS playback offset. + Type, datetime.timedelta, or numerical. + + Raises: + GSS6450Error: raise when offset is not numeric or timedelta. + """ + if isinstance(offset, datetime.timedelta): + offset_raw = offset.total_seconds() + elif isinstance(offset, numbers.Number): + offset_raw = offset + else: + raise GSS6450Error(error=('"offset" must be numerical value or ' + 'datetime.timedelta'), + command='set_playback_offset') + + _ = self._put('-o{}'.format(offset_raw)) + + self._logger.debug('Set playback offset: %s sec.', offset_raw) + + def set_storage_media(self, media): + """Set the storage media of GSS6450. + + Args: + media: RPS storage Media, Internal or External. + Type, str. Option, 'internal', 'removable' + + Raises: + GSS6450Error: raise when media option is not support. + """ + if media == 'internal': + raw_media = '1' + elif media == 'removable': + raw_media = '2' + else: + raise GSS6450Error( + error=('"media" input must be in ["internal", "removable"]. ' + ' Current input is {}'.format(media)), + command='set_storage_media') + + _ = self._put('-M{}-wM'.format(raw_media)) + + resp_raw = self.get_storage_media() + if raw_media != resp_raw[0]: + raise GSS6450Error( + error=('Setting media "{}" is not the same as queried media ' + '"{}".'.format(media, resp_raw)), + command='set_storage_media') diff --git a/acts/framework/acts/controllers/utils_lib/commands/shell.py b/acts/framework/acts/controllers/utils_lib/commands/shell.py index 5c74cd899b..81a2f13f3d 100644 --- a/acts/framework/acts/controllers/utils_lib/commands/shell.py +++ b/acts/framework/acts/controllers/utils_lib/commands/shell.py @@ -28,7 +28,6 @@ class ShellCommand(object): Note: At the moment this only works with the ssh runner. """ - def __init__(self, runner, working_dir=None): """Creates a new shell command invoker. @@ -40,7 +39,7 @@ class ShellCommand(object): self._runner = runner self._working_dir = working_dir - def run(self, command, timeout=3600): + def run(self, command, timeout=60): """Runs a generic command through the runner. Takes the command and prepares it to be run in the target shell using @@ -129,8 +128,7 @@ class ShellCommand(object): True if the string or pattern was found, False otherwise. """ try: - self.run('grep %s %s' % (shlex.quote(search_string), - file_name)) + self.run('grep %s %s' % (shlex.quote(search_string), file_name)) return True except job.Error: return False diff --git a/acts/framework/acts/controllers/utils_lib/ssh/connection.py b/acts/framework/acts/controllers/utils_lib/ssh/connection.py index c8e498345f..71758bb335 100644 --- a/acts/framework/acts/controllers/utils_lib/ssh/connection.py +++ b/acts/framework/acts/controllers/utils_lib/ssh/connection.py @@ -37,7 +37,6 @@ class CommandError(Exception): Attributes: result: The results of the ssh command that had the error. """ - def __init__(self, result): """ Args: @@ -62,7 +61,6 @@ class SshConnection(object): a command is run. If the persistent connection fails it will attempt to connect normally. """ - @property def socket_path(self): """Returns: The os path to the master socket file.""" @@ -120,7 +118,8 @@ class SshConnection(object): if self._master_ssh_proc is None: # Create a shared socket in a temp location. - self._master_ssh_tempdir = tempfile.mkdtemp(prefix='ssh-master') + self._master_ssh_tempdir = tempfile.mkdtemp( + prefix='ssh-master') # Setup flags and options for running the master ssh # -N: Do not execute a remote command. @@ -153,7 +152,7 @@ class SshConnection(object): def run(self, command, - timeout=3600, + timeout=60, ignore_status=False, env=None, io_encoding='utf-8', @@ -205,16 +204,16 @@ class SshConnection(object): dns_retry_count = 2 while True: - result = job.run( - terminal_command, - ignore_status=True, - timeout=timeout, - io_encoding=io_encoding) + result = job.run(terminal_command, + ignore_status=True, + timeout=timeout, + io_encoding=io_encoding) output = result.stdout # Check for a connected message to prevent false negatives. - valid_connection = re.search( - '^CONNECTED: %s' % identifier, output, flags=re.MULTILINE) + valid_connection = re.search('^CONNECTED: %s' % identifier, + output, + flags=re.MULTILINE) if valid_connection: # Remove the first line that contains the connect message. line_index = output.find('\n') + 1 @@ -222,14 +221,13 @@ class SshConnection(object): line_index = len(output) real_output = output[line_index:].encode(io_encoding) - result = job.Result( - command=result.command, - stdout=real_output, - stderr=result._raw_stderr, - exit_status=result.exit_status, - duration=result.duration, - did_timeout=result.did_timeout, - encoding=io_encoding) + result = job.Result(command=result.command, + stdout=real_output, + stderr=result._raw_stderr, + exit_status=result.exit_status, + duration=result.duration, + did_timeout=result.did_timeout, + encoding=io_encoding) if result.exit_status and not ignore_status: raise job.Error(result) return result @@ -268,9 +266,10 @@ class SshConnection(object): if unknown_host: raise Error('Unknown host.', result) - self.log.error('An unknown error has occurred. Job result: %s' % result) - ping_output = job.run( - 'ping %s -c 3 -w 1' % self._settings.hostname, ignore_status=True) + self.log.error('An unknown error has occurred. Job result: %s' % + result) + ping_output = job.run('ping %s -c 3 -w 1' % self._settings.hostname, + ignore_status=True) self.log.error('Ping result: %s' % ping_output) if attempts > 1: self._cleanup_master_ssh() @@ -403,9 +402,8 @@ class SshConnection(object): """ # TODO: This may belong somewhere else: b/32572515 user_host = self._formatter.format_host_name(self._settings) - job.run( - 'scp %s %s:%s' % (local_path, user_host, remote_path), - ignore_status=ignore_status) + job.run('scp %s %s:%s' % (local_path, user_host, remote_path), + ignore_status=ignore_status) def pull_file(self, local_path, remote_path, ignore_status=False): """Send a file from remote host to local host @@ -416,9 +414,8 @@ class SshConnection(object): ignore_status: Whether or not to ignore the command's exit_status. """ user_host = self._formatter.format_host_name(self._settings) - job.run( - 'scp %s:%s %s' % (user_host, remote_path, local_path), - ignore_status=ignore_status) + job.run('scp %s:%s %s' % (user_host, remote_path, local_path), + ignore_status=ignore_status) def find_free_port(self, interface_name='localhost'): """Find a unused port on the remote host. diff --git a/acts/framework/acts/keys.py b/acts/framework/acts/keys.py index eae9a3bb14..ae8945682c 100644 --- a/acts/framework/acts/keys.py +++ b/acts/framework/acts/keys.py @@ -57,6 +57,7 @@ class Config(enum.Enum): key_arduino_wifi_dongle = 'ArduinoWifiDongle' key_packet_capture = 'PacketCapture' key_pdu = 'PduDevice' + key_openwrt_ap = 'OpenWrtAP' # Internal keys, used internally, not exposed to user's config files. ikey_user_param = 'user_params' ikey_testbed_name = 'testbed_name' @@ -81,6 +82,7 @@ class Config(enum.Enum): m_key_arduino_wifi_dongle = 'arduino_wifi_dongle' m_key_packet_capture = 'packet_capture' m_key_pdu = 'pdu' + m_key_openwrt_ap = 'openwrt_ap' # A list of keys whose values in configs should not be passed to test # classes without unpacking first. @@ -104,7 +106,8 @@ class Config(enum.Enum): key_chameleon_device, key_arduino_wifi_dongle, key_packet_capture, - key_pdu + key_pdu, + key_openwrt_ap, ] # Keys that are file or folder paths. diff --git a/acts/framework/acts/libs/logging/log_stream.py b/acts/framework/acts/libs/logging/log_stream.py index fbf0474d13..1003a7da53 100644 --- a/acts/framework/acts/libs/logging/log_stream.py +++ b/acts/framework/acts/libs/logging/log_stream.py @@ -235,7 +235,8 @@ class _LogStream(object): # Add a NullHandler to suppress unwanted console output self.logger.addHandler(_null_handler) self.logger.propagate = False - self.base_path = base_path or logging.log_path + self.base_path = base_path or getattr(logging, 'log_path', + '/tmp/acts_logs') self.subcontext = subcontext context.TestContext.add_base_output_path(self.logger.name, self.base_path) context.TestContext.add_subcontext(self.logger.name, self.subcontext) diff --git a/acts/framework/acts/libs/proc/process.py b/acts/framework/acts/libs/proc/process.py index 6d444a41f6..3a49cfc8c9 100644 --- a/acts/framework/acts/libs/proc/process.py +++ b/acts/framework/acts/libs/proc/process.py @@ -159,8 +159,7 @@ class Process(object): if _on_windows: subprocess.check_call('taskkill /F /T /PID %s' % self._process.pid) else: - pgid = os.getpgid(self._process.pid) - os.killpg(pgid, signal.SIGKILL) + self.signal(signal.SIGKILL) def wait(self, kill_timeout=60.0): """Waits for the process to finish execution. @@ -186,6 +185,18 @@ class Process(object): self._join_threads() self._started = False + def signal(self, sig): + """Sends a signal to the process. + + Args: + sig: The signal to be sent. + """ + if _on_windows: + raise ProcessError('Unable to call Process.signal on windows.') + + pgid = os.getpgid(self._process.pid) + os.killpg(pgid, sig) + def stop(self): """Stops the process. diff --git a/acts/framework/acts/test_decorators.py b/acts/framework/acts/test_decorators.py index bf407d1652..937c6db58f 100644 --- a/acts/framework/acts/test_decorators.py +++ b/acts/framework/acts/test_decorators.py @@ -58,7 +58,9 @@ def repeated_test(num_passes, acceptable_failures=0, return the median, or gather and return standard deviation values. This decorator should be used on test cases, and should not be used on - static or class methods. + static or class methods. The test case must take in an additional argument, + `attempt_number`, which returns the current attempt number, starting from + 1. Note that any TestSignal intended to abort or skip the test will take abort or skip immediately. @@ -84,7 +86,7 @@ def repeated_test(num_passes, acceptable_failures=0, test_signals_received = [] for i in range(num_passes + acceptable_failures): try: - func(self) + func(self, i + 1) except (signals.TestFailure, signals.TestError, AssertionError) as signal: test_signals_received.append(signal) diff --git a/acts/framework/acts/test_utils/abstract_devices/wlan_device.py b/acts/framework/acts/test_utils/abstract_devices/wlan_device.py index 16da4ae41e..01a9231949 100644 --- a/acts/framework/acts/test_utils/abstract_devices/wlan_device.py +++ b/acts/framework/acts/test_utils/abstract_devices/wlan_device.py @@ -43,6 +43,9 @@ def create_wlan_device(hardware_device): type(hardware_device)) +FUCHSIA_VALID_SECURITY_TYPES = {"none", "wep", "wpa", "wpa2", "wpa3"} + + class WlanDevice(object): """Class representing a generic WLAN device. @@ -55,6 +58,7 @@ class WlanDevice(object): def __init__(self, device): self.device = device self.log = logging + self.identifier = None def wifi_toggle_state(self, state): """Base generic WLAN interface. Only called if not overridden by @@ -135,7 +139,23 @@ class WlanDevice(object): raise NotImplementedError("{} must be defined.".format( inspect.currentframe().f_code.co_name)) - def ping(self, dest_ip, count=3, interval=1000, timeout=1000, size=25): + def can_ping(self, + dest_ip, + count=3, + interval=1000, + timeout=1000, + size=25, + additional_ping_params=None): + raise NotImplementedError("{} must be defined.".format( + inspect.currentframe().f_code.co_name)) + + def ping(self, + dest_ip, + count=3, + interval=1000, + timeout=1000, + size=25, + additional_ping_params=None): raise NotImplementedError("{} must be defined.".format( inspect.currentframe().f_code.co_name)) @@ -143,6 +163,14 @@ class WlanDevice(object): raise NotImplementedError("{} must be defined.".format( inspect.currentframe().f_code.co_name)) + def save_network(self, ssid): + raise NotImplementedError("{} must be defined.".format( + inspect.currentframe().f_code.co_name)) + + def clear_saved_networks(self): + raise NotImplementedError("{} must be defined.".format( + inspect.currentframe().f_code.co_name)) + class AndroidWlanDevice(WlanDevice): """Class wrapper for an Android WLAN device. @@ -155,6 +183,7 @@ class AndroidWlanDevice(WlanDevice): """ def __init__(self, android_device): super().__init__(android_device) + self.identifier = android_device.serial def wifi_toggle_state(self, state): awutils.wifi_toggle_state(self.device, state) @@ -226,15 +255,30 @@ class AndroidWlanDevice(WlanDevice): return 'BSSID' in wifi_info and wifi_info['SSID'] == ssid return 'BSSID' in wifi_info - def ping(self, dest_ip, count=3, interval=1000, timeout=1000, size=25): + def can_ping(self, + dest_ip, + count=3, + interval=1000, + timeout=1000, + size=25, + additional_ping_params=None): return adb_shell_ping(self.device, dest_ip=dest_ip, count=count, timeout=timeout) + def ping(self, dest_ip, count=3, interval=1000, timeout=1000, size=25): + pass + def hard_power_cycle(self, pdus): pass + def save_network(self, ssid): + pass + + def clear_saved_networks(self): + pass + class FuchsiaWlanDevice(WlanDevice): """Class wrapper for an Fuchsia WLAN device. @@ -247,6 +291,7 @@ class FuchsiaWlanDevice(WlanDevice): """ def __init__(self, fuchsia_device): super().__init__(fuchsia_device) + self.identifier = fuchsia_device.ip def wifi_toggle_state(self, state): """Stub for Fuchsia implementation.""" @@ -302,13 +347,34 @@ class FuchsiaWlanDevice(WlanDevice): def status(self): return self.device.wlan_lib.wlanStatus() - def ping(self, dest_ip, count=3, interval=1000, timeout=1000, size=25): - ping_result = self.device.ping(dest_ip, - count=count, - interval=interval, - timeout=timeout, - size=size) - return ping_result['status'] + def can_ping(self, + dest_ip, + count=3, + interval=1000, + timeout=1000, + size=25, + additional_ping_params=None): + return self.device.can_ping( + dest_ip, + count=count, + interval=interval, + timeout=timeout, + size=size, + additional_ping_params=additional_ping_params) + + def ping(self, + dest_ip, + count=3, + interval=1000, + timeout=1000, + size=25, + additional_ping_params=None): + return self.device.ping(dest_ip, + count=count, + interval=interval, + timeout=timeout, + size=size, + additional_ping_params=additional_ping_params) def get_wlan_interface_id_list(self): """Function to list available WLAN interfaces. @@ -345,7 +411,7 @@ class FuchsiaWlanDevice(WlanDevice): def is_connected(self, ssid=None): """ Determines if wlan_device is connected to wlan network. - + Args: ssid (optional): string, to check if device is connect to a specific network. @@ -373,3 +439,18 @@ class FuchsiaWlanDevice(WlanDevice): def hard_power_cycle(self, pdus): self.device.reboot(reboot_type='hard', testbed_pdus=pdus) + + def save_network(self, target_ssid, security_type=None, target_pwd=None): + if security_type and security_type not in FUCHSIA_VALID_SECURITY_TYPES: + raise TypeError('Invalid security type: %s' % security_type) + response = self.device.wlan_policy_lib.wlanSaveNetwork( + target_ssid, security_type, target_pwd=target_pwd) + if response.get('error'): + raise EnvironmentError('Failed to save network %s. Err: %s' % + (target_ssid, response.get('error'))) + + def clear_saved_networks(self): + response = self.device.wlan_policy_lib.wlanRemoveAllNetworks() + if response.get('error'): + raise EnvironmentError('Failed to clear saved networks: %s' % + response.get('error')) diff --git a/acts/framework/acts/test_utils/abstract_devices/wlan_device_lib/AbstractDeviceWlanDeviceBaseTest.py b/acts/framework/acts/test_utils/abstract_devices/wlan_device_lib/AbstractDeviceWlanDeviceBaseTest.py index b18c4ec8a0..6dfa376321 100644 --- a/acts/framework/acts/test_utils/abstract_devices/wlan_device_lib/AbstractDeviceWlanDeviceBaseTest.py +++ b/acts/framework/acts/test_utils/abstract_devices/wlan_device_lib/AbstractDeviceWlanDeviceBaseTest.py @@ -21,8 +21,11 @@ class AbstractDeviceWlanDeviceBaseTest(WifiBaseTest): super().setup_class() def on_fail(self, test_name, begin_time): - self.dut.take_bug_report(test_name, begin_time) - self.dut.get_log(test_name, begin_time) + try: + self.dut.take_bug_report(test_name, begin_time) + self.dut.get_log(test_name, begin_time) + except Exception: + pass try: if self.dut.device.hard_reboot_on_fail: diff --git a/acts/framework/acts/test_utils/bt/A2dpBaseTest.py b/acts/framework/acts/test_utils/bt/A2dpBaseTest.py index 1b7afa890a..bcc5bdbf1e 100644 --- a/acts/framework/acts/test_utils/bt/A2dpBaseTest.py +++ b/acts/framework/acts/test_utils/bt/A2dpBaseTest.py @@ -27,6 +27,7 @@ from acts.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest PHONE_MUSIC_FILE_DIRECTORY = '/sdcard/Music' INIT_ATTEN = 0 +WAIT_TIME = 1 class A2dpBaseTest(BluetoothBaseTest): @@ -124,7 +125,7 @@ class A2dpBaseTest(BluetoothBaseTest): self.log.info('Play and record audio for {} second'.format(duration)) self.media.play() self.audio_device.start() - time.sleep(duration) + time.sleep(duration + WAIT_TIME) audio_captured = self.audio_device.stop() self.media.stop() self.log.info('Audio play and record stopped') diff --git a/acts/framework/acts/test_utils/bt/BtInterferenceBaseTest.py b/acts/framework/acts/test_utils/bt/BtInterferenceBaseTest.py new file mode 100644 index 0000000000..5882bc63b5 --- /dev/null +++ b/acts/framework/acts/test_utils/bt/BtInterferenceBaseTest.py @@ -0,0 +1,238 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2019 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +"""Stream music through connected device from phone across different +attenuations.""" + +import json +import math +import time +import acts.controllers.iperf_client as ipc +import acts.controllers.iperf_server as ipf +import acts.test_utils.bt.bt_test_utils as btutils +from acts import asserts +from acts.test_utils.bt.A2dpBaseTest import A2dpBaseTest +from acts.test_utils.bt.loggers import bluetooth_metric_logger as log +from acts.test_utils.wifi import wifi_performance_test_utils as wpeutils +from acts.test_utils.wifi import wifi_power_test_utils as wputils +from acts.test_utils.wifi import wifi_test_utils as wutils +from acts.test_utils.power.PowerBaseTest import ObjNew + +MAX_ATTENUATION = 95 +TEMP_FILE = '/sdcard/Download/tmp.log' +IPERF_CLIENT_ERROR = 'the client has unexpectedly closed the connection' + + +def setup_ap_connection(dut, network, ap, bandwidth=20): + """Setup AP and connect DUT to it. + + Args: + dut: the android device to connect and run traffic + network: the network config for the AP to be setup + ap: access point object + bandwidth: bandwidth of the WiFi network to be setup + Returns: + self.brconfigs: dict for bridge interface configs + """ + wutils.wifi_toggle_state(dut, True) + brconfigs = wputils.ap_setup(ap, network, bandwidth=bandwidth) + wutils.wifi_connect(dut, network, num_of_tries=3) + return brconfigs + + +def start_iperf_client(traffic_pair_obj, duration): + """Setup iperf traffic for TCP downlink. + Args: + traffic_pair_obj: obj to contain info on traffic pair + duration: duration of iperf traffic to run + """ + # Construct the iperf command based on the test params + iperf_cmd = 'iperf3 -c {} -i 1 -t {} -p {} -J -R > {}'.format( + traffic_pair_obj.server_address, duration, + traffic_pair_obj.iperf_server.port, TEMP_FILE) + # Start IPERF client + traffic_pair_obj.dut.adb.shell_nb(iperf_cmd) + + +def unpack_custom_file(file): + """Unpack the json file to . + + Args: + file: custom json file. + """ + with open(file, 'r') as f: + params = json.load(f) + return params + + +def get_iperf_results(iperf_server_obj): + """Get the iperf results and process. + + Args: + iperf_server_obj: the IperfServer object + Returns: + throughput: the average throughput during tests. + """ + # Get IPERF results and add this to the plot title + iperf_file = iperf_server_obj.log_files[-1] + try: + iperf_result = ipf.IPerfResult(iperf_file) + # Compute the throughput in Mbit/s + if iperf_result.error == IPERF_CLIENT_ERROR: + rates = [] + for item in iperf_result.result['intervals']: + rates.append(item['sum']['bits_per_second'] / 8 / 1024 / 1024) + throughput = ((math.fsum(rates) / len(rates))) * 8 * (1.024**2) + else: + throughput = (math.fsum(iperf_result.instantaneous_rates) / len( + iperf_result.instantaneous_rates)) * 8 * (1.024**2) + except (ValueError, TypeError): + throughput = 0 + return throughput + + +class BtInterferenceBaseTest(A2dpBaseTest): + def __init__(self, configs): + super().__init__(configs) + self.bt_logger = log.BluetoothMetricLogger.for_test_case() + self.start_time = time.time() + req_params = [ + 'attenuation_vector', 'wifi_networks', 'codecs', 'custom_files', + 'audio_params' + ] + self.unpack_userparams(req_params) + for file in self.custom_files: + if 'static_interference' in file: + self.static_wifi_interference = unpack_custom_file(file) + elif 'dynamic_interference' in file: + self.dynamic_wifi_interference = unpack_custom_file(file) + + def setup_class(self): + super().setup_class() + # Build object to store all necessary information for each pair of wifi + # interference setup: phone, ap, network, channel, iperf server port/ip + # object and bridge interface configs + if len(self.android_devices) < 5 or len(self.attenuators) < 4: + self.log.error('Need a 4 channel attenuator and 5 android phones' + 'please update the config file') + self.wifi_int_pairs = [] + for i in range(len(self.attenuators) - 1): + tmp_dict = { + 'dut': self.android_devices[i + 1], + 'ap': self.access_points[i], + 'network': self.wifi_networks[i], + 'channel': self.wifi_networks[i]['channel'], + 'iperf_server': self.iperf_servers[i], + 'attenuator': self.attenuators[i + 1], + 'ether_int': self.packet_senders[i], + 'iperf_client': + ipc.IPerfClientOverAdb(self.android_devices[i + 1]) + } + tmp_obj = ObjNew(**tmp_dict) + self.wifi_int_pairs.append(tmp_obj) + ##Setup connection between WiFi APs and Phones and get DHCP address + # for the interface + for obj in self.wifi_int_pairs: + brconfigs = setup_ap_connection(obj.dut, obj.network, obj.ap) + iperf_server_address = wputils.wait_for_dhcp( + obj.ether_int.interface) + setattr(obj, 'server_address', iperf_server_address) + setattr(obj, 'brconfigs', brconfigs) + obj.attenuator.set_atten(MAX_ATTENUATION) + # Enable BQR on master and slave Android device + btutils.enable_bqr(self.dut) + btutils.enable_bqr(self.bt_device_controller) + + def teardown_class(self): + super().teardown_class() + for obj in self.wifi_int_pairs: + obj.ap.bridge.teardown(obj.brconfigs) + self.log.info('Stop IPERF server at port {}'.format( + obj.iperf_server.port)) + obj.iperf_server.stop() + self.log.info('Stop IPERF process on {}'.format(obj.dut.serial)) + obj.dut.adb.shell('pkill -9 iperf3') + #only for glinux machine + # wputils.bring_down_interface(obj.ether_int.interface) + obj.attenuator.set_atten(MAX_ATTENUATION) + obj.ap.close() + + def teardown_test(self): + + super().teardown_test() + + for obj in self.wifi_int_pairs: + obj.attenuator.set_atten(MAX_ATTENUATION) + + def play_and_record_audio(self, duration, queue): + """Play and record audio for a set duration. + + Args: + duration: duration in seconds for music playing + que: multiprocess que to store the return value of this function + Returns: + audio_captured: captured audio file path + """ + + self.log.info('Play and record audio for {} second'.format(duration)) + self.media.play() + self.audio_device.start() + time.sleep(duration) + audio_captured = self.audio_device.stop() + self.media.stop() + self.log.info('Audio play and record stopped') + asserts.assert_true(audio_captured, 'Audio not recorded') + queue.put(audio_captured) + + def locate_interference_pair_by_channel(self, interference_channels): + """Function to find which attenautor to set based on channel info + Args: + interference_channels: list of interference channels + Return: + interference_pair_indices: list of indices for interference pair + in self.wifi_int_pairs + """ + interference_pair_indices = [] + for chan in interference_channels: + for i in range(len(self.wifi_int_pairs)): + if self.wifi_int_pairs[i].channel == chan: + interference_pair_indices.append(i) + return interference_pair_indices + + def get_interference_rssi(self): + """Function to read wifi interference RSSI level.""" + + bssids = [] + self.interference_rssi = [] + wutils.wifi_toggle_state(self.android_devices[0], True) + for item in self.wifi_int_pairs: + ssid = item.network['SSID'] + bssid = item.ap.get_bssid_from_ssid(ssid, '2g') + bssids.append(bssid) + interference_rssi_dict = { + "ssid": ssid, + "bssid": bssid, + "chan": item.channel, + "rssi": 0 + } + self.interference_rssi.append(interference_rssi_dict) + scaned_rssi = wpeutils.get_scan_rssi(self.android_devices[0], + bssids, + num_measurements=2) + for item in self.interference_rssi: + item['rssi'] = scaned_rssi[item['bssid']]['mean'] + self.log.info('Interference RSSI at channel {} is {} dBm'.format( + item['chan'], item['rssi'])) + wutils.wifi_toggle_state(self.android_devices[0], False) diff --git a/acts/framework/acts/test_utils/bt/BtSarBaseTest.py b/acts/framework/acts/test_utils/bt/BtSarBaseTest.py index 77ef27e7e7..509140778b 100644 --- a/acts/framework/acts/test_utils/bt/BtSarBaseTest.py +++ b/acts/framework/acts/test_utils/bt/BtSarBaseTest.py @@ -24,6 +24,7 @@ from acts import asserts from acts.libs.proc import job from acts.base_test import BaseTestClass +from acts.metrics.loggers.blackbox import BlackboxMetricLogger from acts.test_utils.bt.bt_power_test_utils import MediaControl from acts.test_utils.bt.ble_performance_test_utils import run_ble_throughput_and_read_rssi from acts.test_utils.abstract_devices.bluetooth_handsfree_abstract_device import BluetoothHandsfreeAbstractDeviceFactory as bt_factory @@ -37,6 +38,8 @@ FORCE_SAR_ADB_COMMAND = ('am broadcast -n' 'com.google.android.apps.scone/.coex.TestReceiver -a ' 'com.google.android.apps.scone.coex.SIMULATE_STATE ') +SLEEP_DURATION = 2 + DEFAULT_DURATION = 5 DEFAULT_MAX_ERROR_THRESHOLD = 2 DEFAULT_AGG_MAX_ERROR_THRESHOLD = 2 @@ -56,6 +59,8 @@ class BtSarBaseTest(BaseTestClass): '/vendor/etc/bluetooth_power_limits.csv', '/data/vendor/radio/bluetooth_power_limits.csv' ] + self.sar_test_result = BlackboxMetricLogger.for_test_case( + metric_name='pass') self.sar_file_name = os.path.basename(self.power_file_paths[0]) self.power_column = 'BluetoothPower' self.REG_DOMAIN_DICT = { @@ -78,22 +83,25 @@ class BtSarBaseTest(BaseTestClass): 'bt_sar_test_params was not found in the config file.') self.user_params.update(self.test_params) - req_params = ['bt_devices', 'calibration_params'] + req_params = ['bt_devices', 'calibration_params', 'custom_files'] self.unpack_userparams( req_params, country_code='us', duration=DEFAULT_DURATION, - custom_sar_path=None, - music_files=None, sort_order=None, max_error_threshold=DEFAULT_MAX_ERROR_THRESHOLD, agg_error_threshold=DEFAULT_AGG_MAX_ERROR_THRESHOLD, tpc_threshold=[2, 8], - ) + sar_margin={ + 'BDR': 0, + 'EDR': 0, + 'BLE': 0 + }) self.attenuator = self.attenuators[0] self.dut = self.android_devices[0] + for key in self.REG_DOMAIN_DICT.keys(): if self.country_code.lower() in key: self.reg_domain = self.REG_DOMAIN_DICT[key] @@ -103,21 +111,32 @@ class BtSarBaseTest(BaseTestClass): if 'Error' not in self.dut.adb.shell('bluetooth_sar_test -r'): #Flag for SAR version 2 self.sar_version_2 = True - phone_sku = self.dut.adb.shell('getprop ro.boot.hardware.sku') self.power_column = 'BluetoothEDRPower' self.power_file_paths[0] = os.path.join( os.path.dirname(self.power_file_paths[0]), - 'bluetooth_power_limits_{}_{}.csv'.format( - phone_sku, self.reg_domain)) + 'bluetooth_power_limits_{}.csv'.format(self.reg_domain)) self.sar_file_name = os.path.basename(self.power_file_paths[0]) + if self.sar_version_2: + custom_file_suffix = 'version2' + else: + custom_file_suffix = 'version1' + + for file in self.custom_files: + if 'custom_sar_table_{}.csv'.format(custom_file_suffix) in file: + self.custom_sar_path = file + break + else: + raise RuntimeError('Custom Sar File is missing') + self.sar_file_path = self.power_file_paths[0] self.atten_min = 0 self.atten_max = int(self.attenuator.get_max_atten()) - # Initializing media controller - if self.music_files: - music_src = self.music_files[0] + # Get music file and push it to the phone and initialize Media controller + music_files = self.user_params.get('music_files', []) + if music_files: + music_src = music_files[0] music_dest = PHONE_MUSIC_FILE_DIRECTORY success = self.dut.push_system_file(music_src, music_dest) if success: @@ -145,6 +164,9 @@ class BtSarBaseTest(BaseTestClass): def setup_test(self): super().setup_test() + #Reset SAR test result to 0 before every test + self.sar_test_result.metric_value = 0 + # Starting BT on the master self.dut.droid.bluetoothFactoryReset() bt_utils.enable_bluetooth(self.dut.droid, self.dut.ed) @@ -197,24 +219,74 @@ class BtSarBaseTest(BaseTestClass): Args: df: Processed SAR table sweep results """ - self.plot.add_line(df.index, - df['expected_tx_power'], - legend='expected', - marker='circle') - self.plot.add_line(df.index, - df['measured_tx_power'], - legend='measured', - marker='circle') - self.plot.add_line(df.index, - df['delta'], - legend='delta', - marker='circle') - - results_file_path = os.path.join( - self.log_path, '{}.html'.format(self.current_test_name)) + self.plot.add_line( + df.index, + df['expected_tx_power'], + legend='expected', + marker='circle') + self.plot.add_line( + df.index, + df['measured_tx_power'], + legend='measured', + marker='circle') + self.plot.add_line( + df.index, df['delta'], legend='delta', marker='circle') + + results_file_path = os.path.join(self.log_path, '{}.html'.format( + self.current_test_name)) self.plot.generate_figure() wifi_utils.BokehFigure.save_figures([self.plot], results_file_path) + def sweep_power_cap(self): + sar_df = self.bt_sar_df + sar_df['BDR_power_cap'] = -128 + sar_df['EDR_power_cap'] = -128 + sar_df['BLE_power_cap'] = -128 + + if self.sar_version_2: + power_column_dict = { + 'BDR': 'BluetoothBDRPower', + 'EDR': 'BluetoothEDRPower', + 'BLE': 'BluetoothLEPower' + } + else: + power_column_dict = {'EDR': self.power_column} + + power_cap_error = False + + for type, column_name in power_column_dict.items(): + + self.log.info("Performing sanity test on {}".format(type)) + # Iterating through the BT SAR scenarios + for scenario in range(0, self.bt_sar_df.shape[0]): + # Reading BT SAR table row into dict + read_scenario = sar_df.loc[scenario].to_dict() + start_time = self.dut.adb.shell('date +%s.%m') + time.sleep(SLEEP_DURATION) + + # Setting SAR state to the read BT SAR row + self.set_sar_state(self.dut, read_scenario, self.country_code) + + # Reading device power cap from logcat after forcing SAR State + scenario_power_cap = self.get_current_power_cap( + self.dut, start_time, type=type) + sar_df.loc[scenario, '{}_power_cap'.format( + type)] = scenario_power_cap + self.log.info( + 'scenario: {}, ' + 'sar_power: {}, power_cap:{}'.format( + scenario, sar_df.loc[scenario, column_name], + sar_df.loc[scenario, '{}_power_cap'.format(type)])) + + if not sar_df['{}_power_cap'.format(type)].equals(sar_df[column_name]): + power_cap_error = True + + results_file_path = os.path.join(self.log_path, '{}.csv'.format( + self.current_test_name)) + sar_df.to_csv(results_file_path) + + return power_cap_error + def sweep_table(self, client_ad=None, server_ad=None, @@ -248,11 +320,11 @@ class BtSarBaseTest(BaseTestClass): # Sorts the table if self.sort_order: if self.sort_order.lower() == 'ascending': - sar_df = sar_df.sort_values(by=[self.power_column], - ascending=True) + sar_df = sar_df.sort_values( + by=[self.power_column], ascending=True) else: - sar_df = sar_df.sort_values(by=[self.power_column], - ascending=False) + sar_df = sar_df.sort_values( + by=[self.power_column], ascending=False) sar_df = sar_df.reset_index(drop=True) # Sweeping BT SAR table @@ -261,7 +333,7 @@ class BtSarBaseTest(BaseTestClass): read_scenario = sar_df.loc[scenario].to_dict() start_time = self.dut.adb.shell('date +%s.%m') - time.sleep(1) + time.sleep(SLEEP_DURATION) #Setting SAR State self.set_sar_state(self.dut, read_scenario, self.country_code) @@ -270,10 +342,10 @@ class BtSarBaseTest(BaseTestClass): sar_df.loc[scenario, 'power_cap'] = self.get_current_power_cap( self.dut, start_time, type='BLE') - sar_df.loc[scenario, - 'ble_rssi'] = run_ble_throughput_and_read_rssi( - client_ad, server_ad, client_conn_id, - gatt_server, gatt_callback) + sar_df.loc[ + scenario, 'ble_rssi'] = run_ble_throughput_and_read_rssi( + client_ad, server_ad, client_conn_id, gatt_server, + gatt_callback) self.log.info('scenario:{}, power_cap:{}, ble_rssi:{}'.format( scenario, sar_df.loc[scenario, 'power_cap'], @@ -327,17 +399,15 @@ class BtSarBaseTest(BaseTestClass): self.otp = bt_utils.read_otp(self.dut) #OTP backoff - edr_otp = min(0, float(self.otp['EDR']['10']) / 4.0) - bdr_otp = min(0, float(self.otp['BDR']['10']) / 4.0) - ble_otp = min(0, float(self.otp['BLE']['10']) / 4.0) + edr_otp = min(0, float(self.otp['EDR']['10'])) + bdr_otp = min(0, float(self.otp['BR']['10'])) + ble_otp = min(0, float(self.otp['BLE']['10'])) # EDR TX Power for PL10 - edr_tx_power_pl10 = self.calibration_params['target_power']['EDR'][ - '10'] - edr_otp + edr_tx_power_pl10 = self.calibration_params['target_power']['EDR']['10'] - edr_otp # BDR TX Power for PL10 - bdr_tx_power_pl10 = self.calibration_params['target_power']['BDR'][ - '10'] - bdr_otp + bdr_tx_power_pl10 = self.calibration_params['target_power']['BDR']['10'] - bdr_otp # RSSI being measured is BDR offset = bdr_tx_power_pl10 - edr_tx_power_pl10 @@ -350,8 +420,8 @@ class BtSarBaseTest(BaseTestClass): # Adding a target power column if 'ble_rssi' in sar_df.columns: - sar_df['target_power'] = self.calibration_params[ - 'target_power']['BLE']['10'] - ble_otp + sar_df[ + 'target_power'] = self.calibration_params['target_power']['BLE']['10'] - ble_otp else: sar_df['target_power'] = sar_df['pwlv'].astype(str).map( self.calibration_params['target_power']['EDR']) - edr_otp @@ -364,11 +434,11 @@ class BtSarBaseTest(BaseTestClass): ]].min(axis=1) if hasattr(self, 'pl10_atten'): - sar_df['measured_tx_power'] = sar_df['slave_rssi'] + sar_df[ - 'pathloss'] + self.pl10_atten - offset + sar_df[ + 'measured_tx_power'] = sar_df['slave_rssi'] + sar_df['pathloss'] + self.pl10_atten - offset else: - sar_df['measured_tx_power'] = sar_df['ble_rssi'] + sar_df[ - 'pathloss'] + FIXED_ATTENUATION + sar_df[ + 'measured_tx_power'] = sar_df['ble_rssi'] + sar_df['pathloss'] + FIXED_ATTENUATION else: @@ -384,11 +454,11 @@ class BtSarBaseTest(BaseTestClass): sar_df[ 'expected_tx_power'] = sar_df['ftm_power'] - sar_df['backoff'] - sar_df['measured_tx_power'] = sar_df['slave_rssi'] + sar_df[ - 'pathloss'] + self.pl10_atten + sar_df[ + 'measured_tx_power'] = sar_df['slave_rssi'] + sar_df['pathloss'] + self.pl10_atten - sar_df['delta'] = sar_df['expected_tx_power'] - sar_df[ - 'measured_tx_power'] + sar_df[ + 'delta'] = sar_df['expected_tx_power'] - sar_df['measured_tx_power'] self.log.info('Sweep results processed') @@ -407,21 +477,28 @@ class BtSarBaseTest(BaseTestClass): Args: sar_df: processed BT SAR table """ + if self.sar_version_2: + breach_error_result = ( + sar_df['expected_tx_power'] + self.sar_margin[type] > + sar_df['measured_tx_power']).all() + if not breach_error_result: + asserts.fail('Measured TX power exceeds expected') - # checks for errors at particular points in the sweep - max_error_result = abs( - sar_df['delta']) > self.max_error_threshold[type] - if False in max_error_result: - asserts.fail('Maximum Error Threshold Exceeded') + else: + # checks for errors at particular points in the sweep + max_error_result = abs( + sar_df['delta']) > self.max_error_threshold[type] + if max_error_result: + asserts.fail('Maximum Error Threshold Exceeded') - # checks for error accumulation across the sweep - if sar_df['delta'].sum() > self.agg_error_threshold[type]: - asserts.fail( - 'Aggregate Error Threshold Exceeded. Error: {} Threshold: {}'. - format(sar_df['delta'].sum(), self.agg_error_threshold)) + # checks for error accumulation across the sweep + if sar_df['delta'].sum() > self.agg_error_threshold[type]: + asserts.fail( + 'Aggregate Error Threshold Exceeded. Error: {} Threshold: {}'. + format(sar_df['delta'].sum(), self.agg_error_threshold)) - else: - asserts.explicit_pass('Measured and Expected Power Values in line') + self.sar_test_result.metric_value = 1 + asserts.explicit_pass('Measured and Expected Power Values in line') def set_sar_state(self, ad, signal_dict, country_code='us'): """Sets the SAR state corresponding to the BT SAR signal. @@ -453,16 +530,15 @@ class BtSarBaseTest(BaseTestClass): } if 'BTHotspot' in signal_dict.keys(): - device_state_dict[('BT Tethering', + device_state_dict[('Bluetooth tethering', 'bt_tethering')] = signal_dict['BTHotspot'] enforced_state = {} sar_state_command = FORCE_SAR_ADB_COMMAND for key in device_state_dict: enforced_state[key[0]] = device_state_dict[key] - sar_state_command = '{} --ei {} {}'.format(sar_state_command, - key[1], - device_state_dict[key]) + sar_state_command = '{} --ei {} {}'.format( + sar_state_command, key[1], device_state_dict[key]) if self.sar_version_2: sar_state_command = '{} --es country_iso "{}"'.format( sar_state_command, country_code.lower()) @@ -491,7 +567,7 @@ class BtSarBaseTest(BaseTestClass): stat: the desired BT stat. """ # Waiting for logcat to update - time.sleep(1) + time.sleep(SLEEP_DURATION) bt_adb_log = ad.adb.logcat('-b all -t %s' % begin_time) for line in bt_adb_log.splitlines(): if re.findall(regex, line): @@ -516,7 +592,7 @@ class BtSarBaseTest(BaseTestClass): def get_country_code(self, ad, begin_time): """Returns the enforced regulatory domain since begin_time - Returns the enforced regulatory domain since begin_time by parsing logcat. + Returns enforced regulatory domain since begin_time by parsing logcat. Function should follow a function call to set a country code Args: @@ -584,14 +660,14 @@ class BtSarBaseTest(BaseTestClass): """ device_state_regex = 'updateDeviceState: DeviceState: ([\s*\S+\s]+)' - time.sleep(2) + time.sleep(SLEEP_DURATION) device_state = self.parse_bt_logs(ad, begin_time, device_state_regex) if device_state: return device_state raise ValueError("Couldn't fetch device state") - def read_sar_table(self, ad): + def read_sar_table(self, ad, output_path=''): """Extracts the BT SAR table from the phone. Extracts the BT SAR table from the phone into the android device @@ -599,17 +675,19 @@ class BtSarBaseTest(BaseTestClass): Args: ad: android_device object. - + output_path: path to custom sar table Returns: df : BT SAR table (as pandas DataFrame). """ - output_path = os.path.join(ad.device_log_path, self.sar_file_name) - ad.adb.pull('{} {}'.format(self.sar_file_path, output_path)) - df = pd.read_csv(os.path.join(ad.device_log_path, self.sar_file_name)) + if not output_path: + output_path = os.path.join(ad.device_log_path, self.sar_file_name) + ad.adb.pull('{} {}'.format(self.sar_file_path, output_path)) + + df = pd.read_csv(output_path) self.log.info('BT SAR table read from the phone') return df - def push_table(self, ad, src_path): + def push_table(self, ad, src_path, dest_path=''): """Pushes a BT SAR table to the phone. Pushes a BT SAR table to the android device and reboots the device. @@ -624,10 +702,14 @@ class BtSarBaseTest(BaseTestClass): job.run('cp {} {}'.format(src_path, ad.device_log_path)) #Pushing the file provided in the config - ad.push_system_file(src_path, self.sar_file_path) + if dest_path: + ad.push_system_file(src_path, dest_path) + else: + ad.push_system_file(src_path, self.sar_file_path) self.log.info('BT SAR table pushed') ad.reboot() - self.bt_sar_df = self.read_sar_table(self.dut) + + self.bt_sar_df = self.read_sar_table(self.dut, src_path) def set_PL10_atten_level(self, ad): """Finds the attenuation level at which the phone is at PL10 @@ -646,11 +728,11 @@ class BtSarBaseTest(BaseTestClass): for atten in range(self.atten_min, self.atten_max, BT_SAR_ATTEN_STEP): self.attenuator.set_atten(atten) # Sleep required for BQR to reflect the change in parameters - time.sleep(2) + time.sleep(SLEEP_DURATION) metrics = bt_utils.get_bt_metric(ad) if metrics['pwlv'][ad.serial] == 10: - self.log.info('PL10 located at {}'.format(atten + - BT_SAR_ATTEN_STEP)) + self.log.info( + 'PL10 located at {}'.format(atten + BT_SAR_ATTEN_STEP)) return atten + BT_SAR_ATTEN_STEP self.log.warn( diff --git a/acts/framework/acts/test_utils/bt/bt_test_utils.py b/acts/framework/acts/test_utils/bt/bt_test_utils.py index 7acf6a559c..a7e51bd076 100644 --- a/acts/framework/acts/test_utils/bt/bt_test_utils.py +++ b/acts/framework/acts/test_utils/bt/bt_test_utils.py @@ -229,14 +229,21 @@ def connect_phone_to_headset(android, # If already connected, skip pair and connect attempt. while not connected and (time.time() - start_time < timeout): bonded_info = android.droid.bluetoothGetBondedDevices() + connected_info = android.droid.bluetoothGetConnectedDevices() if headset.mac_address not in [ info["address"] for info in bonded_info ]: # Use SL4A to pair and connect with headset. headset.enter_pairing_mode() android.droid.bluetoothDiscoverAndBond(headset_mac_address) - else: # Device is bonded but not connected + elif headset.mac_address not in [ + info["address"] for info in connected_info + ]: + #Device is bonded but not connected android.droid.bluetoothConnectBonded(headset_mac_address) + else: + #Headset is connected, but A2DP profile is not + android.droid.bluetoothA2dpConnect(headset_mac_address) log.info('Waiting for connection...') time.sleep(connection_check_period) # Check for connection. @@ -244,7 +251,6 @@ def connect_phone_to_headset(android, log.info('Devices connected after pair attempt: %s' % connected) return connected - def connect_pri_to_sec(pri_ad, sec_ad, profiles_set, attempts=2): """Connects pri droid to secondary droid. @@ -676,7 +682,7 @@ def read_otp(ad): ad.adb.shell('svc bluetooth enable') time.sleep(2) otp_dict = { - "BDR": { + "BR": { "10": 0, "9": 0, "8": 0 @@ -693,7 +699,7 @@ def read_otp(ad): } } - otp_regex = '\s+\[\s+PL10:([-]*\d+)\s+PL9:([-]*\d+)*\s+PL8:([-]*\d+)\s+\]' + otp_regex = '\s+\[\s+PL10:\s+(\d+)\s+PL9:\s+(\d+)*\s+PL8:\s+(\d+)\s+\]' for key in otp_dict: bank_list = re.findall("{}{}".format(key, otp_regex), otp_output) @@ -701,7 +707,6 @@ def read_otp(ad): if ('0', '0', '0') != bank_tuple: [otp_dict[key]["10"], otp_dict[key]["9"], otp_dict[key]["8"]] = bank_tuple - return otp_dict @@ -723,8 +728,12 @@ def get_bt_metric(ad_list, duration=1, tag="bt_metric", processed=True): """ # Defining bqr quantitites and their regex to extract - regex_dict = {"pwlv": "PwLv:\s(\S+)", "rssi": "RSSI:\s[-](\d+)"} - metrics_dict = {"rssi": {}, "pwlv": {}} + regex_dict = { + "vsp_txpl": "VSP_TxPL:\s(\S+)", + "pwlv": "PwLv:\s(\S+)", + "rssi": "RSSI:\s[-](\d+)" + } + metrics_dict = {"rssi": {}, "pwlv": {}, "vsp_txpl": {}} # Converting a single android device object to list if not isinstance(ad_list, list): @@ -741,7 +750,7 @@ def get_bt_metric(ad_list, duration=1, tag="bt_metric", processed=True): for ad in ad_list: bt_rssi_log = ad.cat_adb_log(tag, begin_time, end_time) - bqr_tag = "Monitoring , Handle:" + bqr_tag = "Handle:" # Extracting supporting bqr quantities for metric, regex in regex_dict.items(): @@ -754,6 +763,11 @@ def get_bt_metric(ad_list, duration=1, tag="bt_metric", processed=True): bqr_metric.append(m) metrics_dict[metric][ad.serial] = bqr_metric + # Ensures back-compatibility for vsp_txpl enabled DUTs + if metrics_dict["vsp_txpl"][ad.serial]: + metrics_dict["pwlv"][ad.serial] = metrics_dict["vsp_txpl"][ + ad.serial] + # Formatting the raw data metrics_dict["rssi"][ad.serial] = [ (-1) * int(x) for x in metrics_dict["rssi"][ad.serial] @@ -769,8 +783,9 @@ def get_bt_metric(ad_list, duration=1, tag="bt_metric", processed=True): sum(metrics_dict["rssi"][ad.serial]) / len(metrics_dict["rssi"][ad.serial]), 2) # Returns last noted value for power level - metrics_dict["pwlv"][ad.serial] = metrics_dict["pwlv"][ - ad.serial][-1] + metrics_dict["pwlv"][ad.serial] = float( + sum(metrics_dict["pwlv"][ad.serial]) / + len(metrics_dict["pwlv"][ad.serial])) return metrics_dict @@ -797,9 +812,9 @@ def get_bt_rssi(ad, duration=1, processed=True): def enable_bqr( - ad_list, - bqr_interval=10, - bqr_event_mask=15, + ad_list, + bqr_interval=10, + bqr_event_mask=15, ): """Sets up BQR reporting. diff --git a/acts/framework/acts/test_utils/gnss/gnss_test_utils.py b/acts/framework/acts/test_utils/gnss/gnss_test_utils.py index cca5417bee..367bb9907c 100644 --- a/acts/framework/acts/test_utils/gnss/gnss_test_utils.py +++ b/acts/framework/acts/test_utils/gnss/gnss_test_utils.py @@ -33,6 +33,8 @@ from acts.controllers.android_device import DEFAULT_QXDM_LOG_PATH from acts.controllers.android_device import SL4A_APK_NAME from acts.test_utils.wifi import wifi_test_utils as wutils from acts.test_utils.tel import tel_test_utils as tutils +from acts.test_utils.instrumentation.device.command.instrumentation_command_builder import InstrumentationCommandBuilder +from acts.test_utils.instrumentation.device.command.instrumentation_command_builder import InstrumentationTestCommandBuilder from acts.utils import get_current_epoch_time from acts.utils import epoch_to_human_time @@ -599,25 +601,35 @@ def clear_aiding_data_by_gtw_gpstool(ad): time.sleep(10) -def start_gnss_by_gtw_gpstool(ad, state, type="gnss", bgdisplay=False): +def start_gnss_by_gtw_gpstool(ad, + state, + type="gnss", + bgdisplay=False, + freq=0, + lowpower=False, + meas=False): """Start or stop GNSS on GTW_GPSTool. Args: ad: An AndroidDevice object. state: True to start GNSS. False to Stop GNSS. type: Different API for location fix. Use gnss/flp/nmea - bgdisplay: true to run GTW when Display off. - false to not run GTW when Display off. + bgdisplay: true to run GTW when Display off. false to not run GTW when + Display off. + freq: An integer to set location update frequency. + meas: A Boolean to set GNSS measurement registeration. + lowpower: A boolean to set GNSS LowPowerMode. """ - if state and not bgdisplay: - ad.adb.shell("am start -S -n com.android.gpstool/.GPSTool " - "--es mode gps --es type %s" % type) - elif state and bgdisplay: - ad.adb.shell("am start -S -n com.android.gpstool/.GPSTool --es mode " - "gps --es type {} --ez BG {}".format(type, bgdisplay)) + cmd = "am start -S -n com.android.gpstool/.GPSTool --es mode gps" if not state: ad.log.info("Stop %s on GTW_GPSTool." % type) - ad.adb.shell("am broadcast -a com.android.gpstool.stop_gps_action") + cmd = "am broadcast -a com.android.gpstool.stop_gps_action" + else: + options = ("--es type {} --ei freq {} --ez BG {} --ez meas {} --ez " + "lowpower {}").format(type, freq, bgdisplay, meas, lowpower) + cmd = cmd + " " + options + + ad.adb.shell(cmd) time.sleep(3) @@ -638,6 +650,9 @@ def process_gnss_by_gtw_gpstool(ad, criteria, type="gnss", clear_data=True): """ retries = 3 for i in range(retries): + if not ad.is_adb_logcat_on: + ad.start_adb_logcat() + check_adblog_functionality(ad) check_location_runtime_permissions( ad, GNSSTOOL_PACKAGE_NAME, GNSSTOOL_PERMISSIONS) begin_time = get_current_epoch_time() @@ -660,8 +675,6 @@ def process_gnss_by_gtw_gpstool(ad, criteria, type="gnss", clear_data=True): "within %d seconds criteria." % (type.upper(), criteria)) time.sleep(1) - if not ad.is_adb_logcat_on: - ad.start_adb_logcat() check_currrent_focus_app(ad) start_gnss_by_gtw_gpstool(ad, False, type) raise signals.TestFailure("Fail to get %s location fixed within %d " @@ -827,13 +840,11 @@ def process_ttff_by_gtw_gpstool(ad, begin_time, true_position, type="gnss"): "message in logcat. Abort test.") if not ad.is_adb_logcat_on: ad.start_adb_logcat() - logcat_results = ad.search_logcat("write TTFF log", begin_time) + logcat_results = ad.search_logcat("write TTFF log", ttff_loop_time) if logcat_results: + ttff_loop_time = get_current_epoch_time() ttff_log = logcat_results[-1]["log_message"].split() ttff_loop = int(ttff_log[8].split(":")[-1]) - if ttff_loop in ttff_data.keys(): - continue - ttff_loop_time = get_current_epoch_time() ttff_sec = float(ttff_log[11]) if ttff_sec != 0.0: ttff_ant_cn = float(ttff_log[18].strip("]")) @@ -897,6 +908,8 @@ def process_ttff_by_gtw_gpstool(ad, begin_time, true_position, type="gnss"): begin_time) if crash_result: raise signals.TestError("GPSTool crashed. Abort test.") + # wait 10 seconds to avoid logs not writing into logcat yet + time.sleep(10) return ttff_data @@ -1383,3 +1396,62 @@ def check_ttff_pe(ad, ttff_data, ttff_mode, pecriteria): raise signals.TestFailure("GTW_GPSTool didn't process TTFF properly.") ad.log.info("All TTFF %s are within test criteria %f meters.", (ttff_mode, pecriteria)) + + +def check_adblog_functionality(ad): + """Restart adb logcat if system can't write logs into file after checking + adblog file size. + + Args: + ad: An AndroidDevice object. + """ + logcat_path = os.path.join(ad.device_log_path, "adblog_%s_debug.txt" % + ad.serial) + if not os.path.exists(logcat_path): + raise signals.TestError("Logcat file %s does not exist." % logcat_path) + original_log_size = os.path.getsize(logcat_path) + ad.log.debug("Original adblog size is %d" % original_log_size) + time.sleep(.5) + current_log_size = os.path.getsize(logcat_path) + ad.log.debug("Current adblog size is %d" % current_log_size) + if current_log_size == original_log_size: + ad.log.warn("System can't write logs into file. Restart adb " + "logcat process now.") + ad.stop_adb_logcat() + ad.start_adb_logcat() + +def build_instrumentation_call(package, + runner, + test_methods=None, + options=None): + """Build an instrumentation call for the tests + + Args: + package: A string to identify test package. + runner: A string to identify test runner. + test_methods: A dictionary contains {class_name, test_method}. + options: A dictionary constaion {key, value} param for test. + + Returns: + An instrumentation call command. + """ + if test_methods is None: + test_methods = {} + cmd_builder = InstrumentationCommandBuilder() + else: + cmd_builder = InstrumentationTestCommandBuilder() + + if options is None: + options = {} + + cmd_builder.set_manifest_package(package) + cmd_builder.set_runner(runner) + cmd_builder.add_flag("-w") + + for class_name, test_method in test_methods.items(): + cmd_builder.add_test_method(class_name, test_method) + + for option_key, option_value in options.items(): + cmd_builder.add_key_value_param(option_key, option_value) + + return cmd_builder.build() diff --git a/acts/framework/acts/test_utils/gnss/gnss_testlog_utils.py b/acts/framework/acts/test_utils/gnss/gnss_testlog_utils.py index 0792da45c2..54d47d789e 100644 --- a/acts/framework/acts/test_utils/gnss/gnss_testlog_utils.py +++ b/acts/framework/acts/test_utils/gnss/gnss_testlog_utils.py @@ -25,50 +25,84 @@ from acts import logger # GPS API Log Reading Config CONFIG_GPSAPILOG = { 'phone_time': - r'(?P<date>\d+\/\d+\/\d+)\s+(?P<time>\d+:\d+:\d+)\s+' + r'^(?P<date>\d+\/\d+\/\d+)\s+(?P<time>\d+:\d+:\d+)\s+' r'Read:\s+(?P<logsize>\d+)\s+bytes', 'SpaceVehicle': - r'Fix:\s+(?P<Fix>\w+)\s+Type:\s+(?P<Type>\w+)\s+' + r'^Fix:\s+(?P<Fix>\w+)\s+Type:\s+(?P<Type>\w+)\s+' r'SV:\s+(?P<SV>\d+)\s+C\/No:\s+(?P<CNo>\d+\.\d+)\s+' r'Elevation:\s+(?P<Elevation>\d+\.\d+)\s+' r'Azimuth:\s+(?P<Azimuth>\d+\.\d+)\s+' r'Signal:\s+(?P<Signal>\w+)\s+' r'Frequency:\s+(?P<Frequency>\d+\.\d+)\s+' r'EPH:\s+(?P<EPH>\w+)\s+ALM:\s+(?P<ALM>\w+)', + 'SpaceVehicle_wBB': + r'^Fix:\s+(?P<Fix>\w+)\s+Type:\s+(?P<Type>\w+)\s+' + r'SV:\s+(?P<SV>\d+)\s+C\/No:\s+(?P<AntCNo>\d+\.\d+),\s+' + r'(?P<BbCNo>\d+\.\d+)\s+' + r'Elevation:\s+(?P<Elevation>\d+\.\d+)\s+' + r'Azimuth:\s+(?P<Azimuth>\d+\.\d+)\s+' + r'Signal:\s+(?P<Signal>\w+)\s+' + r'Frequency:\s+(?P<Frequency>\d+\.\d+)\s+' + r'EPH:\s+(?P<EPH>\w+)\s+ALM:\s+(?P<ALM>\w+)', 'HistoryAvgTop4CNo': - r'History\s+Avg\s+Top4\s+:\s+(?P<HistoryAvgTop4CNo>\d+\.\d+)', + r'^History\s+Avg\s+Top4\s+:\s+(?P<HistoryAvgTop4CNo>\d+\.\d+)', 'CurrentAvgTop4CNo': - r'Current\s+Avg\s+Top4\s+:\s+(?P<CurrentAvgTop4CNo>\d+\.\d+)', + r'^Current\s+Avg\s+Top4\s+:\s+(?P<CurrentAvgTop4CNo>\d+\.\d+)', 'HistoryAvgCNo': - r'History\s+Avg\s+:\s+(?P<HistoryAvgCNo>\d+\.\d+)', + r'^History\s+Avg\s+:\s+(?P<HistoryAvgCNo>\d+\.\d+)', 'CurrentAvgCNo': - r'Current\s+Avg\s+:\s+(?P<CurrentAvgCNo>\d+\.\d+)', + r'^Current\s+Avg\s+:\s+(?P<CurrentAvgCNo>\d+\.\d+)', + 'AntennaHistoryAvgTop4CNo': + r'^Antenna_History\s+Avg\s+Top4\s+:\s+(?P<AntennaHistoryAvgTop4CNo>\d+\.\d+)', + 'AntennaCurrentAvgTop4CNo': + r'^Antenna_Current\s+Avg\s+Top4\s+:\s+(?P<AntennaCurrentAvgTop4CNo>\d+\.\d+)', + 'AntennaHistoryAvgCNo': + r'^Antenna_History\s+Avg\s+:\s+(?P<AntennaHistoryAvgCNo>\d+\.\d+)', + 'AntennaCurrentAvgCNo': + r'^Antenna_Current\s+Avg\s+:\s+(?P<AntennaCurrentAvgCNo>\d+\.\d+)', + 'BasebandHistoryAvgTop4CNo': + r'^Baseband_History\s+Avg\s+Top4\s+:\s+(?P<BasebandHistoryAvgTop4CNo>\d+\.\d+)', + 'BasebandCurrentAvgTop4CNo': + r'^Baseband_Current\s+Avg\s+Top4\s+:\s+(?P<BasebandCurrentAvgTop4CNo>\d+\.\d+)', + 'BasebandHistoryAvgCNo': + r'^Baseband_History\s+Avg\s+:\s+(?P<BasebandHistoryAvgCNo>\d+\.\d+)', + 'BasebandCurrentAvgCNo': + r'^Baseband_Current\s+Avg\s+:\s+(?P<BasebandCurrentAvgCNo>\d+\.\d+)', 'L5inFix': - r'L5\s+used\s+in\s+fix:\s+(?P<L5inFix>\w+)', + r'^L5\s+used\s+in\s+fix:\s+(?P<L5inFix>\w+)', 'L5EngagingRate': - r'L5\s+engaging\s+rate:\s+(?P<L5EngagingRate>\d+.\d+)%', + r'^L5\s+engaging\s+rate:\s+(?P<L5EngagingRate>\d+.\d+)%', 'Provider': - r'Provider:\s+(?P<Provider>\w+)', + r'^Provider:\s+(?P<Provider>\w+)', 'Latitude': - r'Latitude:\s+(?P<Latitude>-?\d+.\d+)', + r'^Latitude:\s+(?P<Latitude>-?\d+.\d+)', 'Longitude': - r'Longitude:\s+(?P<Longitude>-?\d+.\d+)', + r'^Longitude:\s+(?P<Longitude>-?\d+.\d+)', 'Altitude': - r'Altitude:\s+(?P<Altitude>-?\d+.\d+)', + r'^Altitude:\s+(?P<Altitude>-?\d+.\d+)', 'GNSSTime': - r'Time:\s+(?P<Date>\d+\/\d+\/\d+)\s+' + r'^Time:\s+(?P<Date>\d+\/\d+\/\d+)\s+' r'(?P<Time>\d+:\d+:\d+)', 'Speed': - r'Speed:\s+(?P<Speed>\d+.\d+)', + r'^Speed:\s+(?P<Speed>\d+.\d+)', 'Bearing': - r'Bearing:\s+(?P<Bearing>\d+.\d+)', + r'^Bearing:\s+(?P<Bearing>\d+.\d+)', } # Space Vehicle Statistics Dataframe List +# Handle the pre GPSTool 2.12.24 case LIST_SVSTAT = [ 'HistoryAvgTop4CNo', 'CurrentAvgTop4CNo', 'HistoryAvgCNo', 'CurrentAvgCNo', 'L5inFix', 'L5EngagingRate' ] +# Handle the post GPSTool 2.12.24 case with baseband CNo +LIST_SVSTAT_WBB = [ + 'AntennaHistoryAvgTop4CNo', 'AntennaCurrentAvgTop4CNo', + 'AntennaHistoryAvgCNo', 'AntennaCurrentAvgCNo', + 'BasebandHistoryAvgTop4CNo', 'BasebandCurrentAvgTop4CNo', + 'BasebandHistoryAvgCNo', 'BasebandCurrentAvgCNo', 'L5inFix', + 'L5EngagingRate' +] # Location Fix Info Dataframe List LIST_LOCINFO = [ @@ -83,11 +117,12 @@ CONFIG_GPSTTFFLOG = { r'(?P<start_datetime>\d+\/\d+\/\d+-\d+:\d+:\d+.\d+)\s+' r'(?P<stop_datetime>\d+\/\d+\/\d+-\d+:\d+:\d+.\d+)\s+' r'(?P<ttff>\d+.\d+)\s+' - r'\[Avg Top4 : (?P<avg_top4_cn0>\d+.\d+)\]\s' - r'\[Avg : (?P<avg_cn0>\d+.\d+)\]\s+\[(?P<fix_type>\d+\w+ fix)\]\s+' + r'\[Antenna_Avg Top4 : (?P<ant_avg_top4_cn0>\d+.\d+)\]\s' + r'\[Antenna_Avg : (?P<ant_avg_cn0>\d+.\d+)\]\s' + r'\[Baseband_Avg Top4 : (?P<bb_avg_top4_cn0>\d+.\d+)\]\s' + r'\[Baseband_Avg : (?P<<bb_avg_cn0>\d+.\d+)\]\s+\[(?P<fix_type>\d+\w+ fix)\]\s+' r'\[Satellites used for fix : (?P<satnum_for_fix>\d+)\]' } - LOGPARSE_UTIL_LOGGER = logger.create_logger() @@ -150,7 +185,7 @@ def parse_log_to_df(filename, configs, index_rownum=True): if index_rownum and not parsed_data[key].empty: parsed_data[key].set_index('rownumber', inplace=True) elif parsed_data[key].empty: - LOGPARSE_UTIL_LOGGER.warning( + LOGPARSE_UTIL_LOGGER.debug( 'The parsed dataframe of "%s" is empty.', key) # Return parsed data list @@ -315,24 +350,43 @@ def parse_gpsapilog_to_df_v2(filename): # Add phone_time from timestamp dataframe by row number for key in parsed_data: - if key != 'phone_time': + if (key != 'phone_time') and (not parsed_data[key].empty): parsed_data[key] = pds.merge_asof(parsed_data[key], parsed_data['phone_time'], left_index=True, right_index=True) # Get space vehicle info dataframe - sv_info_df = parsed_data['SpaceVehicle'] + # Handle the pre GPSTool 2.12.24 case + if not parsed_data['SpaceVehicle'].empty: + sv_info_df = parsed_data['SpaceVehicle'] + + # Handle the post GPSTool 2.12.24 case with baseband CNo + elif not parsed_data['SpaceVehicle_wBB'].empty: + sv_info_df = parsed_data['SpaceVehicle_wBB'] # Get space vehicle statistics dataframe - # First merge all dataframe from LIST_SVSTAT[1:], - sv_stat_df = fts.reduce( - lambda item1, item2: pds.merge(item1, item2, on='phone_time'), - [parsed_data[key] for key in LIST_SVSTAT[1:]]) - # Then merge with LIST_SVSTAT[0] - sv_stat_df = pds.merge(sv_stat_df, - parsed_data[LIST_SVSTAT[0]], - on='phone_time') + # Handle the pre GPSTool 2.12.24 case + if not parsed_data['HistoryAvgTop4CNo'].empty: + # First merge all dataframe from LIST_SVSTAT[1:], + sv_stat_df = fts.reduce( + lambda item1, item2: pds.merge(item1, item2, on='phone_time'), + [parsed_data[key] for key in LIST_SVSTAT[1:]]) + # Then merge with LIST_SVSTAT[0] + sv_stat_df = pds.merge(sv_stat_df, + parsed_data[LIST_SVSTAT[0]], + on='phone_time') + + # Handle the post GPSTool 2.12.24 case with baseband CNo + elif not parsed_data['AntennaHistoryAvgTop4CNo'].empty: + # First merge all dataframe from LIST_SVSTAT[1:], + sv_stat_df = fts.reduce( + lambda item1, item2: pds.merge(item1, item2, on='phone_time'), + [parsed_data[key] for key in LIST_SVSTAT_WBB[1:]]) + # Then merge with LIST_SVSTAT[0] + sv_stat_df = pds.merge(sv_stat_df, + parsed_data[LIST_SVSTAT_WBB[0]], + on='phone_time') # Get location fix information dataframe # First merge all dataframe from LIST_LOCINFO[1:], @@ -353,17 +407,53 @@ def parse_gpsapilog_to_df_v2(filename): timestamp_df['logsize'] = timestamp_df['logsize'].astype(int) sv_info_df['SV'] = sv_info_df['SV'].astype(int) - sv_info_df['CNo'] = sv_info_df['CNo'].astype(float) sv_info_df['Elevation'] = sv_info_df['Elevation'].astype(float) sv_info_df['Azimuth'] = sv_info_df['Azimuth'].astype(float) sv_info_df['Frequency'] = sv_info_df['Frequency'].astype(float) - sv_stat_df['CurrentAvgTop4CNo'] = sv_stat_df['CurrentAvgTop4CNo'].astype( - float) - sv_stat_df['CurrentAvgCNo'] = sv_stat_df['CurrentAvgCNo'].astype(float) - sv_stat_df['HistoryAvgTop4CNo'] = sv_stat_df['HistoryAvgTop4CNo'].astype( - float) - sv_stat_df['HistoryAvgCNo'] = sv_stat_df['HistoryAvgCNo'].astype(float) + if 'CNo' in list(sv_info_df.columns): + sv_info_df['CNo'] = sv_info_df['CNo'].astype(float) + sv_info_df['AntCNo'] = sv_info_df['CNo'] + elif 'AntCNo' in list(sv_info_df.columns): + sv_info_df['AntCNo'] = sv_info_df['AntCNo'].astype(float) + sv_info_df['BbCNo'] = sv_info_df['BbCNo'].astype(float) + + if 'CurrentAvgTop4CNo' in list(sv_stat_df.columns): + sv_stat_df['CurrentAvgTop4CNo'] = sv_stat_df[ + 'CurrentAvgTop4CNo'].astype(float) + sv_stat_df['CurrentAvgCNo'] = sv_stat_df['CurrentAvgCNo'].astype(float) + sv_stat_df['HistoryAvgTop4CNo'] = sv_stat_df[ + 'HistoryAvgTop4CNo'].astype(float) + sv_stat_df['HistoryAvgCNo'] = sv_stat_df['HistoryAvgCNo'].astype(float) + sv_stat_df['AntennaCurrentAvgTop4CNo'] = sv_stat_df[ + 'CurrentAvgTop4CNo'] + sv_stat_df['AntennaCurrentAvgCNo'] = sv_stat_df['CurrentAvgCNo'] + sv_stat_df['AntennaHistoryAvgTop4CNo'] = sv_stat_df[ + 'HistoryAvgTop4CNo'] + sv_stat_df['AntennaHistoryAvgCNo'] = sv_stat_df['HistoryAvgCNo'] + sv_stat_df['BasebandCurrentAvgTop4CNo'] = npy.nan + sv_stat_df['BasebandCurrentAvgCNo'] = npy.nan + sv_stat_df['BasebandHistoryAvgTop4CNo'] = npy.nan + sv_stat_df['BasebandHistoryAvgCNo'] = npy.nan + + elif 'AntennaCurrentAvgTop4CNo' in list(sv_stat_df.columns): + sv_stat_df['AntennaCurrentAvgTop4CNo'] = sv_stat_df[ + 'AntennaCurrentAvgTop4CNo'].astype(float) + sv_stat_df['AntennaCurrentAvgCNo'] = sv_stat_df[ + 'AntennaCurrentAvgCNo'].astype(float) + sv_stat_df['AntennaHistoryAvgTop4CNo'] = sv_stat_df[ + 'AntennaHistoryAvgTop4CNo'].astype(float) + sv_stat_df['AntennaHistoryAvgCNo'] = sv_stat_df[ + 'AntennaHistoryAvgCNo'].astype(float) + sv_stat_df['BasebandCurrentAvgTop4CNo'] = sv_stat_df[ + 'BasebandCurrentAvgTop4CNo'].astype(float) + sv_stat_df['BasebandCurrentAvgCNo'] = sv_stat_df[ + 'BasebandCurrentAvgCNo'].astype(float) + sv_stat_df['BasebandHistoryAvgTop4CNo'] = sv_stat_df[ + 'BasebandHistoryAvgTop4CNo'].astype(float) + sv_stat_df['BasebandHistoryAvgCNo'] = sv_stat_df[ + 'BasebandHistoryAvgCNo'].astype(float) + sv_stat_df['L5EngagingRate'] = sv_stat_df['L5EngagingRate'].astype(float) loc_info_df['Latitude'] = loc_info_df['Latitude'].astype(float) diff --git a/acts/framework/acts/test_utils/net/connectivity_const.py b/acts/framework/acts/test_utils/net/connectivity_const.py index 37b8c80255..60d4f67e7c 100644 --- a/acts/framework/acts/test_utils/net/connectivity_const.py +++ b/acts/framework/acts/test_utils/net/connectivity_const.py @@ -66,6 +66,8 @@ MULTIPATH_PREFERENCE_PERFORMANCE = 1 << 2 # Private DNS constants DNS_GOOGLE = "dns.google" +DNS_QUAD9 = "dns.quad9.net" +DNS_CLOUDFLARE = "1dot1dot1dot1.cloudflare-dns.com" PRIVATE_DNS_MODE_OFF = "off" PRIVATE_DNS_MODE_OPPORTUNISTIC = "opportunistic" PRIVATE_DNS_MODE_STRICT = "hostname" @@ -121,6 +123,9 @@ class VpnProfileType(enum.Enum): IPSEC_XAUTH_PSK = 3 IPSEC_XAUTH_RSA = 4 IPSEC_HYBRID_RSA = 5 + IKEV2_IPSEC_USER_PASS = 6 + IKEV2_IPSEC_PSK = 7 + IKEV2_IPSEC_RSA = 8 # Constants for config file @@ -138,3 +143,6 @@ class VpnReqParams(object): cert_password = "cert_password" pptp_mppe = "pptp_mppe" ipsec_server_type = "ipsec_server_type" + wifi_network = "wifi_network" + vpn_identity = "vpn_identity" + vpn_server_hostname = "vpn_server_hostname" diff --git a/acts/framework/acts/test_utils/net/connectivity_test_utils.py b/acts/framework/acts/test_utils/net/connectivity_test_utils.py index 4b7668c315..153630ff7f 100644 --- a/acts/framework/acts/test_utils/net/connectivity_test_utils.py +++ b/acts/framework/acts/test_utils/net/connectivity_test_utils.py @@ -15,53 +15,94 @@ from acts import asserts from acts.test_utils.net import connectivity_const as cconst +from queue import Empty -def start_natt_keepalive(ad, src_ip, src_port, dst_ip, interval = 10): - """ Start NAT-T keep alive on dut """ +def _listen_for_keepalive_event(ad, key, msg, ka_event): + """Listen for keepalive event and return status - ad.log.info("Starting NATT Keepalive") - status = None - - key = ad.droid.connectivityStartNattKeepalive( - interval, src_ip, src_port, dst_ip) - - ad.droid.connectivityNattKeepaliveStartListeningForEvent(key, "Started") + Args: + ad: DUT object + key: keepalive key + msg: Error message + event: Keepalive event type + """ + ad.droid.socketKeepaliveStartListeningForEvent(key, ka_event) try: - event = ad.ed.pop_event("PacketKeepaliveCallback") - status = event["data"]["packetKeepaliveEvent"] + event = ad.ed.pop_event("SocketKeepaliveCallback") + status = event["data"]["socketKeepaliveEvent"] == ka_event except Empty: - msg = "Failed to receive confirmation of starting natt keepalive" asserts.fail(msg) finally: - ad.droid.connectivityNattKeepaliveStopListeningForEvent( - key, "Started") + ad.droid.socketKeepaliveStopListeningForEvent(key, ka_event) + if ka_event != "Started": + ad.droid.removeSocketKeepaliveReceiverKey(key) + if status: + ad.log.info("'%s' keepalive event successful" % ka_event) + return status - if status != "Started": - ad.log.error("Received keepalive status: %s" % status) - ad.droid.connectivityRemovePacketKeepaliveReceiverKey(key) - return None - return key +def start_natt_socket_keepalive(ad, udp_encap, src_ip, dst_ip, interval = 10): + """Start NATT SocketKeepalive on DUT -def stop_natt_keepalive(ad, key): - """ Stop NAT-T keep alive on dut """ + Args: + ad: DUT object + udp_encap: udp_encap socket key + src_ip: IP addr of the client + dst_ip: IP addr of the keepalive server + interval: keepalive time interval + """ + ad.log.info("Starting Natt Socket Keepalive") + key = ad.droid.startNattSocketKeepalive(udp_encap, src_ip, dst_ip, interval) + msg = "Failed to receive confirmation of starting natt socket keeaplive" + status = _listen_for_keepalive_event(ad, key, msg, "Started") + return key if status else None - ad.log.info("Stopping NATT keepalive") - status = False - ad.droid.connectivityStopNattKeepalive(key) +def start_tcp_socket_keepalive(ad, socket, time_interval = 10): + """Start TCP socket keepalive on DUT - ad.droid.connectivityNattKeepaliveStartListeningForEvent(key, "Stopped") - try: - event = ad.ed.pop_event("PacketKeepaliveCallback") - status = event["data"]["packetKeepaliveEvent"] == "Stopped" - except Empty: - msg = "Failed to receive confirmation of stopping natt keepalive" - asserts.fail(msg) - finally: - ad.droid.connectivityNattKeepaliveStopListeningForEvent( - key, "Stopped") + Args: + ad: DUT object + socket: TCP socket key + time_interval: Keepalive time interval + """ + ad.log.info("Starting TCP Socket Keepalive") + key = ad.droid.startTcpSocketKeepalive(socket, time_interval) + msg = "Failed to receive confirmation of starting tcp socket keeaplive" + status = _listen_for_keepalive_event(ad, key, msg, "Started") + return key if status else None - ad.droid.connectivityRemovePacketKeepaliveReceiverKey(key) - return status +def socket_keepalive_error(ad, key): + """Verify Error callback + + Args: + ad: DUT object + key: Keepalive key + """ + ad.log.info("Verify Error callback on keepalive: %s" % key) + msg = "Failed to receive confirmation of Error callback" + return _listen_for_keepalive_event(ad, key, msg, "Error") + +def socket_keepalive_data_received(ad, key): + """Verify OnDataReceived callback + + Args: + ad: DUT object + key: Keepalive key + """ + ad.log.info("Verify OnDataReceived callback on keepalive: %s" % key) + msg = "Failed to receive confirmation of OnDataReceived callback" + return _listen_for_keepalive_event(ad, key, msg, "OnDataReceived") + +def stop_socket_keepalive(ad, key): + """Stop SocketKeepalive on DUT + + Args: + ad: DUT object + key: Keepalive key + """ + ad.log.info("Stopping Socket keepalive: %s" % key) + ad.droid.stopSocketKeepalive(key) + msg = "Failed to receive confirmation of stopping socket keepalive" + return _listen_for_keepalive_event(ad, key, msg, "Stopped") def set_private_dns(ad, dns_mode, hostname=None): """ Set private DNS mode on dut """ diff --git a/acts/framework/acts/test_utils/net/net_test_utils.py b/acts/framework/acts/test_utils/net/net_test_utils.py index db0f90078c..7e6efa5ce6 100644 --- a/acts/framework/acts/test_utils/net/net_test_utils.py +++ b/acts/framework/acts/test_utils/net/net_test_utils.py @@ -14,13 +14,16 @@ # See the License for the specific language governing permissions and # limitations under the License. import logging +import os -from acts.controllers import adb from acts import asserts +from acts import signals +from acts import utils +from acts.controllers import adb from acts.controllers.adb_lib.error import AdbError from acts.logger import epoch_to_log_line_timestamp -from acts.utils import get_current_epoch_time from acts.logger import normalize_log_line_timestamp +from acts.utils import get_current_epoch_time from acts.utils import start_standing_subprocess from acts.utils import stop_standing_subprocess from acts.test_utils.net import connectivity_const as cconst @@ -43,6 +46,9 @@ USB_CHARGE_MODE = "svc usb setFunctions" USB_TETHERING_MODE = "svc usb setFunctions rndis" DEVICE_IP_ADDRESS = "ip address" +GCE_SSH = "gcloud compute ssh " +GCE_SCP = "gcloud compute scp " + def verify_lte_data_and_tethering_supported(ad): """Verify if LTE data is enabled and tethering supported""" @@ -87,6 +93,7 @@ def verify_ping_to_vpn_ip(ad, vpn_ping_addr): """ ping_result = None pkt_loss = "100% packet loss" + logging.info("Pinging: %s" % vpn_ping_addr) try: ping_result = ad.adb.shell("ping -c 3 -W 2 %s" % vpn_ping_addr) except AdbError: @@ -166,6 +173,7 @@ def download_load_certs(ad, vpn_params, vpn_type, vpn_server_addr, vpn_params['client_pkcs_file_name']) local_file_path = os.path.join(log_path, local_cert_name) + logging.info("URL is: %s" % url) try: ret = urllib.request.urlopen(url) with open(local_file_path, "wb") as f: @@ -226,6 +234,50 @@ def generate_legacy_vpn_profile(ad, return vpn_profile +def generate_ikev2_vpn_profile(ad, vpn_params, vpn_type, server_addr, log_path): + """Generate VPN profile for IKEv2 VPN. + + Args: + ad: android device object. + vpn_params: vpn params from config file. + vpn_type: ikev2 vpn type. + server_addr: vpn server addr. + log_path: log path to download cert. + + Returns: + Vpn profile. + """ + vpn_profile = { + VPN_CONST.TYPE: vpn_type.value, + VPN_CONST.SERVER: server_addr, + } + + if vpn_type.name == "IKEV2_IPSEC_USER_PASS": + vpn_profile[VPN_CONST.USER] = vpn_params["vpn_username"] + vpn_profile[VPN_CONST.PWD] = vpn_params["vpn_password"] + vpn_profile[VPN_CONST.IPSEC_ID] = vpn_params["vpn_identity"] + cert_name = download_load_certs( + ad, vpn_params, vpn_type, vpn_params["server_addr"], + "IKEV2_IPSEC_USER_PASS", log_path) + vpn_profile[VPN_CONST.IPSEC_CA_CERT] = cert_name.split('.')[0] + ad.droid.installCertificate( + vpn_profile, cert_name, vpn_params['cert_password']) + elif vpn_type.name == "IKEV2_IPSEC_PSK": + vpn_profile[VPN_CONST.IPSEC_ID] = vpn_params["vpn_identity"] + vpn_profile[VPN_CONST.IPSEC_SECRET] = vpn_params["psk_secret"] + else: + vpn_profile[VPN_CONST.IPSEC_ID] = "%s@%s" % ( + vpn_params["vpn_identity"], server_addr) + logging.info("ID: %s@%s" % (vpn_params["vpn_identity"], server_addr)) + cert_name = download_load_certs( + ad, vpn_params, vpn_type, vpn_params["server_addr"], + "IKEV2_IPSEC_RSA", log_path) + vpn_profile[VPN_CONST.IPSEC_USER_CERT] = cert_name.split('.')[0] + vpn_profile[VPN_CONST.IPSEC_CA_CERT] = cert_name.split('.')[0] + ad.droid.installCertificate( + vpn_profile, cert_name, vpn_params['cert_password']) + + return vpn_profile def start_tcpdump(ad, test_name): """Start tcpdump on all interfaces @@ -289,6 +341,85 @@ def stop_tcpdump(ad, file_name = "tcpdump_%s_%s.pcap" % (ad.serial, test_name) return "%s/%s" % (log_path, file_name) +def start_tcpdump_gce_server(ad, test_name, dest_port, gce): + """ Start tcpdump on gce server + + Args: + ad: android device object + test_name: test case name + dest_port: port to collect tcpdump + gce: dictionary of gce instance + + Returns: + process id and pcap file path from gce server + """ + ad.log.info("Starting tcpdump on gce server") + + # pcap file name + fname = "/tmp/%s_%s_%s_%s" % \ + (test_name, ad.model, ad.serial, + time.strftime('%Y-%m-%d_%H-%M-%S', time.localtime(time.time()))) + + # start tcpdump + tcpdump_cmd = "sudo bash -c \'tcpdump -i %s -w %s.pcap port %s > \ + %s.txt 2>&1 & echo $!\'" % (gce["interface"], fname, dest_port, fname) + gcloud_ssh_cmd = "%s --project=%s --zone=%s %s@%s --command " % \ + (GCE_SSH, gce["project"], gce["zone"], gce["username"], gce["hostname"]) + gce_ssh_cmd = '%s "%s"' % (gcloud_ssh_cmd, tcpdump_cmd) + utils.exe_cmd(gce_ssh_cmd) + + # get process id + ps_cmd = '%s "ps aux | grep tcpdump | grep %s"' % (gcloud_ssh_cmd, fname) + tcpdump_pid = utils.exe_cmd(ps_cmd).decode("utf-8", "ignore").split() + if not tcpdump_pid: + raise signals.TestFailure("Failed to start tcpdump on gce server") + return tcpdump_pid[1], fname + +def stop_tcpdump_gce_server(ad, tcpdump_pid, fname, gce): + """ Stop and pull tcpdump file from gce server + + Args: + ad: android device object + tcpdump_pid: process id for tcpdump file + fname: tcpdump file path + gce: dictionary of gce instance + + Returns: + pcap file from gce server + """ + ad.log.info("Stop and pull pcap file from gce server") + + # stop tcpdump + tcpdump_cmd = "sudo kill %s" % tcpdump_pid + gcloud_ssh_cmd = "%s --project=%s --zone=%s %s@%s --command " % \ + (GCE_SSH, gce["project"], gce["zone"], gce["username"], gce["hostname"]) + gce_ssh_cmd = '%s "%s"' % (gcloud_ssh_cmd, tcpdump_cmd) + utils.exe_cmd(gce_ssh_cmd) + + # verify tcpdump is stopped + ps_cmd = '%s "ps aux | grep tcpdump"' % gcloud_ssh_cmd + res = utils.exe_cmd(ps_cmd).decode("utf-8", "ignore") + if tcpdump_pid in res.split(): + raise signals.TestFailure("Failed to stop tcpdump on gce server") + if not fname: + return None + + # pull pcap file + gcloud_scp_cmd = "%s --project=%s --zone=%s %s@%s:" % \ + (GCE_SCP, gce["project"], gce["zone"], gce["username"], gce["hostname"]) + pull_file = '%s%s.pcap %s/' % (gcloud_scp_cmd, fname, ad.device_log_path) + utils.exe_cmd(pull_file) + if not os.path.exists( + "%s/%s.pcap" % (ad.device_log_path, fname.split('/')[-1])): + raise signals.TestFailure("Failed to pull tcpdump from gce server") + + # delete pcaps + utils.exe_cmd('%s "sudo rm %s.*"' % (gcloud_ssh_cmd, fname)) + + # return pcap file + pcap_file = "%s/%s.pcap" % (ad.device_log_path, fname.split('/')[-1]) + return pcap_file + def is_ipaddress_ipv6(ip_address): """Verify if the given string is a valid IPv6 address. @@ -379,4 +510,3 @@ def wait_for_new_iface(old_ifaces): return new_ifaces.pop() time.sleep(1) asserts.fail("Timeout waiting for tethering interface on host") - diff --git a/acts/framework/acts/test_utils/net/socket_test_utils.py b/acts/framework/acts/test_utils/net/socket_test_utils.py index a8a05fc206..42e4537de3 100644 --- a/acts/framework/acts/test_utils/net/socket_test_utils.py +++ b/acts/framework/acts/test_utils/net/socket_test_utils.py @@ -258,6 +258,18 @@ def close_server_socket(ad, socket): status = ad.droid.closeTcpServerSocket(socket) asserts.assert_true(status, "Failed to socket") +def shutdown_socket(ad, socket): + """ Shutdown socket + + Args: + 1. ad - androidandroid device object + 2. socket - socket key + """ + fd = ad.droid.getFileDescriptorOfSocket(socket) + asserts.assert_true(fd, "Failed to get FileDescriptor key") + status = ad.droid.shutdownFileDescriptor(fd) + asserts.assert_true(status, "Failed to shutdown socket") + def send_recv_data_sockets(client, server, client_sock, server_sock): """ Send data over TCP socket from client to server. Verify that server received the data diff --git a/acts/framework/acts/test_utils/power/PowerBTBaseTest.py b/acts/framework/acts/test_utils/power/PowerBTBaseTest.py index 897982288f..3ea3d80f27 100644 --- a/acts/framework/acts/test_utils/power/PowerBTBaseTest.py +++ b/acts/framework/acts/test_utils/power/PowerBTBaseTest.py @@ -27,7 +27,8 @@ PHONE_MUSIC_FILE_DIRECTORY = '/sdcard/Music' INIT_ATTEN = [0] -def ramp_attenuation(obj_atten, attenuation_target): +def ramp_attenuation(obj_atten, attenuation_target, attenuation_step_max=20, + time_wait_in_between=5 ): """Ramp the attenuation up or down for BT tests. Ramp the attenuation slowly so it won't have dramatic signal drop to affect @@ -36,15 +37,16 @@ def ramp_attenuation(obj_atten, attenuation_target): Args: obj_atten: attenuator object, a single port attenuator attenuation_target: target attenuation level to reach to. + attenuation_step_max: max step for attenuation set + time_wait_in_between: wait time between attenuation changes """ - attenuation_step_max = 20 sign = lambda x: copysign(1, x) attenuation_delta = obj_atten.get_atten() - attenuation_target while abs(attenuation_delta) > attenuation_step_max: attenuation_intermediate = obj_atten.get_atten( ) - sign(attenuation_delta) * attenuation_step_max obj_atten.set_atten(attenuation_intermediate) - time.sleep(5) + time.sleep(time_wait_in_between) attenuation_delta = obj_atten.get_atten() - attenuation_target obj_atten.set_atten(attenuation_target) diff --git a/acts/framework/acts/test_utils/power/PowerBaseTest.py b/acts/framework/acts/test_utils/power/PowerBaseTest.py index 40f2a6b53f..8e3482dacc 100644 --- a/acts/framework/acts/test_utils/power/PowerBaseTest.py +++ b/acts/framework/acts/test_utils/power/PowerBaseTest.py @@ -346,7 +346,6 @@ class PowerBaseTest(base_test.BaseTestClass): self.avg_current = result.average_current plot_utils.monsoon_data_plot(self.mon_info, result) - plot_utils.monsoon_histogram_plot(self.mon_info, result) return result @@ -386,8 +385,6 @@ class PowerBaseTest(base_test.BaseTestClass): Returns: mon_info: Dictionary with the monsoon packet config """ - if self.iperf_duration: - self.mon_duration = self.iperf_duration - 10 mon_info = ObjNew(dut=self.mon, freq=self.mon_freq, duration=self.mon_duration, diff --git a/acts/framework/acts/test_utils/power/PowerGTWGnssBaseTest.py b/acts/framework/acts/test_utils/power/PowerGTWGnssBaseTest.py new file mode 100644 index 0000000000..fe79e80159 --- /dev/null +++ b/acts/framework/acts/test_utils/power/PowerGTWGnssBaseTest.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python3 +# +# Copyright 2020 - The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import time + +from acts import signals +from acts import utils +from acts.test_utils.power.PowerBaseTest import PowerBaseTest +from acts.test_utils.gnss import gnss_test_utils as gutils +from acts.test_utils.wifi import wifi_test_utils as wutils + +DEFAULT_WAIT_TIME = 120 +STANDALONE_WAIT_TIME = 1200 +DPO_NV_VALUE = '15DC' +MDS_TEST_PACKAGE = 'com.google.mdstest' +MDS_RUNNER = 'com.google.mdstest.instrument.ModemConfigInstrumentation' + + +class PowerGTWGnssBaseTest(PowerBaseTest): + """Power GTW Gnss Base test""" + + def setup_class(self): + super().setup_class() + self.ad = self.android_devices[0] + req_params = [ + 'wifi_network', 'test_location', 'qdsp6m_path', + 'calibrate_target' + ] + self.unpack_userparams(req_param_names=req_params) + gutils.disable_xtra_throttle(self.ad) + + def setup_test(self): + super().setup_test() + # Enable GNSS setting for GNSS standalone mode + self.ad.adb.shell('settings put secure location_mode 3') + + def teardown_test(self): + begin_time = utils.get_current_epoch_time() + self.ad.take_bug_report(self.test_name, begin_time) + gutils.get_gnss_qxdm_log(self.ad, self.qdsp6m_path) + + def baseline_test(self): + """Baseline power measurement""" + self.ad.droid.goToSleepNow() + result = self.collect_power_data() + self.ad.log.info('TestResult AVG_Current %.2f' % result.average_current) + + def start_gnss_tracking_with_power_data(self, + mode='default', + is_signal=True, + freq=0, + lowpower=False, + meas=False): + """Start GNSS tracking and collect power metrics. + + Args: + is_signal: default True, False for no Gnss signal test. + freq: an integer to set location update frequency. + lowpower: a boolean to set GNSS Low Power Mode. + mean: a boolean to set GNSS Measurement registeration. + """ + self.ad.adb.shell('settings put secure location_mode 3') + gutils.clear_aiding_data_by_gtw_gpstool(self.ad) + gutils.start_gnss_by_gtw_gpstool(self.ad, True, 'gnss', True, freq, + lowpower, meas) + self.ad.droid.goToSleepNow() + + sv_collecting_time = DEFAULT_WAIT_TIME + if mode == 'standalone': + sv_collecting_time = STANDALONE_WAIT_TIME + self.ad.log.info('Wait %d seconds for %s mode' % + (sv_collecting_time, mode)) + time.sleep(sv_collecting_time) + + result = self.collect_power_data() + self.ad.log.info('TestResult AVG_Current %.2f' % result.average_current) + self.calibrate_avg_current(result) + self.ad.send_keycode('WAKEUP') + gutils.start_gnss_by_gtw_gpstool(self.ad, False, 'gnss') + if is_signal: + gutils.parse_gtw_gpstool_log( + self.ad, self.test_location, type='gnss') + + def calibrate_avg_current(self, monsoon_results): + """Calibrate average current by filtering AP wake up current with target + value. + + Args: + monsoon_result: a MonsoonResult obj. + """ + monsoon_results = [monsoon_results] + calibrate_results = [ + data_point.current * 1000 + for monsoon_result in monsoon_results + for data_point in monsoon_result.get_data_points() + if data_point.current * 1000 < self.calibrate_target + ] + avg_current = sum(calibrate_results) / len(calibrate_results) + self.ad.log.info('TestResult Calibrate_AVG_Current %.2f' % avg_current) + + def enable_DPO(self, enable): + """Enable or disable the DPO option. + + Args: + enable: True or False to enable DPO. + """ + self.ad.log.info('Change DPO to new state: %s.' % enable) + val = '02' if enable else '00' + options = {'request': 'writeNV', 'item': DPO_NV_VALUE, 'data': val} + instrument_cmd = gutils.build_instrumentation_call( + MDS_TEST_PACKAGE, MDS_RUNNER, options=options) + result = self.ad.adb.shell(instrument_cmd) + if 'SUCCESS' not in result: + self.ad.log.info(result) + raise signals.TestFailure('DPO is not able to Turn: %s' % enable) + self.dut_rockbottom() diff --git a/acts/framework/acts/test_utils/power/PowerWiFiBaseTest.py b/acts/framework/acts/test_utils/power/PowerWiFiBaseTest.py index 80b563b292..c72c20cb7f 100644 --- a/acts/framework/acts/test_utils/power/PowerWiFiBaseTest.py +++ b/acts/framework/acts/test_utils/power/PowerWiFiBaseTest.py @@ -21,6 +21,7 @@ from acts.test_utils.power import plot_utils IPERF_DURATION = 'iperf_duration' INITIAL_ATTEN = [0, 0, 90, 90] +IPERF_TAIL = 5 class PowerWiFiBaseTest(PBT.PowerBaseTest): @@ -28,7 +29,6 @@ class PowerWiFiBaseTest(PBT.PowerBaseTest): Inherited from the PowerBaseTest class """ - def setup_class(self): super().setup_class() @@ -48,7 +48,7 @@ class PowerWiFiBaseTest(PBT.PowerBaseTest): if hasattr(self, 'iperf_servers'): self.iperf_server = self.iperf_servers[0] if self.iperf_duration: - self.mon_duration = self.iperf_duration - 10 + self.mon_duration = self.iperf_duration - self.mon_offset - IPERF_TAIL self.create_monsoon_info() def teardown_test(self): @@ -86,7 +86,10 @@ class PowerWiFiBaseTest(PBT.PowerBaseTest): for ap in self.access_points: ap.close() - def setup_ap_connection(self, network, bandwidth=80, connect=True, + def setup_ap_connection(self, + network, + bandwidth=80, + connect=True, ap=None): """Setup AP and connect DUT to it. @@ -101,8 +104,9 @@ class PowerWiFiBaseTest(PBT.PowerBaseTest): wutils.wifi_toggle_state(self.dut, True) if not ap: if hasattr(self, 'access_points'): - self.brconfigs = wputils.ap_setup( - self.access_point, network, bandwidth=bandwidth) + self.brconfigs = wputils.ap_setup(self.access_point, + network, + bandwidth=bandwidth) else: self.brconfigs = wputils.ap_setup(ap, network, bandwidth=bandwidth) if connect: diff --git a/acts/framework/acts/test_utils/power/cellular/cellular_power_base_test.py b/acts/framework/acts/test_utils/power/cellular/cellular_power_base_test.py index 10d93e9d69..1e422f535e 100644 --- a/acts/framework/acts/test_utils/power/cellular/cellular_power_base_test.py +++ b/acts/framework/acts/test_utils/power/cellular/cellular_power_base_test.py @@ -21,11 +21,12 @@ import acts.controllers.cellular_simulator as simulator from acts.controllers.anritsu_lib import md8475_cellular_simulator as anritsu from acts.controllers.rohdeschwarz_lib import cmw500_cellular_simulator as cmw from acts.controllers.rohdeschwarz_lib import cmx500_cellular_simulator as cmx -from acts.test_utils.power.tel_simulations.GsmSimulation import GsmSimulation -from acts.test_utils.power.tel_simulations.LteSimulation import LteSimulation -from acts.test_utils.power.tel_simulations.UmtsSimulation import UmtsSimulation -from acts.test_utils.power.tel_simulations.LteCaSimulation import LteCaSimulation -from acts.test_utils.power.tel_simulations.LteImsSimulation import LteImsSimulation +from acts.controllers.cellular_lib import AndroidCellularDut +from acts.controllers.cellular_lib import GsmSimulation +from acts.controllers.cellular_lib import LteSimulation +from acts.controllers.cellular_lib import UmtsSimulation +from acts.controllers.cellular_lib import LteCaSimulation +from acts.controllers.cellular_lib import LteImsSimulation from acts.test_utils.tel import tel_test_utils as telutils @@ -238,6 +239,14 @@ class PowerCellularLabBaseTest(PBT.PowerBaseTest): return True + def collect_power_data(self): + """ Collect power data using base class method and plot result + histogram. """ + + result = super().collect_power_data() + plot_utils.monsoon_histogram_plot(self.mon_info, result) + return result + def teardown_test(self): """ Executed after every test case, even if it failed or an exception happened. @@ -358,11 +367,11 @@ class PowerCellularLabBaseTest(PBT.PowerBaseTest): """ simulation_dictionary = { - self.PARAM_SIM_TYPE_LTE: LteSimulation, - self.PARAM_SIM_TYPE_UMTS: UmtsSimulation, - self.PARAM_SIM_TYPE_GSM: GsmSimulation, - self.PARAM_SIM_TYPE_LTE_CA: LteCaSimulation, - self.PARAM_SIM_TYPE_LTE_IMS: LteImsSimulation + self.PARAM_SIM_TYPE_LTE: LteSimulation.LteSimulation, + self.PARAM_SIM_TYPE_UMTS: UmtsSimulation.UmtsSimulation, + self.PARAM_SIM_TYPE_GSM: GsmSimulation.GsmSimulation, + self.PARAM_SIM_TYPE_LTE_CA: LteCaSimulation.LteCaSimulation, + self.PARAM_SIM_TYPE_LTE_IMS: LteImsSimulation.LteImsSimulation } if not sim_type in simulation_dictionary: @@ -383,9 +392,11 @@ class PowerCellularLabBaseTest(PBT.PowerBaseTest): if sim_type not in self.calibration_table: self.calibration_table[sim_type] = {} + cellular_dut = AndroidCellularDut.AndroidCellularDut( + self.dut, self.log) # Instantiate a new simulation self.simulation = simulation_class(self.cellular_simulator, self.log, - self.dut, self.test_params, + cellular_dut, self.test_params, self.calibration_table[sim_type]) def ensure_valid_calibration_table(self, calibration_table): diff --git a/acts/framework/acts/test_utils/power/cellular/cellular_traffic_power_test.py b/acts/framework/acts/test_utils/power/cellular/cellular_traffic_power_test.py index 58b62ad7be..9dd4a5e427 100644 --- a/acts/framework/acts/test_utils/power/cellular/cellular_traffic_power_test.py +++ b/acts/framework/acts/test_utils/power/cellular/cellular_traffic_power_test.py @@ -19,6 +19,7 @@ import time import scapy.all as scapy from acts import asserts +from acts import utils from acts.metrics.loggers.blackbox import BlackboxMetricLogger from acts.test_utils.power import IperfHelper as IPH from acts.test_utils.power import plot_utils @@ -281,6 +282,11 @@ class PowerTelTrafficTest(PWCEL.PowerCellularLabBaseTest): self.iperf_server_address = scapy.get_if_addr( self.packet_senders[0].interface) + self.log.info('Testing IP connectivity with ping.') + if not utils.adb_shell_ping( + client_host, count=10, dest_ip=self.iperf_server_address): + raise RuntimeError('Ping between DUT and host failed.') + # Start iPerf traffic iperf_helpers = [] diff --git a/acts/framework/acts/test_utils/tel/anritsu_utils.py b/acts/framework/acts/test_utils/tel/anritsu_utils.py index a06fd99350..4ffdd8b883 100644 --- a/acts/framework/acts/test_utils/tel/anritsu_utils.py +++ b/acts/framework/acts/test_utils/tel/anritsu_utils.py @@ -18,6 +18,7 @@ import time from queue import Empty from datetime import datetime +from acts.controllers.anritsu_lib import band_constants from acts.controllers.anritsu_lib._anritsu_utils import AnritsuUtils from acts.controllers.anritsu_lib.md8475a import BtsNumber from acts.controllers.anritsu_lib.md8475a import BtsNwNameEnable @@ -145,22 +146,6 @@ Fi_CSCF_IPV6_ADDR_IMS = "2001:0:0:1::3" Fi_CSCF_IPV4_ADDR_911 = "192.168.1.12" Fi_CSCF_IPV6_ADDR_911 = "2001:0:0:2::2" -# GSM BAND constants -GSM_BAND_GSM450 = "GSM450" -GSM_BAND_GSM480 = "GSM480" -GSM_BAND_GSM850 = "GSM850" -GSM_BAND_PGSM900 = "P-GSM900" -GSM_BAND_EGSM900 = "E-GSM900" -GSM_BAND_RGSM900 = "R-GSM900" -GSM_BAND_DCS1800 = "DCS1800" -GSM_BAND_PCS1900 = "PCS1900" - -LTE_BAND_2 = 2 -LTE_BAND_4 = 4 -LTE_BAND_12 = 12 -WCDMA_BAND_1 = 1 -WCDMA_BAND_2 = 2 - # Default Cell Parameters DEFAULT_OUTPUT_LEVEL = -30 DEFAULT_1X_OUTPUT_LEVEL = -35 @@ -169,10 +154,10 @@ DEFAULT_LTE_BAND = [2, 4] Fi_LTE_TMO_BAND = [4] Fi_LTE_SPR_BAND = [25] Fi_LTE_USCC_BAND = [12] -Fi_GSM_TMO_BAND = GSM_BAND_PGSM900 +Fi_GSM_TMO_BAND = band_constants.GSM_BAND_PGSM900 DEFAULT_WCDMA_BAND = 1 DEFAULT_WCDMA_PACKET_RATE = BtsPacketRate.WCDMA_DLHSAUTO_REL7_ULHSAUTO -DEFAULT_GSM_BAND = GSM_BAND_GSM850 +DEFAULT_GSM_BAND = band_constants.GSM_BAND_GSM850 #Google Fi CDMA Bands 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 5b2f313b3f..3b6207eac6 100644 --- a/acts/framework/acts/test_utils/tel/tel_data_utils.py +++ b/acts/framework/acts/test_utils/tel/tel_data_utils.py @@ -22,11 +22,14 @@ from acts.utils import rand_ascii_str from acts.test_utils.tel.tel_subscription_utils import \ get_subid_from_slot_index from acts.test_utils.tel.tel_subscription_utils import set_subid_for_data +from acts.test_utils.tel.tel_subscription_utils import get_outgoing_message_sub_id +from acts.test_utils.tel.tel_subscription_utils import get_outgoing_voice_sub_id from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_NW_SELECTION from acts.test_utils.tel.tel_defines import NETWORK_SERVICE_DATA from acts.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING from acts.test_utils.tel.tel_defines import WAIT_TIME_BETWEEN_STATE_CHECK from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_FOR_STATE_CHANGE +from acts.test_utils.tel.tel_defines import WAIT_TIME_AFTER_REBOOT from acts.test_utils.tel.tel_subscription_utils import get_default_data_sub_id from acts.test_utils.tel.tel_test_utils import start_youtube_video from acts.test_utils.tel.tel_test_utils import start_wifi_tethering @@ -581,8 +584,8 @@ def browsing_test(log, ad, wifi_ssid=None, pass_threshold_in_mb = 1.0): ad.droid.goToSleepNow() time.sleep(rest_idle_time) ad.log.info("Wake up device.") - ad.droid.wakeLockAcquireBright() - ad.droid.wakeUpNow() + ad.wakeup_screen() + ad.adb.shell("input keyevent 82") time.sleep(3) else: time.sleep(idle_time) @@ -607,3 +610,108 @@ def browsing_test(log, ad, wifi_ssid=None, pass_threshold_in_mb = 1.0): usage = "unknown" ad.log.info("Usage of browsing: %s MB" % usage) return False + +def reboot_test(log, ad, wifi_ssid=None): + """ Reboot test to verify the service availability after reboot. + + Test procedure: + 1. Reboot + 2. Wait WAIT_TIME_AFTER_REBOOT for reboot complete. + 3. Check service state. False will be returned if service state is not "IN_SERVICE". + 4. Check if network is connected. False will be returned if not. + 5. Check if cellular data or Wi-Fi connection is available. False will be returned if not. + 6. Check if internet connection is available. False will be returned if not. + 7. Check if DSDS mode, data sub ID, voice sub ID and message sub ID still keep the same. + + Args: + log: log object. + ad: android object. + wifi_ssid: SSID of Wi-Fi AP for Wi-Fi connection. + + Returns: + True if pass; False if fail. + """ + try: + wifi_connected = False + if wifi_ssid and check_is_wifi_connected(ad.log, ad, wifi_ssid): + wifi_connected = True + + data_subid = get_default_data_sub_id(ad) + voice_subid = get_outgoing_voice_sub_id(ad) + sms_subid = get_outgoing_message_sub_id(ad) + + ad.reboot() + time.sleep(WAIT_TIME_AFTER_REBOOT) + + if not wait_for_state( + get_service_state_by_adb, + "IN_SERVICE", + MAX_WAIT_TIME_FOR_STATE_CHANGE, + WAIT_TIME_BETWEEN_STATE_CHECK, + log, + ad): + ad.log.error("Current service state: %s" % service_state) + return False + + if not ad.droid.connectivityNetworkIsConnected(): + ad.log.error("Network is NOT connected!") + return False + + if wifi_connected: + if not check_is_wifi_connected(ad.log, ad, wifi_ssid): + return False + else: + if not wait_for_cell_data_connection(log, ad, True): + ad.log.error("Failed to enable data connection.") + return False + + if not verify_internet_connection(log, ad): + ad.log.error("Internet connection is not available") + return False + + sim_mode = ad.droid.telephonyGetPhoneCount() + if hasattr(ad, "dsds"): + if sim_mode == 1: + ad.log.error("Phone is in single SIM mode after reboot.") + return False + elif sim_mode == 2: + ad.log.info("Phone keeps being in dual SIM mode after reboot.") + else: + if sim_mode == 1: + ad.log.info("Phone keeps being in single SIM mode after reboot.") + elif sim_mode == 2: + ad.log.error("Phone is in dual SIM mode after reboot.") + return False + + data_subid_after_reboot = get_default_data_sub_id(ad) + if data_subid_after_reboot != data_subid: + ad.log.error( + "Data sub ID changed! (Before reboot: %s; after reboot: %s)", + data_subid, data_subid_after_reboot) + return False + else: + ad.log.info("Data sub ID does not change after reboot.") + + voice_subid_after_reboot = get_outgoing_voice_sub_id(ad) + if voice_subid_after_reboot != voice_subid: + ad.log.error( + "Voice sub ID changed! (Before reboot: %s; after reboot: %s)", + voice_subid, voice_subid_after_reboot) + return False + else: + ad.log.info("Voice sub ID does not change after reboot.") + + sms_subid_after_reboot = get_outgoing_message_sub_id(ad) + if sms_subid_after_reboot != sms_subid: + ad.log.error( + "Message sub ID changed! (Before reboot: %s; after reboot: %s)", + sms_subid, sms_subid_after_reboot) + return False + else: + ad.log.info("Message sub ID does not change after reboot.") + + except Exception as e: + ad.log.error(e) + return False + + return True
\ No newline at end of file diff --git a/acts/framework/acts/test_utils/tel/tel_defines.py b/acts/framework/acts/test_utils/tel/tel_defines.py index ae66a83c3e..bcaf15f6a8 100644 --- a/acts/framework/acts/test_utils/tel/tel_defines.py +++ b/acts/framework/acts/test_utils/tel/tel_defines.py @@ -213,7 +213,10 @@ POWER_LEVEL_OUT_OF_SERVICE = -100 # Callbox Power level which will ensure full service on device POWER_LEVEL_FULL_SERVICE = -20 - +# set a fake time to test time recovering from network +FAKE_DATE_TIME = "010203042019.05" +FAKE_YEAR = "2019" +WAIT_TIME_SYNC_DATE_TIME_FROM_NETWORK = 2 # These are used in phone_number_formatter PHONE_NUMBER_STRING_FORMAT_7_DIGIT = 7 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 fbb6917088..3783af200f 100644 --- a/acts/framework/acts/test_utils/tel/tel_test_utils.py +++ b/acts/framework/acts/test_utils/tel/tel_test_utils.py @@ -127,6 +127,7 @@ from acts.test_utils.tel.tel_defines import WAIT_TIME_CHANGE_DATA_SUB_ID from acts.test_utils.tel.tel_defines import WAIT_TIME_IN_CALL from acts.test_utils.tel.tel_defines import WAIT_TIME_LEAVE_VOICE_MAIL from acts.test_utils.tel.tel_defines import WAIT_TIME_REJECT_CALL +from acts.test_utils.tel.tel_defines import WAIT_TIME_SYNC_DATE_TIME_FROM_NETWORK from acts.test_utils.tel.tel_defines import WAIT_TIME_VOICE_MAIL_SERVER_RESPONSE from acts.test_utils.tel.tel_defines import WFC_MODE_DISABLED from acts.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED @@ -179,6 +180,7 @@ from acts.test_utils.tel.tel_subscription_utils import get_outgoing_voice_sub_id from acts.test_utils.tel.tel_subscription_utils import get_incoming_voice_sub_id from acts.test_utils.tel.tel_subscription_utils import get_incoming_message_sub_id from acts.test_utils.tel.tel_subscription_utils import set_subid_for_outgoing_call +from acts.test_utils.tel.tel_subscription_utils import set_incoming_voice_sub_id from acts.test_utils.tel.tel_subscription_utils import set_subid_for_message from acts.test_utils.tel.tel_subscription_utils import get_subid_on_same_network_of_host_ad from acts.test_utils.wifi import wifi_test_utils @@ -3747,6 +3749,7 @@ def active_file_download_task(log, ad, file_name="5MB", method="curl"): } url_map = { "1MB": [ + "http://146.148.91.8/download/1MB.zip", "http://ipv4.download.thinkbroadband.com/1MB.zip" ], "5MB": [ @@ -4943,16 +4946,25 @@ def show_enhanced_4g_lte(ad, sub_id): if capabilities: if "hide_enhanced_4g_lte" in capabilities: result = False - ad.log.info('"Enhanced 4G LTE MODE" is hidden for sub ID %s.', sub_id) - show_enhanced_4g_lte_mode = getattr(ad, "show_enhanced_4g_lte_mode", False) + ad.log.info( + '"Enhanced 4G LTE MODE" is hidden for sub ID %s.', sub_id) + show_enhanced_4g_lte_mode = getattr( + ad, "show_enhanced_4g_lte_mode", False) if show_enhanced_4g_lte_mode in ["true", "True"]: current_voice_sub_id = get_outgoing_voice_sub_id(ad) if sub_id != current_voice_sub_id: set_incoming_voice_sub_id(ad, sub_id) - ad.log.info('Show "Enhanced 4G LTE MODE" forcibly for sub ID %s.', sub_id) - ad.adb.shell("am broadcast -a com.google.android.carrier.action.LOCAL_OVERRIDE -n com.google.android.carrier/.ConfigOverridingReceiver --ez hide_enhanced_4g_lte_bool false") - ad.telephony["subscription"][sub_id]["capabilities"].remove("hide_enhanced_4g_lte") + ad.log.info( + 'Show "Enhanced 4G LTE MODE" forcibly for sub ID %s.', + sub_id) + ad.adb.shell( + "am broadcast \ + -a com.google.android.carrier.action.LOCAL_OVERRIDE \ + -n com.google.android.carrier/.ConfigOverridingReceiver \ + --ez hide_enhanced_4g_lte_bool false") + ad.telephony["subscription"][sub_id]["capabilities"].remove( + "hide_enhanced_4g_lte") if sub_id != current_voice_sub_id: set_incoming_voice_sub_id(ad, current_voice_sub_id) @@ -4963,11 +4975,13 @@ def show_enhanced_4g_lte(ad, sub_id): def toggle_volte(log, ad, new_state=None): """Toggle enable/disable VoLTE for default voice subscription. + Args: ad: Android device object. new_state: VoLTE mode state to set to. True for enable, False for disable. If None, opposite of the current state. + Raises: TelTestUtilsError if platform does not support VoLTE. """ @@ -4980,7 +4994,8 @@ def toggle_volte_for_subscription(log, ad, sub_id, new_state=None): Args: ad: Android device object. - sub_id: subscription ID + sub_id: Optional. If not assigned the default sub ID for voice call will + be used. new_state: VoLTE mode state to set to. True for enable, False for disable. If None, opposite of the current state. @@ -4989,19 +5004,74 @@ def toggle_volte_for_subscription(log, ad, sub_id, new_state=None): if not show_enhanced_4g_lte(ad, sub_id): return False - current_state = ad.droid.imsMmTelIsAdvancedCallingEnabled(sub_id) - if new_state is None: - new_state = not current_state - if new_state != current_state: - ad.log.info("Toggle Enhanced 4G LTE Mode from %s to %s on sub_id %s", current_state, - new_state, sub_id) - ad.droid.imsMmTelSetAdvancedCallingEnabled(sub_id, new_state) - check_state = ad.droid.imsMmTelIsAdvancedCallingEnabled(sub_id) - if check_state != new_state: - ad.log.error("Failed to toggle Enhanced 4G LTE Mode to %s, still set to %s on sub_id %s", - new_state, check_state, sub_id) - return False - return True + current_state = None + result = True + + if sub_id is None: + sub_id = ad.droid.subscriptionGetDefaultVoiceSubId() + + try: + current_state = ad.droid.imsMmTelIsAdvancedCallingEnabled(sub_id) + except Exception as e: + ad.log.warning(e) + + if current_state is not None: + if new_state is None: + new_state = not current_state + if new_state != current_state: + ad.log.info( + "Toggle Enhanced 4G LTE Mode from %s to %s on sub_id %s", + current_state, new_state, sub_id) + ad.droid.imsMmTelSetAdvancedCallingEnabled(sub_id, new_state) + check_state = ad.droid.imsMmTelIsAdvancedCallingEnabled(sub_id) + if check_state != new_state: + ad.log.error("Failed to toggle Enhanced 4G LTE Mode to %s, still \ + set to %s on sub_id %s", new_state, check_state, sub_id) + result = False + return result + else: + # TODO: b/26293960 No framework API available to set IMS by SubId. + voice_sub_id_changed = False + current_sub_id = get_incoming_voice_sub_id(ad) + if current_sub_id != sub_id: + set_incoming_voice_sub_id(ad, sub_id) + voice_sub_id_changed = True + + # b/139641554 + ad.terminate_all_sessions() + bring_up_sl4a(ad) + + if not ad.droid.imsIsEnhanced4gLteModeSettingEnabledByPlatform(): + ad.log.info( + "Enhanced 4G Lte Mode Setting is not enabled by platform for \ + sub ID %s.", sub_id) + return False + + current_state = ad.droid.imsIsEnhanced4gLteModeSettingEnabledByUser() + ad.log.info("Current state of Enhanced 4G Lte Mode Setting for sub \ + ID %s: %s", sub_id, current_state) + ad.log.info("New desired state of Enhanced 4G Lte Mode Setting for sub \ + ID %s: %s", sub_id, new_state) + + if new_state is None: + new_state = not current_state + if new_state != current_state: + ad.log.info( + "Toggle Enhanced 4G LTE Mode from %s to %s for sub ID %s.", + current_state, new_state, sub_id) + ad.droid.imsSetEnhanced4gMode(new_state) + time.sleep(5) + + check_state = ad.droid.imsIsEnhanced4gLteModeSettingEnabledByUser() + if check_state != new_state: + ad.log.error("Failed to toggle Enhanced 4G LTE Mode to %s, \ + still set to %s on sub_id %s", new_state, check_state, sub_id) + result = False + + if voice_sub_id_changed: + set_incoming_voice_sub_id(ad, current_sub_id) + + return result def toggle_wfc(log, ad, new_state=None): @@ -5010,43 +5080,124 @@ def toggle_wfc(log, ad, new_state=None): Args: log: Log object ad: Android device object. - new_state: True or False + new_state: WFC state to set to. + True for enable, False for disable. + If None, opposite of the current state. """ - if not ad.droid.imsIsWfcEnabledByPlatform(): - ad.log.info("WFC is not enabled by platform") - return False - current_state = ad.droid.imsIsWfcEnabledByUser() - if current_state is None: - new_state = not current_state - if new_state != current_state: - ad.log.info("Toggle WFC user enabled from %s to %s", current_state, - new_state) - ad.droid.imsSetWfcSetting(new_state) - return True + return toggle_wfc_for_subscription( + log, ad, new_state, get_outgoing_voice_sub_id(ad)) -def toggle_wfc_for_subscription(ad, new_state=None, sub_id=None): - """ Toggle WFC enable/disable +def toggle_wfc_for_subscription(log, ad, new_state=None, sub_id=None): + """ Toggle WFC enable/disable for specified voice subscription. Args: ad: Android device object. - sub_id: subscription Id - new_state: True or False + sub_id: Optional. If not assigned the default sub ID for voice call will + be used. + new_state: WFC state to set to. + True for enable, False for disable. + If None, opposite of the current state. """ + current_state = None + result = True + if sub_id is None: sub_id = ad.droid.subscriptionGetDefaultVoiceSubId() - current_state = ad.droid.imsMmTelIsVoWiFiSettingEnabled(sub_id) - if current_state is None: - new_state = not current_state - if new_state != current_state: - ad.log.info("SubId %s - Toggle WFC from %s to %s", sub_id, - current_state, new_state) - ad.droid.imsMmTelSetVoWiFiSettingEnabled(sub_id, new_state) + + try: + current_state = ad.droid.imsMmTelIsVoWiFiSettingEnabled(sub_id) + except Exception as e: + ad.log.warning(e) + + if current_state is not None: + if new_state is None: + new_state = not current_state + if new_state != current_state: + ad.log.info( + "Toggle Enhanced 4G LTE Mode from %s to %s on sub_id %s", + current_state, new_state, sub_id) + ad.droid.imsMmTelSetVoWiFiSettingEnabled(sub_id, new_state) + check_state = ad.droid.imsMmTelIsVoWiFiSettingEnabled(sub_id) + if check_state != new_state: + ad.log.error("Failed to toggle Enhanced 4G LTE Mode to %s, \ + still set to %s on sub_id %s", new_state, check_state, sub_id) + result = False + return result + else: + voice_sub_id_changed = False + if not sub_id: + sub_id = get_outgoing_voice_sub_id(ad) + else: + current_sub_id = get_incoming_voice_sub_id(ad) + if current_sub_id != sub_id: + set_incoming_voice_sub_id(ad, sub_id) + voice_sub_id_changed = True + + # b/139641554 + ad.terminate_all_sessions() + bring_up_sl4a(ad) + + if not ad.droid.imsIsWfcEnabledByPlatform(): + ad.log.info("WFC is not enabled by platform for sub ID %s.", sub_id) + return False + + current_state = ad.droid.imsIsWfcEnabledByUser() + ad.log.info("Current state of WFC Setting for sub ID %s: %s", + sub_id, current_state) + ad.log.info("New desired state of WFC Setting for sub ID %s: %s", + sub_id, new_state) + + if new_state is None: + new_state = not current_state + if new_state != current_state: + ad.log.info("Toggle WFC user enabled from %s to %s for sub ID %s", + current_state, new_state, sub_id) + ad.droid.imsSetWfcSetting(new_state) + + if voice_sub_id_changed: + set_incoming_voice_sub_id(ad, current_sub_id) + + return True + +def is_enhanced_4g_lte_mode_setting_enabled(ad, sub_id, enabled_by="platform"): + voice_sub_id_changed = False + current_sub_id = get_incoming_voice_sub_id(ad) + if current_sub_id != sub_id: + set_incoming_voice_sub_id(ad, sub_id) + voice_sub_id_changed = True + if enabled_by == "platform": + res = ad.droid.imsIsEnhanced4gLteModeSettingEnabledByPlatform() + else: + res = ad.droid.imsIsEnhanced4gLteModeSettingEnabledByUser() + if not res: + ad.log.info("Enhanced 4G Lte Mode Setting is NOT enabled by %s for sub \ + ID %s.", enabled_by, sub_id) + if voice_sub_id_changed: + set_incoming_voice_sub_id(ad, current_sub_id) + return False + if voice_sub_id_changed: + set_incoming_voice_sub_id(ad, current_sub_id) + ad.log.info("Enhanced 4G Lte Mode Setting is enabled by %s for sub ID %s.", + enabled_by, sub_id) return True +def set_enhanced_4g_mode(ad, sub_id, state): + voice_sub_id_changed = False + current_sub_id = get_incoming_voice_sub_id(ad) + if current_sub_id != sub_id: + set_incoming_voice_sub_id(ad, sub_id) + voice_sub_id_changed = True + + ad.droid.imsSetEnhanced4gMode(state) + time.sleep(5) + + if voice_sub_id_changed: + set_incoming_voice_sub_id(ad, current_sub_id) def wait_for_enhanced_4g_lte_setting(log, ad, + sub_id, max_time=MAX_WAIT_TIME_FOR_STATE_CHANGE): """Wait for android device to enable enhance 4G LTE setting. @@ -5060,9 +5211,13 @@ def wait_for_enhanced_4g_lte_setting(log, Return False if timeout. """ return wait_for_state( - ad.droid.imsIsEnhanced4gLteModeSettingEnabledByPlatform, + is_enhanced_4g_lte_mode_setting_enabled, True, - max_wait_time=max_time) + max_time, + WAIT_TIME_BETWEEN_STATE_CHECK, + ad, + sub_id, + enabled_by="platform") def set_wfc_mode(log, ad, wfc_mode): @@ -5078,29 +5233,8 @@ def set_wfc_mode(log, ad, wfc_mode): Returns: True if success. False if ad does not support WFC or error happened. """ - if wfc_mode != WFC_MODE_DISABLED and wfc_mode not in ad.telephony[ - "subscription"][get_outgoing_voice_sub_id(ad)].get("wfc_modes", []): - ad.log.error("WFC mode %s is not supported", wfc_mode) - raise signals.TestSkip("WFC mode %s is not supported" % wfc_mode) - try: - ad.log.info("Set wfc mode to %s", wfc_mode) - if wfc_mode != WFC_MODE_DISABLED: - start_adb_tcpdump(ad, interface="wlan0", mask="all") - if not ad.droid.imsIsWfcEnabledByPlatform(): - if wfc_mode == WFC_MODE_DISABLED: - return True - else: - ad.log.error("WFC not supported by platform.") - return False - ad.droid.imsSetWfcMode(wfc_mode) - mode = ad.droid.imsGetWfcMode() - if mode != wfc_mode: - ad.log.error("WFC mode is %s, not in %s", mode, wfc_mode) - return False - except Exception as e: - log.error(e) - return False - return True + return set_wfc_mode_for_subscription( + ad, wfc_mode, get_outgoing_voice_sub_id(ad)) def set_wfc_mode_for_subscription(ad, wfc_mode, sub_id=None): @@ -5116,22 +5250,97 @@ def set_wfc_mode_for_subscription(ad, wfc_mode, sub_id=None): Returns: True if success. False if ad does not support WFC or error happened. """ + if wfc_mode not in [ + WFC_MODE_WIFI_ONLY, + WFC_MODE_CELLULAR_PREFERRED, + WFC_MODE_WIFI_PREFERRED, + WFC_MODE_DISABLED]: + + ad.log.error("Given WFC mode (%s) is not correct.", wfc_mode) + return False + + current_mode = None + result = True + + if sub_id is None: + sub_id = ad.droid.subscriptionGetDefaultVoiceSubId() + try: - if sub_id is None: - sub_id = ad.droid.subscriptionGetDefaultVoiceSubId() - if not ad.droid.imsMmTelIsVoWiFiSettingEnabled(sub_id): - ad.log.info("SubId %s - Enabling WiFi Calling", sub_id) - ad.droid.imsMmTelSetVoWiFiSettingEnabled(sub_id, True) - ad.log.info("SubId %s - setwfcmode to %s", sub_id, wfc_mode) - ad.droid.imsMmTelSetVoWiFiModeSetting(sub_id, wfc_mode) - mode = ad.droid.imsMmTelGetVoWiFiModeSetting(sub_id) - if mode != wfc_mode: - ad.log.error("SubId %s - getwfcmode shows %s", sub_id, mode) - return False + current_mode = ad.droid.imsMmTelGetVoWiFiModeSetting(sub_id) + ad.log.info("Current WFC mode of sub ID: %s", current_mode) except Exception as e: - ad.log.error(e) - return False - return True + ad.log.warning(e) + + if current_mode is not None: + try: + if not ad.droid.imsMmTelIsVoWiFiSettingEnabled(sub_id): + if wfc_mode is WFC_MODE_DISABLED: + return True + ad.log.info( + "WFC is disabled for sub ID %s. Enabling WFC...", sub_id) + ad.droid.imsMmTelSetVoWiFiSettingEnabled(sub_id, True) + + if wfc_mode is WFC_MODE_DISABLED: + ad.droid.imsMmTelSetVoWiFiSettingEnabled(sub_id, False) + return True + + ad.log.info("Set wfc mode to %s for sub ID %s.", wfc_mode, sub_id) + ad.droid.imsMmTelSetVoWiFiModeSetting(sub_id, wfc_mode) + mode = ad.droid.imsMmTelGetVoWiFiModeSetting(sub_id) + if mode != wfc_mode: + ad.log.error("WFC mode for sub ID %s is %s, not in %s", + sub_id, mode, wfc_mode) + return False + except Exception as e: + ad.log.error(e) + return False + return True + else: + voice_sub_id_changed = False + if not sub_id: + sub_id = get_outgoing_voice_sub_id(ad) + else: + current_sub_id = get_incoming_voice_sub_id(ad) + if current_sub_id != sub_id: + set_incoming_voice_sub_id(ad, sub_id) + voice_sub_id_changed = True + + # b/139641554 + ad.terminate_all_sessions() + bring_up_sl4a(ad) + + if wfc_mode != WFC_MODE_DISABLED and wfc_mode not in ad.telephony[ + "subscription"][get_outgoing_voice_sub_id(ad)].get("wfc_modes", []): + ad.log.error("WFC mode %s is not supported", wfc_mode) + raise signals.TestSkip("WFC mode %s is not supported" % wfc_mode) + try: + ad.log.info("Set wfc mode to %s", wfc_mode) + if wfc_mode != WFC_MODE_DISABLED: + start_adb_tcpdump(ad, interface="wlan0", mask="all") + if not ad.droid.imsIsWfcEnabledByPlatform(): + if wfc_mode == WFC_MODE_DISABLED: + if voice_sub_id_changed: + set_incoming_voice_sub_id(ad, current_sub_id) + return True + else: + ad.log.error("WFC not supported by platform.") + if voice_sub_id_changed: + set_incoming_voice_sub_id(ad, current_sub_id) + return False + ad.droid.imsSetWfcMode(wfc_mode) + mode = ad.droid.imsGetWfcMode() + if voice_sub_id_changed: + set_incoming_voice_sub_id(ad, current_sub_id) + if mode != wfc_mode: + ad.log.error("WFC mode is %s, not in %s", mode, wfc_mode) + return False + except Exception as e: + log.error(e) + if voice_sub_id_changed: + set_incoming_voice_sub_id(ad, current_sub_id) + return False + return True + def set_ims_provisioning_for_subscription(ad, feature_flag, value, sub_id=None): @@ -5562,18 +5771,24 @@ def wait_for_data_attach_for_subscription(log, ad, sub_id, max_time): NETWORK_SERVICE_DATA) -def is_ims_registered(log, ad): +def is_ims_registered(log, ad, sub_id=None): """Return True if IMS registered. Args: log: log object. ad: android device. + sub_id: Optional. If not assigned the default sub ID of voice call will + be used. Returns: Return True if IMS registered. Return False if IMS not registered. """ - return ad.droid.telephonyIsImsRegistered() + if not sub_id: + return ad.droid.telephonyIsImsRegistered() + else: + return change_voice_subid_temporarily( + ad, sub_id, ad.droid.telephonyIsImsRegistered) def wait_for_ims_registered(log, ad, max_time=MAX_WAIT_TIME_WFC_ENABLED): @@ -5590,26 +5805,48 @@ def wait_for_ims_registered(log, ad, max_time=MAX_WAIT_TIME_WFC_ENABLED): """ return _wait_for_droid_in_state(log, ad, max_time, is_ims_registered) +def is_volte_available(log, ad, sub_id): + """Return True if VoLTE is available. + + Args: + log: log object. + ad: android device. + sub_id: Optional. If not assigned the default sub ID of voice call will + be used. + + Returns: + Return True if VoLTE is available. + Return False if VoLTE is not available. + """ + if not sub_id: + return ad.droid.telephonyIsVolteAvailable() + else: + return change_voice_subid_temporarily( + ad, sub_id, ad.droid.telephonyIsVolteAvailable) -def is_volte_enabled(log, ad): +def is_volte_enabled(log, ad, sub_id=None): """Return True if VoLTE feature bit is True. Args: log: log object. ad: android device. + sub_id: Optional. If not assigned the default sub ID of voice call will + be used. Returns: Return True if VoLTE feature bit is True and IMS registered. Return False if VoLTE feature bit is False or IMS not registered. """ - if not is_ims_registered(log, ad): - ad.log.info("IMS is not registered.") + if not is_ims_registered(log, ad, sub_id): + ad.log.info("IMS is not registered for sub ID %s.", sub_id) return False - if not ad.droid.telephonyIsVolteAvailable(): - ad.log.info("IMS is registered, IsVolteCallingAvailble is False") + if not is_volte_available(log, ad, sub_id): + ad.log.info("IMS is registered for sub ID %s, IsVolteCallingAvailable \ + is False", sub_id) return False else: - ad.log.info("IMS is registered, IsVolteCallingAvailble is True") + ad.log.info("IMS is registered for sub ID %s, IsVolteCallingAvailable \ + is True", sub_id) return True @@ -5632,7 +5869,8 @@ def is_video_enabled(log, ad): return video_status -def wait_for_volte_enabled(log, ad, max_time=MAX_WAIT_TIME_VOLTE_ENABLED): +def wait_for_volte_enabled( + log, ad, max_time=MAX_WAIT_TIME_VOLTE_ENABLED,sub_id=None): """Wait for android device to report VoLTE enabled bit true. Args: @@ -5644,7 +5882,11 @@ def wait_for_volte_enabled(log, ad, max_time=MAX_WAIT_TIME_VOLTE_ENABLED): Return True if device report VoLTE enabled bit true within max_time. Return False if timeout. """ - return _wait_for_droid_in_state(log, ad, max_time, is_volte_enabled) + if not sub_id: + return _wait_for_droid_in_state(log, ad, max_time, is_volte_enabled) + else: + return _wait_for_droid_in_state_for_subscription( + log, ad, sub_id, max_time, is_volte_enabled) def wait_for_video_enabled(log, ad, max_time=MAX_WAIT_TIME_VOLTE_ENABLED): @@ -5677,10 +5919,10 @@ def is_wfc_enabled(log, ad): ad.log.info("IMS is not registered.") return False if not ad.droid.telephonyIsWifiCallingAvailable(): - ad.log.info("IMS is registered, IsWifiCallingAvailble is False") + ad.log.info("IMS is registered, IsWifiCallingAvailable is False") return False else: - ad.log.info("IMS is registered, IsWifiCallingAvailble is True") + ad.log.info("IMS is registered, IsWifiCallingAvailable is True") return True @@ -6353,7 +6595,7 @@ def mms_receive_verify_after_call_hangup_for_subscription( if not wait_for_matching_mms(log, ad_rx, phonenumber_tx, message): return False finally: - ad_rx.droid.smsStopTrackingIncomingMmsMessage() + ad_rx.messaging_droid.smsStopTrackingIncomingMmsMessage() return True @@ -10312,44 +10554,110 @@ def wait_for_matching_multiple_sms(log, return True -def is_sms_in_collision_match(event, phonenumber_tx, phonenumber_tx2, text, text2): +def is_sms_in_collision_match( + event, phonenumber_tx, phonenumber_tx2, text, text2): event_text = event['data']['Text'].strip() if event_text.startswith("("): event_text = event_text.split(")")[-1] for phonenumber, txt in [[phonenumber_tx, text], [phonenumber_tx2, text2]]: - if check_phone_number_match(event['data']['Sender'], phonenumber) and txt.startswith(event_text): + if check_phone_number_match( + event['data']['Sender'], phonenumber) and txt.startswith(event_text): return True return False -def is_sms_in_collision_partial_match(event, phonenumber_tx, phonenumber_tx2, text, text2): +def is_sms_in_collision_partial_match( + event, phonenumber_tx, phonenumber_tx2, text, text2): for phonenumber, txt in [[phonenumber_tx, text], [phonenumber_tx2, text2]]: - if check_phone_number_match(event['data']['Sender'], phonenumber) and event['data']['Text'].strip() == txt: + if check_phone_number_match( + event['data']['Sender'], phonenumber) and \ + event['data']['Text'].strip() == txt: return True return False -def is_sms_match_among_multiple_sms(event, phonenumber_tx, phonenumber_tx2, texts=[], texts2=[]): +def is_sms_match_among_multiple_sms( + event, phonenumber_tx, phonenumber_tx2, texts=[], texts2=[]): for txt in texts: - if check_phone_number_match(event['data']['Sender'], phonenumber_tx) and event['data']['Text'].strip() == txt: + if check_phone_number_match( + event['data']['Sender'], phonenumber_tx) and \ + event['data']['Text'].strip() == txt: return True for txt in texts2: - if check_phone_number_match(event['data']['Sender'], phonenumber_tx2) and event['data']['Text'].strip() == txt: + if check_phone_number_match( + event['data']['Sender'], phonenumber_tx2) and \ + event['data']['Text'].strip() == txt: return True return False -def is_sms_partial_match_among_multiple_sms(event, phonenumber_tx, phonenumber_tx2, texts=[], texts2=[]): +def is_sms_partial_match_among_multiple_sms( + event, phonenumber_tx, phonenumber_tx2, texts=[], texts2=[]): event_text = event['data']['Text'].strip() if event_text.startswith("("): event_text = event_text.split(")")[-1] for txt in texts: - if check_phone_number_match(event['data']['Sender'], phonenumber_tx) and txt.startswith(event_text): + if check_phone_number_match( + event['data']['Sender'], phonenumber_tx) and \ + txt.startswith(event_text): return True for txt in texts2: - if check_phone_number_match(event['data']['Sender'], phonenumber_tx2) and txt.startswith(event_text): + if check_phone_number_match( + event['data']['Sender'], phonenumber_tx2) and \ + txt.startswith(event_text): return True return False + +def set_time_sync_from_network(ad, action): + if (action == 'enable'): + ad.log.info('Enabling sync time from network.') + ad.adb.shell('settings put global auto_time 1') + + elif (action == 'disable'): + ad.log.info('Disabling sync time from network.') + ad.adb.shell('settings put global auto_time 0') + + time.sleep(WAIT_TIME_SYNC_DATE_TIME_FROM_NETWORK) + +def datetime_handle(ad, action, set_datetime_value='', get_year=False): + get_value = '' + if (action == 'get'): + if (get_year): + datetime_string = ad.adb.shell('date') + datetime_list = datetime_string.split() + try: + get_value = datetime_list[5] + except Exception as e: + self.log.error("Fail to get year from datetime: %s. " \ + "Exception error: %s", datetime_list + , str(e)) + raise signals.TestSkip("Fail to get year from datetime" \ + ", the format is changed. Skip the test.") + else: + get_value = ad.adb.shell('date') + + elif (action == 'set'): + ad.adb.shell('date %s' % set_datetime_value) + time.sleep(WAIT_TIME_SYNC_DATE_TIME_FROM_NETWORK) + ad.adb.shell('am broadcast -a android.intent.action.TIME_SET') + + return get_value + +def change_voice_subid_temporarily(ad, sub_id, state_check_func): + result = False + voice_sub_id_changed = False + current_sub_id = get_incoming_voice_sub_id(ad) + if current_sub_id != sub_id: + set_incoming_voice_sub_id(ad, sub_id) + voice_sub_id_changed = True + + if state_check_func(): + result = True + + if voice_sub_id_changed: + set_incoming_voice_sub_id(ad, current_sub_id) + + return result
\ No newline at end of file diff --git a/acts/framework/acts/test_utils/tel/tel_voice_utils.py b/acts/framework/acts/test_utils/tel/tel_voice_utils.py index 4294bf3ea6..1c41658fa5 100644 --- a/acts/framework/acts/test_utils/tel/tel_voice_utils.py +++ b/acts/framework/acts/test_utils/tel/tel_voice_utils.py @@ -765,7 +765,6 @@ def phone_setup_iwlan(log, Make sure phone connect to WiFi. (If wifi_ssid is not None.) Wait for phone to be in iwlan data network type. Wait for phone to report wfc enabled flag to be true. - Args: log: Log object. ad: Android device object. @@ -774,14 +773,9 @@ def phone_setup_iwlan(log, wifi_ssid: WiFi network SSID. This is optional. If wifi_ssid is None, then phone_setup_iwlan will not attempt to connect to wifi. wifi_pwd: WiFi network password. This is optional. - Returns: True if success. False if fail. """ - if not get_capability_for_subscription(ad, CAPABILITY_WFC, - get_outgoing_voice_sub_id(ad)): - ad.log.error("WFC is not supported, abort test.") - raise signals.TestSkip("WFC is not supported, abort test.") return phone_setup_iwlan_for_subscription(log, ad, get_outgoing_voice_sub_id(ad), is_airplane_mode, wfc_mode, @@ -801,7 +795,6 @@ def phone_setup_iwlan_for_subscription(log, Make sure phone connect to WiFi. (If wifi_ssid is not None.) Wait for phone to be in iwlan data network type. Wait for phone to report wfc enabled flag to be true. - Args: log: Log object. ad: Android device object. @@ -811,19 +804,19 @@ def phone_setup_iwlan_for_subscription(log, wifi_ssid: WiFi network SSID. This is optional. If wifi_ssid is None, then phone_setup_iwlan will not attempt to connect to wifi. wifi_pwd: WiFi network password. This is optional. - Returns: True if success. False if fail. """ + if not get_capability_for_subscription(ad, CAPABILITY_WFC, sub_id): + ad.log.error("WFC is not supported, abort test.") + raise signals.TestSkip("WFC is not supported, abort test.") toggle_airplane_mode(log, ad, is_airplane_mode, strict_checking=False) - # check if WFC supported phones if wfc_mode != WFC_MODE_DISABLED and not ad.droid.imsIsWfcEnabledByPlatform( ): ad.log.error("WFC is not enabled on this device by checking " "ImsManager.isWfcEnabledByPlatform") return False - if wifi_ssid is not None: if not ensure_wifi_connected(log, ad, wifi_ssid, wifi_pwd, apm=is_airplane_mode): ad.log.error("Fail to bring up WiFi connection on %s.", wifi_ssid) @@ -832,11 +825,9 @@ def phone_setup_iwlan_for_subscription(log, ad.log.info("WiFi network SSID not specified, available user " "parameters are: wifi_network_ssid, wifi_network_ssid_2g, " "wifi_network_ssid_5g") - if not set_wfc_mode(log, ad, wfc_mode): ad.log.error("Unable to set WFC mode to %s.", wfc_mode) return False - if not wait_for_wfc_enabled(log, ad, max_time=MAX_WAIT_TIME_WFC_ENABLED): ad.log.error("WFC is not enabled") return False @@ -1077,8 +1068,9 @@ def phone_setup_csfb_for_subscription(log, ad, sub_id): if not phone_setup_4g_for_subscription(log, ad, sub_id): ad.log.error("Failed to set to 4G data.") return False - if ad.droid.imsIsEnhanced4gLteModeSettingEnabledByPlatform(): - toggle_volte(log, ad, False) + + toggle_volte(log, ad, False) + if not ensure_network_generation_for_subscription( log, ad, sub_id, GEN_4G, voice_or_data=NETWORK_SERVICE_DATA): return False @@ -1111,20 +1103,22 @@ def phone_setup_volte(log, ad): def phone_setup_volte_for_subscription(log, ad, sub_id): """Setup VoLTE enable for subscription id. - Args: log: log object ad: android device object. sub_id: subscription id. - Returns: True: if VoLTE is enabled successfully. False: for errors """ + if not get_capability_for_subscription(ad, CAPABILITY_VOLTE, + get_outgoing_voice_sub_id(ad)): + ad.log.error("VoLTE is not supported, abort test.") + raise signals.TestSkip("VoLTE is not supported, abort test.") if not phone_setup_4g_for_subscription(log, ad, sub_id): ad.log.error("Failed to set to 4G data.") return False - if not wait_for_enhanced_4g_lte_setting(log, ad): + if not wait_for_enhanced_4g_lte_setting(log, ad, sub_id): ad.log.error("Enhanced 4G LTE setting is not available") return False toggle_volte_for_subscription(log, ad, sub_id, True) @@ -1361,7 +1355,6 @@ def phone_idle_volte(log, ad): def phone_idle_volte_for_subscription(log, ad, sub_id): """Return if phone is idle for VoLTE call test for subscription id. - Args: ad: Android device object. sub_id: subscription id. @@ -1371,7 +1364,7 @@ def phone_idle_volte_for_subscription(log, ad, sub_id): voice_or_data=NETWORK_SERVICE_VOICE): ad.log.error("Voice rat not in LTE mode.") return False - if not wait_for_volte_enabled(log, ad, MAX_WAIT_TIME_VOLTE_ENABLED): + if not wait_for_volte_enabled(log, ad, MAX_WAIT_TIME_VOLTE_ENABLED, sub_id): ad.log.error( "Failed to <report volte enabled true> within %s seconds.", MAX_WAIT_TIME_VOLTE_ENABLED) @@ -1699,7 +1692,7 @@ def is_phone_in_call_iwlan(log, ad, call_id=None): ad.log.info("IMS is not registered.") return False if not ad.droid.telephonyIsWifiCallingAvailable(): - ad.log.info("IsWifiCallingAvailble is False") + ad.log.info("IsWifiCallingAvailable is False") return False if not call_id: call_ids = ad.droid.telecomCallGetCallIds() diff --git a/acts/framework/acts/test_utils/wifi/OWNERS b/acts/framework/acts/test_utils/wifi/OWNERS index 31966b7984..edb3e3ee80 100644 --- a/acts/framework/acts/test_utils/wifi/OWNERS +++ b/acts/framework/acts/test_utils/wifi/OWNERS @@ -1,5 +1,6 @@ -bmahadev@google.com +bkleung@google.com +dysu@google.com etancohen@google.com -mplass@google.com +gmoturu@google.com rpius@google.com satk@google.com diff --git a/acts/framework/acts/test_utils/wifi/WifiBaseTest.py b/acts/framework/acts/test_utils/wifi/WifiBaseTest.py index 82d655fff1..e79d03eda5 100644 --- a/acts/framework/acts/test_utils/wifi/WifiBaseTest.py +++ b/acts/framework/acts/test_utils/wifi/WifiBaseTest.py @@ -295,6 +295,112 @@ class WifiBaseTest(BaseTestClass): self.update_bssid(ap_instance, ap, network, hostapd_constants.BAND_2G) + def configure_openwrt_ap_and_start( + self, + channel_5g=hostapd_constants.AP_DEFAULT_CHANNEL_5G, + channel_2g=hostapd_constants.AP_DEFAULT_CHANNEL_2G, + ssid_length_2g=hostapd_constants.AP_SSID_LENGTH_2G, + passphrase_length_2g=hostapd_constants.AP_PASSPHRASE_LENGTH_2G, + ssid_length_5g=hostapd_constants.AP_SSID_LENGTH_5G, + passphrase_length_5g=hostapd_constants.AP_PASSPHRASE_LENGTH_5G, + mirror_ap=False, + hidden=False, + same_ssid=False, + open_network=False, + wpa_network=False, + wep_network=False, + ent_network=False, + ent_network_pwd=False, + radius_conf_2g=None, + radius_conf_5g=None, + radius_conf_pwd=None, + ap_count=1): + """Create, configure and start OpenWrt AP. + + Args: + channel_5g: 5G channel to configure. + channel_2g: 2G channel to configure. + ssid_length_2g: Int, number of characters to use for 2G SSID. + passphrase_length_2g: Int, length of password for 2G network. + ssid_length_5g: Int, number of characters to use for 5G SSID. + passphrase_length_5g: Int, length of password for 5G network. + same_ssid: Boolean, determines if both bands on AP use the same SSID. + open_network: Boolean, to check if open network should be configured. + wpa_network: Boolean, to check if wpa network should be configured. + wep_network: Boolean, to check if wep network should be configured. + ent_network: Boolean, to check if ent network should be configured. + ent_network_pwd: Boolean, to check if ent pwd network should be configured. + radius_conf_2g: dictionary with enterprise radius server details. + radius_conf_5g: dictionary with enterprise radius server details. + radius_conf_pwd: dictionary with enterprise radiuse server details. + ap_count: APs to configure. + """ + self.reference_networks = [] + self.wpa_networks = [] + self.wep_networks = [] + self.ent_networks = [] + self.ent_networks_pwd = [] + self.open_network = [] + for _ in range(ap_count): + network_list = [] + if wpa_network: + wpa_dict = self.get_psk_network(mirror_ap, + self.reference_networks, + hidden, + same_ssid, + ssid_length_2g, + ssid_length_5g, + passphrase_length_2g, + passphrase_length_5g) + wpa_dict[hostapd_constants.BAND_2G]["security"] = "psk2" + wpa_dict[hostapd_constants.BAND_5G]["security"] = "psk2" + self.wpa_networks.append(wpa_dict) + network_list.append(wpa_dict) + if wep_network: + wep_dict = self.get_wep_network(mirror_ap, + self.wep_networks, + hidden, + same_ssid, + ssid_length_2g, + ssid_length_5g) + network_list.append(wep_dict) + if ent_network: + ent_dict = self.get_open_network(mirror_ap, + self.ent_networks, + hidden, + same_ssid, + ssid_length_2g, + ssid_length_5g) + ent_dict["2g"]["security"] = "wpa2" + ent_dict["2g"].update(radius_conf_2g) + ent_dict["5g"]["security"] = "wpa2" + ent_dict["5g"].update(radius_conf_5g) + network_list.append(ent_dict) + if ent_network_pwd: + ent_pwd_dict = self.get_open_network(mirror_ap, + self.ent_networks_pwd, + hidden, + same_ssid, + ssid_length_2g, + ssid_length_5g) + ent_pwd_dict["2g"]["security"] = "wpa2" + ent_pwd_dict["2g"].update(radius_conf_pwd) + ent_pwd_dict["5g"]["security"] = "wpa2" + ent_pwd_dict["5g"].update(radius_conf_pwd) + network_list.append(ent_pwd_dict) + if open_network: + open_dict = self.get_open_network(mirror_ap, + self.open_network, + hidden, + same_ssid, + ssid_length_2g, + ssid_length_5g) + network_list.append(open_dict) + self.access_points[_].configure_ap(network_list, + channel_2g, + channel_5g) + self.access_points[_].start_ap() + def legacy_configure_ap_and_start( self, channel_5g=hostapd_constants.AP_DEFAULT_CHANNEL_5G, @@ -316,11 +422,6 @@ class WifiBaseTest(BaseTestClass): ent_network_pwd=False, radius_conf_pwd=None, ap_count=1): - asserts.assert_true( - len(self.user_params["AccessPoint"]) == 2, - "Exactly two access points must be specified. \ - Each access point has 2 radios, one each for 2.4GHZ \ - and 5GHz. A test can choose to use one or both APs.") config_count = 1 count = 0 diff --git a/acts/framework/acts/test_utils/wifi/aware/AwareBaseTest.py b/acts/framework/acts/test_utils/wifi/aware/AwareBaseTest.py index df303ced44..ed85f5b754 100644 --- a/acts/framework/acts/test_utils/wifi/aware/AwareBaseTest.py +++ b/acts/framework/acts/test_utils/wifi/aware/AwareBaseTest.py @@ -32,7 +32,8 @@ class AwareBaseTest(BaseTestClass): device_startup_offset = 2 def setup_test(self): - required_params = ("aware_default_power_mode", ) + required_params = ("aware_default_power_mode", + "dbs_supported_models",) self.unpack_userparams(required_params) for ad in self.android_devices: @@ -40,15 +41,14 @@ class AwareBaseTest(BaseTestClass): not ad.droid.doesDeviceSupportWifiAwareFeature(), "Device under test does not support Wi-Fi Aware - skipping test" ) - wutils.wifi_toggle_state(ad, True) + aware_avail = ad.droid.wifiIsAwareAvailable() ad.droid.wifiP2pClose() + wutils.wifi_toggle_state(ad, True) 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) @@ -58,6 +58,7 @@ class AwareBaseTest(BaseTestClass): # set randomization interval to 0 (disable) to reduce likelihood of # interference in tests autils.configure_mac_random_interval(ad, 0) + ad.ed.clear_all_events() def teardown_test(self): for ad in self.android_devices: 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 2623f9bfcb..e2977999c1 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 @@ -468,6 +468,28 @@ def verify_socket_connect(dut_s, dut_c, ipv6_s, ipv6_c, port): return True +def run_ping6(dut, target_ip, duration=60): + """Run ping test and return the latency result + + Args: + dut: the dut which run the ping cmd + target_ip: target IP Address for ping + duration: the duration time of the ping + + return: dict contains "min/avg/max/mdev" result + """ + cmd = "ping6 -w %d %s" % (duration, target_ip) + ping_result = dut.adb.shell(cmd, timeout=duration + 1) + res = re.match(".*mdev = (\S+) .*", ping_result, re.S) + asserts.assert_true(res, "Cannot reach the IP address %s", target_ip) + title = ["min", "avg", "max", "mdev"] + result = res.group(1).split("/") + latency_result = {} + for i in range(len(title)): + latency_result[title[i]] = result[i] + return latency_result + + ######################################################### # Aware primitives ######################################################### diff --git a/acts/framework/acts/test_utils/wifi/p2p/WifiP2pBaseTest.py b/acts/framework/acts/test_utils/wifi/p2p/WifiP2pBaseTest.py index 7aca3c6ca9..1c5a53f120 100644 --- a/acts/framework/acts/test_utils/wifi/p2p/WifiP2pBaseTest.py +++ b/acts/framework/acts/test_utils/wifi/p2p/WifiP2pBaseTest.py @@ -24,16 +24,32 @@ from acts.base_test import BaseTestClass from acts.test_utils.wifi import wifi_test_utils as wutils from acts.test_utils.wifi.p2p import wifi_p2p_const as p2pconsts +WAIT_TIME = 60 + + class WifiP2pBaseTest(BaseTestClass): def __init__(self, controllers): if not hasattr(self, 'android_devices'): super(WifiP2pBaseTest, self).__init__(controllers) def setup_class(self): + for ad in self.android_devices: + ad.droid.wakeLockAcquireBright() + ad.droid.wakeUpNow() + required_params = () + optional_params = ("skip_read_factory_mac", ) + self.unpack_userparams(required_params, + optional_params, + skip_read_factory_mac=0) + self.dut1 = self.android_devices[0] self.dut2 = self.android_devices[1] - self.dut1_mac = self.get_p2p_mac_address(self.dut1) - self.dut2_mac = self.get_p2p_mac_address(self.dut2) + if self.skip_read_factory_mac: + self.dut1_mac = None + self.dut2_mac = None + else: + self.dut1_mac = self.get_p2p_mac_address(self.dut1) + self.dut2_mac = self.get_p2p_mac_address(self.dut2) #init location before init p2p acts.utils.set_location_service(self.dut1, True) @@ -44,7 +60,7 @@ class WifiP2pBaseTest(BaseTestClass): self.dut1.droid.wifiP2pInitialize() time.sleep(p2pconsts.DEFAULT_FUNCTION_SWITCH_TIME) asserts.assert_true(self.dut1.droid.wifiP2pIsEnabled(), - "DUT1's p2p should be initialized but it didn't") + "DUT1's p2p should be initialized but it didn't") self.dut1.name = "Android_" + self.dut1.serial self.dut1.droid.wifiP2pSetDeviceName(self.dut1.name) wutils.wifi_test_device_init(self.dut2) @@ -52,7 +68,7 @@ class WifiP2pBaseTest(BaseTestClass): self.dut2.droid.wifiP2pInitialize() time.sleep(p2pconsts.DEFAULT_FUNCTION_SWITCH_TIME) asserts.assert_true(self.dut2.droid.wifiP2pIsEnabled(), - "DUT2's p2p should be initialized but it didn't") + "DUT2's p2p should be initialized but it didn't") self.dut2.name = "Android_" + self.dut2.serial self.dut2.droid.wifiP2pSetDeviceName(self.dut2.name) @@ -63,12 +79,12 @@ class WifiP2pBaseTest(BaseTestClass): utils.sync_device_time(self.dut3) self.dut3.droid.wifiP2pInitialize() time.sleep(p2pconsts.DEFAULT_FUNCTION_SWITCH_TIME) - asserts.assert_true(self.dut3.droid.wifiP2pIsEnabled(), - "DUT3's p2p should be initialized but it didn't") + asserts.assert_true( + self.dut3.droid.wifiP2pIsEnabled(), + "DUT3's p2p should be initialized but it didn't") self.dut3.name = "Android_" + self.dut3.serial self.dut3.droid.wifiP2pSetDeviceName(self.dut3.name) - def teardown_class(self): self.dut1.droid.wifiP2pClose() self.dut2.droid.wifiP2pClose() @@ -78,11 +94,12 @@ class WifiP2pBaseTest(BaseTestClass): if len(self.android_devices) > 2: self.dut3.droid.wifiP2pClose() acts.utils.set_location_service(self.dut3, False) + for ad in self.android_devices: + ad.droid.wakeLockRelease() + ad.droid.goToSleepNow() def setup_test(self): for ad in self.android_devices: - ad.droid.wakeLockAcquireBright() - ad.droid.wakeUpNow() ad.ed.clear_all_events() def teardown_test(self): @@ -90,13 +107,11 @@ class WifiP2pBaseTest(BaseTestClass): # Clear p2p group info ad.droid.wifiP2pRequestPersistentGroupInfo() event = ad.ed.pop_event("WifiP2pOnPersistentGroupInfoAvailable", - p2pconsts.DEFAULT_TIMEOUT) + p2pconsts.DEFAULT_TIMEOUT) for network in event['data']: ad.droid.wifiP2pDeletePersistentGroup(network['NetworkId']) # Clear p2p local service ad.droid.wifiP2pClearLocalServices() - ad.droid.wakeLockRelease() - ad.droid.goToSleepNow() def on_fail(self, test_name, begin_time): for ad in self.android_devices: @@ -105,5 +120,7 @@ class WifiP2pBaseTest(BaseTestClass): def get_p2p_mac_address(self, dut): """Gets the current MAC address being used for Wi-Fi Direct.""" + dut.reboot() + time.sleep(WAIT_TIME) out = dut.adb.shell("ifconfig p2p0") return re.match(".* HWaddr (\S+).*", out, re.S).group(1) diff --git a/acts/framework/acts/test_utils/wifi/p2p/wifi_p2p_const.py b/acts/framework/acts/test_utils/wifi/p2p/wifi_p2p_const.py index b50a5d35fc..87f405967e 100644 --- a/acts/framework/acts/test_utils/wifi/p2p/wifi_p2p_const.py +++ b/acts/framework/acts/test_utils/wifi/p2p/wifi_p2p_const.py @@ -28,6 +28,11 @@ DEFAULT_TIMEOUT = 30 DEFAULT_SLEEPTIME = 5 DEFAULT_FUNCTION_SWITCH_TIME = 10 DEFAULT_SERVICE_WAITING_TIME = 20 +DEFAULT_GROUP_CLIENT_LOST_TIME = 60 + +P2P_CONNECT_NEGOTIATION = 0 +P2P_CONNECT_JOIN = 1 +P2P_CONNECT_INVITATION = 2 ###################################################### # Wifi P2p sl4a Event String ###################################################### @@ -40,7 +45,7 @@ ONGOING_PEER_SET_SUCCESS_EVENT = "WifiP2psetP2pPeerConfigureOnSuccess" CONNECT_SUCCESS_EVENT = "WifiP2pConnectOnSuccess" CREATE_GROUP_SUCCESS_EVENT = "WifiP2pCreateGroupOnSuccess" SET_CHANNEL_SUCCESS_EVENT = "WifiP2pSetChannelsOnSuccess" - +GROUP_INFO_AVAILABLE_EVENT = "WifiP2pOnGroupInfoAvailable" ###################################################### # Wifi P2p local service event @@ -60,14 +65,15 @@ UPNP_EVENT_SERVICELIST_KEY = "ServiceList" # Wifi P2p local service type #################################################### P2P_LOCAL_SERVICE_UPNP = 0 -P2P_LOCAL_SERVICE_IPP = 1 -P2P_LOCAL_SERVICE_AFP = 2 +P2P_LOCAL_SERVICE_IPP = 1 +P2P_LOCAL_SERVICE_AFP = 2 ###################################################### # Wifi P2p group capability ###################################################### P2P_GROUP_CAPAB_GROUP_OWNER = 1 + ###################################################### # Wifi P2p UPnP MediaRenderer local service ###################################################### @@ -78,17 +84,19 @@ class UpnpTestData(): uuid = "6859dede-8574-59ab-9332-123456789011" rootdevice = "upnp:rootdevice" + ###################################################### # Wifi P2p Bonjour IPP & AFP local service ###################################################### class IppTestData(): - ippInstanceName = "MyPrinter"; - ippRegistrationType = "_ipp._tcp"; - ippDomainName = "myprinter._ipp._tcp.local."; - ipp_txtRecord = {"txtvers":"1", "pdl": "application/postscript"} + ippInstanceName = "MyPrinter" + ippRegistrationType = "_ipp._tcp" + ippDomainName = "myprinter._ipp._tcp.local." + ipp_txtRecord = {"txtvers": "1", "pdl": "application/postscript"} + class AfpTestData(): - afpInstanceName = "Example"; - afpRegistrationType = "_afpovertcp._tcp"; - afpDomainName = "example._afpovertcp._tcp.local."; + afpInstanceName = "Example" + afpRegistrationType = "_afpovertcp._tcp" + afpDomainName = "example._afpovertcp._tcp.local." afp_txtRecord = {} diff --git a/acts/framework/acts/test_utils/wifi/p2p/wifi_p2p_test_utils.py b/acts/framework/acts/test_utils/wifi/p2p/wifi_p2p_test_utils.py index 21486b07ae..a4456a59bd 100755 --- a/acts/framework/acts/test_utils/wifi/p2p/wifi_p2p_test_utils.py +++ b/acts/framework/acts/test_utils/wifi/p2p/wifi_p2p_test_utils.py @@ -25,6 +25,7 @@ from acts import utils from acts.test_utils.wifi.p2p import wifi_p2p_const as p2pconsts import acts.utils + def is_discovered(event, ad): """Check an Android device exist in WifiP2pOnPeersAvailable event or not. @@ -41,7 +42,8 @@ def is_discovered(event, ad): return True return False -def check_disconnect(ad): + +def check_disconnect(ad, timeout=p2pconsts.DEFAULT_TIMEOUT): """Check an Android device disconnect or not Args: @@ -49,8 +51,7 @@ def check_disconnect(ad): """ ad.droid.wifiP2pRequestConnectionInfo() # wait disconnect event - ad.ed.pop_event(p2pconsts.DISCONNECTED_EVENT, - p2pconsts.DEFAULT_TIMEOUT) + ad.ed.pop_event(p2pconsts.DISCONNECTED_EVENT, timeout) def p2p_disconnect(ad): @@ -63,6 +64,7 @@ def p2p_disconnect(ad): ad.droid.wifiP2pRemoveGroup() check_disconnect(ad) + def p2p_connection_ping_test(ad, target_ip_address): """Let an Android device to start ping target_ip_address @@ -70,10 +72,13 @@ def p2p_connection_ping_test(ad, target_ip_address): ad: The android device target_ip_address: ip address which would like to ping """ - ad.log.debug("Run Ping Test, %s ping %s "% (ad.serial, target_ip_address)) + ad.log.debug("Run Ping Test, %s ping %s " % (ad.serial, target_ip_address)) asserts.assert_true( - acts.utils.adb_shell_ping(ad, count=3, dest_ip=target_ip_address, - timeout=20),"%s ping failed" % (ad.serial)) + acts.utils.adb_shell_ping(ad, + count=6, + dest_ip=target_ip_address, + timeout=20), "%s ping failed" % (ad.serial)) + def is_go(ad): """Check an Android p2p role is Go or not @@ -87,12 +92,12 @@ def is_go(ad): ad.log.debug("is go check") ad.droid.wifiP2pRequestConnectionInfo() ad_connect_info_event = ad.ed.pop_event( - p2pconsts.CONNECTION_INFO_AVAILABLE_EVENT, - p2pconsts.DEFAULT_TIMEOUT) + p2pconsts.CONNECTION_INFO_AVAILABLE_EVENT, p2pconsts.DEFAULT_TIMEOUT) if ad_connect_info_event['data']['isGroupOwner']: return True return False + def p2p_go_ip(ad): """Get GO IP address @@ -104,13 +109,40 @@ def p2p_go_ip(ad): ad.log.debug("p2p go ip") ad.droid.wifiP2pRequestConnectionInfo() ad_connect_info_event = ad.ed.pop_event( - p2pconsts.CONNECTION_INFO_AVAILABLE_EVENT, - p2pconsts.DEFAULT_TIMEOUT) - ad.log.debug("p2p go ip: %s" % ad_connect_info_event['data']['groupOwnerHostAddress']) + p2pconsts.CONNECTION_INFO_AVAILABLE_EVENT, p2pconsts.DEFAULT_TIMEOUT) + ad.log.debug("p2p go ip: %s" % + ad_connect_info_event['data']['groupOwnerHostAddress']) return ad_connect_info_event['data']['groupOwnerHostAddress'] + +def p2p_get_current_group(ad): + """Get current group information + + Args: + ad: The android device + Return: + p2p group information + """ + ad.log.debug("get current group") + ad.droid.wifiP2pRequestGroupInfo() + ad_group_info_event = ad.ed.pop_event(p2pconsts.GROUP_INFO_AVAILABLE_EVENT, + p2pconsts.DEFAULT_TIMEOUT) + ad.log.debug( + "p2p group: SSID:%s, password:%s, owner address: %s, interface: %s" % + (ad_group_info_event['data']['NetworkName'], + ad_group_info_event['data']['Passphrase'], + ad_group_info_event['data']['OwnerAddress'], + ad_group_info_event['data']['Interface'])) + return ad_group_info_event['data'] + + #trigger p2p connect to ad2 from ad1 -def p2p_connect(ad1, ad2, isReconnect, wpsSetup, isJoinExistingGroup=False): +def p2p_connect(ad1, + ad2, + isReconnect, + wpsSetup, + p2p_connect_type=p2pconsts.P2P_CONNECT_NEGOTIATION, + go_ad=None): """trigger p2p connect to ad2 from ad1 Args: @@ -119,70 +151,86 @@ def p2p_connect(ad1, ad2, isReconnect, wpsSetup, isJoinExistingGroup=False): isReconnect: boolean, if persist group is exist, isReconnect is true, otherswise is false. wpsSetup: which wps connection would like to use + p2p_connect_type: enumeration, which type this p2p connection is + go_ad: The group owner android device which is used for the invitation connection """ - ad1.log.info("Create p2p connection from %s to %s via wps: %s" % - (ad1.name, ad2.name, wpsSetup)) - if isJoinExistingGroup: + ad1.log.info("Create p2p connection from %s to %s via wps: %s type %d" % + (ad1.name, ad2.name, wpsSetup, p2p_connect_type)) + if p2p_connect_type == p2pconsts.P2P_CONNECT_INVITATION: + if go_ad is None: + go_ad = ad1 + find_p2p_device(ad1, ad2) + find_p2p_group_owner(ad2, go_ad) + elif p2p_connect_type == p2pconsts.P2P_CONNECT_JOIN: find_p2p_group_owner(ad1, ad2) else: find_p2p_device(ad1, ad2) time.sleep(p2pconsts.DEFAULT_SLEEPTIME) - wifi_p2p_config = {WifiP2PEnums.WifiP2pConfig.DEVICEADDRESS_KEY: - ad2.deviceAddress, WifiP2PEnums.WifiP2pConfig.WPSINFO_KEY: - {WifiP2PEnums.WpsInfo.WPS_SETUP_KEY: wpsSetup}} + wifi_p2p_config = { + WifiP2PEnums.WifiP2pConfig.DEVICEADDRESS_KEY: ad2.deviceAddress, + WifiP2PEnums.WifiP2pConfig.WPSINFO_KEY: { + WifiP2PEnums.WpsInfo.WPS_SETUP_KEY: wpsSetup + } + } ad1.droid.wifiP2pConnect(wifi_p2p_config) ad1.ed.pop_event(p2pconsts.CONNECT_SUCCESS_EVENT, - p2pconsts.DEFAULT_TIMEOUT) + p2pconsts.DEFAULT_TIMEOUT) time.sleep(p2pconsts.DEFAULT_SLEEPTIME) if not isReconnect: ad1.droid.requestP2pPeerConfigure() ad1_peerConfig = ad1.ed.pop_event( - p2pconsts.ONGOING_PEER_INFO_AVAILABLE_EVENT, - p2pconsts.DEFAULT_TIMEOUT) + p2pconsts.ONGOING_PEER_INFO_AVAILABLE_EVENT, + p2pconsts.DEFAULT_TIMEOUT) ad1.log.debug(ad1_peerConfig['data']) ad2.droid.requestP2pPeerConfigure() ad2_peerConfig = ad2.ed.pop_event( - p2pconsts.ONGOING_PEER_INFO_AVAILABLE_EVENT, - p2pconsts.DEFAULT_TIMEOUT) + p2pconsts.ONGOING_PEER_INFO_AVAILABLE_EVENT, + p2pconsts.DEFAULT_TIMEOUT) ad2.log.debug(ad2_peerConfig['data']) if wpsSetup == WifiP2PEnums.WpsInfo.WIFI_WPS_INFO_DISPLAY: - asserts.assert_true(WifiP2PEnums.WpsInfo.WPS_PIN_KEY - in ad1_peerConfig['data'][ - WifiP2PEnums.WifiP2pConfig.WPSINFO_KEY], - "Can't get pin value"); - ad2_peerConfig['data'][WifiP2PEnums.WifiP2pConfig.WPSINFO_KEY][ - WifiP2PEnums.WpsInfo.WPS_PIN_KEY] = ad1_peerConfig[ - 'data'][WifiP2PEnums.WifiP2pConfig.WPSINFO_KEY][ - WifiP2PEnums.WpsInfo.WPS_PIN_KEY] - ad2.droid.setP2pPeerConfigure(ad2_peerConfig['data']) - ad2.ed.pop_event(p2pconsts.ONGOING_PEER_SET_SUCCESS_EVENT, - p2pconsts.DEFAULT_TIMEOUT); - ad2.droid.wifiP2pAcceptConnection() + asserts.assert_true( + WifiP2PEnums.WpsInfo.WPS_PIN_KEY in ad1_peerConfig['data'][ + WifiP2PEnums.WifiP2pConfig.WPSINFO_KEY], + "Can't get pin value") + ad2_peerConfig['data'][WifiP2PEnums.WifiP2pConfig.WPSINFO_KEY][ + WifiP2PEnums.WpsInfo.WPS_PIN_KEY] = ad1_peerConfig['data'][ + WifiP2PEnums.WifiP2pConfig.WPSINFO_KEY][ + WifiP2PEnums.WpsInfo.WPS_PIN_KEY] + ad2.droid.setP2pPeerConfigure(ad2_peerConfig['data']) + ad2.ed.pop_event(p2pconsts.ONGOING_PEER_SET_SUCCESS_EVENT, + p2pconsts.DEFAULT_TIMEOUT) + ad2.droid.wifiP2pAcceptConnection() elif wpsSetup == WifiP2PEnums.WpsInfo.WIFI_WPS_INFO_KEYPAD: - asserts.assert_true( WifiP2PEnums.WpsInfo.WPS_PIN_KEY - in ad2_peerConfig['data'][ - WifiP2PEnums.WifiP2pConfig.WPSINFO_KEY], - "Can't get pin value"); - ad1_peerConfig['data'][WifiP2PEnums.WifiP2pConfig.WPSINFO_KEY][ - WifiP2PEnums.WpsInfo.WPS_PIN_KEY] = ad2_peerConfig[ - 'data'][WifiP2PEnums.WifiP2pConfig.WPSINFO_KEY][ - WifiP2PEnums.WpsInfo.WPS_PIN_KEY] - ad1.droid.setP2pPeerConfigure(ad1_peerConfig['data']) - ad1.ed.pop_event(p2pconsts.ONGOING_PEER_SET_SUCCESS_EVENT, - p2pconsts.DEFAULT_TIMEOUT) - #Need to Accpet first in ad1 to avoid connect time out in ad2, - #the timeout just 1 sec in ad2 - ad1.droid.wifiP2pAcceptConnection() - time.sleep(p2pconsts.DEFAULT_SLEEPTIME) - ad2.droid.wifiP2pConfirmConnection() + asserts.assert_true( + WifiP2PEnums.WpsInfo.WPS_PIN_KEY in ad2_peerConfig['data'][ + WifiP2PEnums.WifiP2pConfig.WPSINFO_KEY], + "Can't get pin value") + ad1_peerConfig['data'][WifiP2PEnums.WifiP2pConfig.WPSINFO_KEY][ + WifiP2PEnums.WpsInfo.WPS_PIN_KEY] = ad2_peerConfig['data'][ + WifiP2PEnums.WifiP2pConfig.WPSINFO_KEY][ + WifiP2PEnums.WpsInfo.WPS_PIN_KEY] + ad1.droid.setP2pPeerConfigure(ad1_peerConfig['data']) + ad1.ed.pop_event(p2pconsts.ONGOING_PEER_SET_SUCCESS_EVENT, + p2pconsts.DEFAULT_TIMEOUT) + #Need to Accept first in ad1 to avoid connect time out in ad2, + #the timeout just 1 sec in ad2 + ad1.droid.wifiP2pAcceptConnection() + time.sleep(p2pconsts.DEFAULT_SLEEPTIME) + ad2.droid.wifiP2pConfirmConnection() elif wpsSetup == WifiP2PEnums.WpsInfo.WIFI_WPS_INFO_PBC: - ad2.droid.wifiP2pAcceptConnection() + ad2.droid.wifiP2pAcceptConnection() + if p2p_connect_type == p2pconsts.P2P_CONNECT_INVITATION: + time.sleep(p2pconsts.DEFAULT_SLEEPTIME) + go_ad.droid.wifiP2pAcceptConnection() #wait connected event - ad1.ed.pop_event(p2pconsts.CONNECTED_EVENT, - p2pconsts.DEFAULT_TIMEOUT) - ad2.ed.pop_event(p2pconsts.CONNECTED_EVENT, - p2pconsts.DEFAULT_TIMEOUT) + if p2p_connect_type == p2pconsts.P2P_CONNECT_INVITATION: + go_ad.ed.pop_event(p2pconsts.CONNECTED_EVENT, + p2pconsts.DEFAULT_TIMEOUT) + else: + ad1.ed.pop_event(p2pconsts.CONNECTED_EVENT, p2pconsts.DEFAULT_TIMEOUT) + ad2.ed.pop_event(p2pconsts.CONNECTED_EVENT, p2pconsts.DEFAULT_TIMEOUT) + def p2p_connect_with_config(ad1, ad2, network_name, passphrase, band): """trigger p2p connect to ad2 from ad1 with config @@ -194,28 +242,27 @@ def p2p_connect_with_config(ad1, ad2, network_name, passphrase, band): passphrase: the passphrase of the desired group. band: the operating band of the desired group. """ - ad1.log.info("Create p2p connection from %s to %s" % - (ad1.name, ad2.name)) + ad1.log.info("Create p2p connection from %s to %s" % (ad1.name, ad2.name)) find_p2p_device(ad1, ad2) time.sleep(p2pconsts.DEFAULT_SLEEPTIME) wifi_p2p_config = { - WifiP2PEnums.WifiP2pConfig.NETWORK_NAME: network_name, - WifiP2PEnums.WifiP2pConfig.PASSPHRASE: passphrase, - WifiP2PEnums.WifiP2pConfig.GROUP_BAND: band, - WifiP2PEnums.WifiP2pConfig.WPSINFO_KEY: { - WifiP2PEnums.WpsInfo.WPS_SETUP_KEY: WifiP2PEnums.WpsInfo.WIFI_WPS_INFO_PBC - } + WifiP2PEnums.WifiP2pConfig.NETWORK_NAME: network_name, + WifiP2PEnums.WifiP2pConfig.PASSPHRASE: passphrase, + WifiP2PEnums.WifiP2pConfig.GROUP_BAND: band, + WifiP2PEnums.WifiP2pConfig.WPSINFO_KEY: { + WifiP2PEnums.WpsInfo.WPS_SETUP_KEY: + WifiP2PEnums.WpsInfo.WIFI_WPS_INFO_PBC + } } ad1.droid.wifiP2pConnect(wifi_p2p_config) ad1.ed.pop_event(p2pconsts.CONNECT_SUCCESS_EVENT, - p2pconsts.DEFAULT_TIMEOUT) + p2pconsts.DEFAULT_TIMEOUT) time.sleep(p2pconsts.DEFAULT_SLEEPTIME) #wait connected event - ad1.ed.pop_event(p2pconsts.CONNECTED_EVENT, - p2pconsts.DEFAULT_TIMEOUT) - ad2.ed.pop_event(p2pconsts.CONNECTED_EVENT, - p2pconsts.DEFAULT_TIMEOUT) + ad1.ed.pop_event(p2pconsts.CONNECTED_EVENT, p2pconsts.DEFAULT_TIMEOUT) + ad2.ed.pop_event(p2pconsts.CONNECTED_EVENT, p2pconsts.DEFAULT_TIMEOUT) + def find_p2p_device(ad1, ad2): """Check an Android device ad1 can discover an Android device ad2 @@ -227,13 +274,14 @@ def find_p2p_device(ad1, ad2): ad1.droid.wifiP2pDiscoverPeers() ad2.droid.wifiP2pDiscoverPeers() p2p_find_result = False - while not p2p_find_result: + while not p2p_find_result: ad1_event = ad1.ed.pop_event(p2pconsts.PEER_AVAILABLE_EVENT, - p2pconsts.P2P_FIND_TIMEOUT) + p2pconsts.P2P_FIND_TIMEOUT) ad1.log.debug(ad1_event['data']) p2p_find_result = is_discovered(ad1_event, ad2) asserts.assert_true(p2p_find_result, - "DUT didn't discovered peer:%s device"% (ad2.name)) + "DUT didn't discovered peer:%s device" % (ad2.name)) + def find_p2p_group_owner(ad1, ad2): """Check an Android device ad1 can discover an Android device ad2 which @@ -243,21 +291,23 @@ def find_p2p_group_owner(ad1, ad2): ad1: The android device ad2: The android device which is a group owner """ - ad2.droid.wifiP2pStopPeerDiscovery(); + ad2.droid.wifiP2pStopPeerDiscovery() time.sleep(p2pconsts.DEFAULT_FUNCTION_SWITCH_TIME) ad1.droid.wifiP2pDiscoverPeers() p2p_find_result = False while not p2p_find_result: ad1_event = ad1.ed.pop_event(p2pconsts.PEER_AVAILABLE_EVENT, - p2pconsts.P2P_FIND_TIMEOUT) + p2pconsts.P2P_FIND_TIMEOUT) ad1.log.debug(ad1_event['data']) for device in ad1_event['data']['Peers']: - if (device['Name'] == ad2.name and - int(device['GroupCapability']) & p2pconsts.P2P_GROUP_CAPAB_GROUP_OWNER): + if (device['Name'] == ad2.name and int(device['GroupCapability']) + & p2pconsts.P2P_GROUP_CAPAB_GROUP_OWNER): ad2.deviceAddress = device['Address'] p2p_find_result = True - asserts.assert_true(p2p_find_result, - "DUT didn't discovered group owner peer:%s device"% (ad2.name)) + asserts.assert_true( + p2p_find_result, + "DUT didn't discovered group owner peer:%s device" % (ad2.name)) + def createP2pLocalService(ad, serviceCategory): """Based on serviceCategory to create p2p local service @@ -270,15 +320,16 @@ def createP2pLocalService(ad, serviceCategory): testData = genTestData(serviceCategory) if serviceCategory == p2pconsts.P2P_LOCAL_SERVICE_UPNP: ad.droid.wifiP2pCreateUpnpServiceInfo(testData[0], testData[1], - testData[2]) - elif (serviceCategory == p2pconsts.P2P_LOCAL_SERVICE_IPP or - serviceCategory == p2pconsts.P2P_LOCAL_SERVICE_AFP): + testData[2]) + elif (serviceCategory == p2pconsts.P2P_LOCAL_SERVICE_IPP + or serviceCategory == p2pconsts.P2P_LOCAL_SERVICE_AFP): ad.droid.wifiP2pCreateBonjourServiceInfo(testData[0], testData[1], - testData[2]) + testData[2]) ad.droid.wifiP2pAddLocalService() + def requestServiceAndCheckResult(ad_serviceProvider, ad_serviceReceiver, - serviceType, queryString1, queryString2): + serviceType, queryString1, queryString2): """Based on serviceType and query info, check service request result same as expect or not on an Android device ad_serviceReceiver. And remove p2p service request after result check. @@ -292,8 +343,8 @@ def requestServiceAndCheckResult(ad_serviceProvider, ad_serviceReceiver, """ expectData = genExpectTestData(serviceType, queryString1, queryString2) find_p2p_device(ad_serviceReceiver, ad_serviceProvider) - ad_serviceReceiver.droid.wifiP2pStopPeerDiscovery(); - ad_serviceReceiver.droid.wifiP2pClearServiceRequests(); + ad_serviceReceiver.droid.wifiP2pStopPeerDiscovery() + ad_serviceReceiver.droid.wifiP2pClearServiceRequests() time.sleep(p2pconsts.DEFAULT_FUNCTION_SWITCH_TIME) ad_serviceReceiver.droid.wifiP2pDiscoverServices() @@ -301,18 +352,19 @@ def requestServiceAndCheckResult(ad_serviceProvider, ad_serviceReceiver, service_id = 0 if (serviceType == WifiP2PEnums.WifiP2pServiceInfo.WIFI_P2P_SERVICE_TYPE_BONJOUR): - ad_serviceReceiver.log.info("Request bonjour service in \ + ad_serviceReceiver.log.info( + "Request bonjour service in \ %s with Query String %s and %s " % - (ad_serviceReceiver.name, queryString1, queryString2)) + (ad_serviceReceiver.name, queryString1, queryString2)) ad_serviceReceiver.log.info("expectData %s" % expectData) if queryString1 != None: service_id = ad_serviceReceiver.droid.wifiP2pAddDnssdServiceRequest( - queryString1,queryString2) + queryString1, queryString2) else: service_id = ad_serviceReceiver.droid.wifiP2pAddServiceRequest( - serviceType) + serviceType) ad_serviceReceiver.log.info("request bonjour service id %s" % - service_id) + service_id) ad_serviceReceiver.droid.wifiP2pSetDnsSdResponseListeners() ad_serviceReceiver.droid.wifiP2pDiscoverServices() ad_serviceReceiver.log.info("Check Service Listener") @@ -320,45 +372,47 @@ def requestServiceAndCheckResult(ad_serviceProvider, ad_serviceReceiver, try: dnssd_events = ad_serviceReceiver.ed.pop_all(p2pconsts.DNSSD_EVENT) dnssd_txrecord_events = ad_serviceReceiver.ed.pop_all( - p2pconsts.DNSSD_TXRECORD_EVENT) + p2pconsts.DNSSD_TXRECORD_EVENT) dns_service = WifiP2PEnums.WifiP2pDnsSdServiceResponse() for dnssd_event in dnssd_events: - if dnssd_event['data']['SourceDeviceAddress' - ] == ad_serviceProvider.deviceAddress: + if dnssd_event['data'][ + 'SourceDeviceAddress'] == ad_serviceProvider.deviceAddress: dns_service.InstanceName = dnssd_event['data'][ - p2pconsts.DNSSD_EVENT_INSTANCENAME_KEY] + p2pconsts.DNSSD_EVENT_INSTANCENAME_KEY] dns_service.RegistrationType = dnssd_event['data'][ - p2pconsts.DNSSD_EVENT_REGISTRATIONTYPE_KEY] + p2pconsts.DNSSD_EVENT_REGISTRATIONTYPE_KEY] dns_service.FullDomainName = "" dns_service.TxtRecordMap = "" serviceData[dns_service.toString()] = 1 for dnssd_txrecord_event in dnssd_txrecord_events: - if dnssd_txrecord_event['data']['SourceDeviceAddress' - ] == ad_serviceProvider.deviceAddress: + if dnssd_txrecord_event['data'][ + 'SourceDeviceAddress'] == ad_serviceProvider.deviceAddress: dns_service.InstanceName = "" dns_service.RegistrationType = "" dns_service.FullDomainName = dnssd_txrecord_event['data'][ - p2pconsts.DNSSD_TXRECORD_EVENT_FULLDOMAINNAME_KEY] + p2pconsts.DNSSD_TXRECORD_EVENT_FULLDOMAINNAME_KEY] dns_service.TxtRecordMap = dnssd_txrecord_event['data'][ - p2pconsts.DNSSD_TXRECORD_EVENT_TXRECORDMAP_KEY] + p2pconsts.DNSSD_TXRECORD_EVENT_TXRECORDMAP_KEY] serviceData[dns_service.toString()] = 1 ad_serviceReceiver.log.info("serviceData %s" % serviceData) if len(serviceData) == 0: - ad_serviceReceiver.droid.wifiP2pRemoveServiceRequest(service_id) - return -1; + ad_serviceReceiver.droid.wifiP2pRemoveServiceRequest( + service_id) + return -1 except queue.Empty as error: - ad_serviceReceiver.log.info("dnssd event is empty",) + ad_serviceReceiver.log.info("dnssd event is empty", ) elif (serviceType == - WifiP2PEnums.WifiP2pServiceInfo.WIFI_P2P_SERVICE_TYPE_UPNP): - ad_serviceReceiver.log.info("Request upnp service in %s with Query String %s "% - (ad_serviceReceiver.name, queryString1)) + WifiP2PEnums.WifiP2pServiceInfo.WIFI_P2P_SERVICE_TYPE_UPNP): + ad_serviceReceiver.log.info( + "Request upnp service in %s with Query String %s " % + (ad_serviceReceiver.name, queryString1)) ad_serviceReceiver.log.info("expectData %s" % expectData) if queryString1 != None: service_id = ad_serviceReceiver.droid.wifiP2pAddUpnpServiceRequest( - queryString1) + queryString1) else: service_id = ad_serviceReceiver.droid.wifiP2pAddServiceRequest( - WifiP2PEnums.WifiP2pServiceInfo.WIFI_P2P_SERVICE_TYPE_UPNP) + WifiP2PEnums.WifiP2pServiceInfo.WIFI_P2P_SERVICE_TYPE_UPNP) ad_serviceReceiver.droid.wifiP2pSetUpnpResponseListeners() ad_serviceReceiver.droid.wifiP2pDiscoverServices() ad_serviceReceiver.log.info("Check Service Listener") @@ -366,27 +420,33 @@ def requestServiceAndCheckResult(ad_serviceProvider, ad_serviceReceiver, try: upnp_events = ad_serviceReceiver.ed.pop_all(p2pconsts.UPNP_EVENT) for upnp_event in upnp_events: - if upnp_event['data']['Device']['Address' - ] == ad_serviceProvider.deviceAddress: + if upnp_event['data']['Device'][ + 'Address'] == ad_serviceProvider.deviceAddress: for service in upnp_event['data'][ p2pconsts.UPNP_EVENT_SERVICELIST_KEY]: serviceData[service] = 1 ad_serviceReceiver.log.info("serviceData %s" % serviceData) if len(serviceData) == 0: - ad_serviceReceiver.droid.wifiP2pRemoveServiceRequest(service_id) - return -1; + ad_serviceReceiver.droid.wifiP2pRemoveServiceRequest( + service_id) + return -1 except queue.Empty as error: - ad_serviceReceiver.log.info("p2p upnp event is empty",) + ad_serviceReceiver.log.info("p2p upnp event is empty", ) ad_serviceReceiver.log.info("Check ServiceList") - asserts.assert_true(checkServiceQueryResult(serviceData,expectData), - "ServiceList not same as Expect"); + asserts.assert_true(checkServiceQueryResult(serviceData, expectData), + "ServiceList not same as Expect") # After service checked, remove the service_id ad_serviceReceiver.droid.wifiP2pRemoveServiceRequest(service_id) return 0 -def requestServiceAndCheckResultWithRetry(ad_serviceProvider, ad_serviceReceiver, - serviceType, queryString1, queryString2, retryCount=3): + +def requestServiceAndCheckResultWithRetry(ad_serviceProvider, + ad_serviceReceiver, + serviceType, + queryString1, + queryString2, + retryCount=3): """ allow failures for requestServiceAndCheckResult. Service discovery might fail unexpectedly because the request packet might not be recevied by the service responder due to p2p state switch. @@ -401,14 +461,16 @@ def requestServiceAndCheckResultWithRetry(ad_serviceProvider, ad_serviceReceiver """ ret = 0 while retryCount > 0: - ret = requestServiceAndCheckResult(ad_serviceProvider, ad_serviceReceiver, - serviceType, queryString1, queryString2) + ret = requestServiceAndCheckResult(ad_serviceProvider, + ad_serviceReceiver, serviceType, + queryString1, queryString2) if (ret == 0): break retryCount -= 1 asserts.assert_equal(0, ret, "cannot find any services with retries.") + def checkServiceQueryResult(serviceList, expectServiceList): """Check serviceList same as expectServiceList or not @@ -427,6 +489,7 @@ def checkServiceQueryResult(serviceList, expectServiceList): del tempExpectServiceList[service] return len(tempExpectServiceList) == 0 and len(tempServiceList) == 0 + def genTestData(serviceCategory): """Based on serviceCategory to generator Test Data @@ -439,8 +502,10 @@ def genTestData(serviceCategory): if serviceCategory == p2pconsts.P2P_LOCAL_SERVICE_UPNP: testData.append(p2pconsts.UpnpTestData.uuid) testData.append(p2pconsts.UpnpTestData.serviceType) - testData.append([p2pconsts.UpnpTestData.AVTransport, - p2pconsts.UpnpTestData.ConnectionManager]) + testData.append([ + p2pconsts.UpnpTestData.AVTransport, + p2pconsts.UpnpTestData.ConnectionManager + ]) elif serviceCategory == p2pconsts.P2P_LOCAL_SERVICE_IPP: testData.append(p2pconsts.IppTestData.ippInstanceName) testData.append(p2pconsts.IppTestData.ippRegistrationType) @@ -452,6 +517,7 @@ def genTestData(serviceCategory): return testData + def genExpectTestData(serviceType, queryString1, queryString2): """Based on serviceCategory to generator expect serviceList @@ -477,7 +543,7 @@ def genExpectTestData(serviceType, queryString1, queryString2): return expectServiceList ipp_service.InstanceName = p2pconsts.IppTestData.ippInstanceName ipp_service.RegistrationType = ( - p2pconsts.IppTestData.ippRegistrationType + ".local.") + p2pconsts.IppTestData.ippRegistrationType + ".local.") ipp_service.FullDomainName = "" ipp_service.TxtRecordMap = "" expectServiceList[ipp_service.toString()] = 1 @@ -492,7 +558,7 @@ def genExpectTestData(serviceType, queryString1, queryString2): return expectServiceList ipp_service.InstanceName = p2pconsts.IppTestData.ippInstanceName ipp_service.RegistrationType = ( - p2pconsts.IppTestData.ippRegistrationType + ".local.") + p2pconsts.IppTestData.ippRegistrationType + ".local.") ipp_service.FullDomainName = "" ipp_service.TxtRecordMap = "" expectServiceList[ipp_service.toString()] = 1 @@ -505,7 +571,7 @@ def genExpectTestData(serviceType, queryString1, queryString2): afp_service.InstanceName = p2pconsts.AfpTestData.afpInstanceName afp_service.RegistrationType = ( - p2pconsts.AfpTestData.afpRegistrationType + ".local.") + p2pconsts.AfpTestData.afpRegistrationType + ".local.") afp_service.FullDomainName = "" afp_service.TxtRecordMap = "" expectServiceList[afp_service.toString()] = 1 @@ -519,23 +585,24 @@ def genExpectTestData(serviceType, queryString1, queryString2): return expectServiceList elif serviceType == WifiP2PEnums.WifiP2pServiceInfo.WIFI_P2P_SERVICE_TYPE_UPNP: upnp_service = "uuid:" + p2pconsts.UpnpTestData.uuid + "::" + ( - p2pconsts.UpnpTestData.rootdevice) + p2pconsts.UpnpTestData.rootdevice) expectServiceList[upnp_service] = 1 if queryString1 != "upnp:rootdevice": upnp_service = "uuid:" + p2pconsts.UpnpTestData.uuid + ( - "::" + p2pconsts.UpnpTestData.AVTransport) + "::" + p2pconsts.UpnpTestData.AVTransport) expectServiceList[upnp_service] = 1 upnp_service = "uuid:" + p2pconsts.UpnpTestData.uuid + ( - "::" + p2pconsts.UpnpTestData.ConnectionManager) + "::" + p2pconsts.UpnpTestData.ConnectionManager) expectServiceList[upnp_service] = 1 upnp_service = "uuid:" + p2pconsts.UpnpTestData.uuid + ( - "::" + p2pconsts.UpnpTestData.serviceType) + "::" + p2pconsts.UpnpTestData.serviceType) expectServiceList[upnp_service] = 1 - upnp_service = "uuid:"+p2pconsts.UpnpTestData.uuid + upnp_service = "uuid:" + p2pconsts.UpnpTestData.uuid expectServiceList[upnp_service] = 1 return expectServiceList + def p2p_create_group(ad): """Create a group as Group Owner @@ -544,9 +611,10 @@ def p2p_create_group(ad): """ ad.droid.wifiP2pCreateGroup() ad.ed.pop_event(p2pconsts.CREATE_GROUP_SUCCESS_EVENT, - p2pconsts.DEFAULT_TIMEOUT) + p2pconsts.DEFAULT_TIMEOUT) time.sleep(p2pconsts.DEFAULT_SLEEPTIME) + def p2p_create_group_with_config(ad, network_name, passphrase, band): """Create a group as Group Owner @@ -554,19 +622,22 @@ def p2p_create_group_with_config(ad, network_name, passphrase, band): ad: The android device """ wifi_p2p_config = { - WifiP2PEnums.WifiP2pConfig.NETWORK_NAME: network_name, - WifiP2PEnums.WifiP2pConfig.PASSPHRASE: passphrase, - WifiP2PEnums.WifiP2pConfig.GROUP_BAND: band, - WifiP2PEnums.WifiP2pConfig.WPSINFO_KEY: { - WifiP2PEnums.WpsInfo.WPS_SETUP_KEY: WifiP2PEnums.WpsInfo.WIFI_WPS_INFO_PBC - } + WifiP2PEnums.WifiP2pConfig.NETWORK_NAME: network_name, + WifiP2PEnums.WifiP2pConfig.PASSPHRASE: passphrase, + WifiP2PEnums.WifiP2pConfig.GROUP_BAND: band, + WifiP2PEnums.WifiP2pConfig.WPSINFO_KEY: { + WifiP2PEnums.WpsInfo.WPS_SETUP_KEY: + WifiP2PEnums.WpsInfo.WIFI_WPS_INFO_PBC + } } ad.droid.wifiP2pCreateGroupWithConfig(wifi_p2p_config) ad.ed.pop_event(p2pconsts.CREATE_GROUP_SUCCESS_EVENT, - p2pconsts.DEFAULT_TIMEOUT) + p2pconsts.DEFAULT_TIMEOUT) time.sleep(p2pconsts.DEFAULT_SLEEPTIME) -def wifi_p2p_set_channels_for_current_group(ad, listening_chan, operating_chan): + +def wifi_p2p_set_channels_for_current_group(ad, listening_chan, + operating_chan): """Sets the listening channel and operating channel of the current group created with initialize. @@ -579,8 +650,8 @@ def wifi_p2p_set_channels_for_current_group(ad, listening_chan, operating_chan): ad.ed.pop_event(p2pconsts.SET_CHANNEL_SUCCESS_EVENT, p2pconsts.DEFAULT_TIMEOUT) -class WifiP2PEnums(): +class WifiP2PEnums(): class WifiP2pConfig(): DEVICEADDRESS_KEY = "deviceAddress" WPSINFO_KEY = "wpsInfo" @@ -612,12 +683,12 @@ class WifiP2PEnums(): class WifiP2pDnsSdServiceResponse(): def __init__(self): pass + InstanceName = "" RegistrationType = "" FullDomainName = "" TxtRecordMap = {} + def toString(self): return self.InstanceName + self.RegistrationType + ( - self.FullDomainName + str(self.TxtRecordMap)) - - + self.FullDomainName + str(self.TxtRecordMap)) diff --git a/acts/framework/acts/test_utils/wifi/wifi_constants.py b/acts/framework/acts/test_utils/wifi/wifi_constants.py index 21f13d2fc1..3a4990571c 100644 --- a/acts/framework/acts/test_utils/wifi/wifi_constants.py +++ b/acts/framework/acts/test_utils/wifi/wifi_constants.py @@ -37,18 +37,37 @@ SOFTAP_CALLBACK_EVENT = "WifiManagerSoftApCallback-" # Callback Event for softap state change # WifiManagerSoftApCallback-[callbackId]-OnStateChanged SOFTAP_STATE_CHANGED = "-OnStateChanged" -# Cllback Event for client number change: -# WifiManagerSoftApCallback-[callbackId]-OnNumClientsChanged -SOFTAP_NUMBER_CLIENTS_CHANGED = "-OnNumClientsChanged" -SOFTAP_NUMBER_CLIENTS_CALLBACK_KEY = "NumClients" SOFTAP_STATE_CHANGE_CALLBACK_KEY = "State" WIFI_AP_DISABLING_STATE = 10 WIFI_AP_DISABLED_STATE = 11 WIFI_AP_ENABLING_STATE = 12 WIFI_AP_ENABLED_STATE = 13 WIFI_AP_FAILED_STATE = 14 -DEFAULT_SOFTAP_TIMEOUT_S = 600 # 10 minutes +# Callback Event for client number change: +# WifiManagerSoftApCallback-[callbackId]-OnNumClientsChanged +SOFTAP_NUMBER_CLIENTS_CHANGED = "-OnNumClientsChanged" +SOFTAP_NUMBER_CLIENTS_CALLBACK_KEY = "NumClients" +SOFTAP_CLIENTS_MACS_CALLBACK_KEY = "MacAddresses" +# Callback Event for softap info change +SOFTAP_INFO_CHANGED = "-OnInfoChanged" +SOFTAP_INFO_FREQUENCY_CALLBACK_KEY = "frequency" +SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY = "bandwidth" +# Callback Event for softap client blocking +SOFTAP_BLOCKING_CLIENT_CONNECTING = "-OnBlockedClientConnecting" +SOFTAP_BLOCKING_CLIENT_REASON_KEY = "BlockedReason" +SOFTAP_BLOCKING_CLIENT_WIFICLIENT_KEY = "WifiClient" +SAP_CLIENT_BLOCK_REASON_CODE_BLOCKED_BY_USER = 0 +SAP_CLIENT_BLOCK_REASON_CODE_NO_MORE_STAS = 1 + +# Callback Event for softap capability +SOFTAP_CAPABILITY_CHANGED = "-OnCapabilityChanged" +SOFTAP_CAPABILITY_MAX_SUPPORTED_CLIENTS = "maxSupportedClients" +SOFTAP_CAPABILITY_FEATURE_ACS = "acsOffloadSupported" +SOFTAP_CAPABILITY_FEATURE_CLIENT_CONTROL = "clientForceDisconnectSupported" +SOFTAP_CAPABILITY_FEATURE_WPA3_SAE = "wpa3SaeSupported" + +DEFAULT_SOFTAP_TIMEOUT_S = 600 # 10 minutes # AP related constants AP_MAIN = "main_AP" diff --git a/acts/framework/acts/test_utils/wifi/wifi_performance_test_utils.py b/acts/framework/acts/test_utils/wifi/wifi_performance_test_utils.py index 39896bc1f5..324d9db0cd 100644 --- a/acts/framework/acts/test_utils/wifi/wifi_performance_test_utils.py +++ b/acts/framework/acts/test_utils/wifi/wifi_performance_test_utils.py @@ -84,7 +84,8 @@ class LinkLayerStats(): def update_stats(self): if self.llstats_enabled: try: - llstats_output = self.dut.adb.shell(self.LLSTATS_CMD, timeout=0.1) + llstats_output = self.dut.adb.shell(self.LLSTATS_CMD, + timeout=0.1) except: llstats_output = '' else: @@ -682,12 +683,53 @@ def get_ping_stats_nb(src_device, dest_address, ping_duration, ping_interval, ping_interval, ping_size) +# Iperf utilities @nonblocking def start_iperf_client_nb(iperf_client, iperf_server_address, iperf_args, tag, timeout): return iperf_client.start(iperf_server_address, iperf_args, tag, timeout) +def get_iperf_arg_string(duration, + reverse_direction, + interval=1, + traffic_type='TCP', + socket_size=None, + num_processes=1, + udp_throughput='1000M', + ipv6=False): + """Function to format iperf client arguments. + + This function takes in iperf client parameters and returns a properly + formatter iperf arg string to be used in throughput tests. + + Args: + duration: iperf duration in seconds + reverse_direction: boolean controlling the -R flag for iperf clients + interval: iperf print interval + traffic_type: string specifying TCP or UDP traffic + socket_size: string specifying TCP window or socket buffer, e.g., 2M + num_processes: int specifying number of iperf processes + udp_throughput: string specifying TX throughput in UDP tests, e.g. 100M + ipv6: boolean controlling the use of IP V6 + Returns: + iperf_args: string of formatted iperf args + """ + iperf_args = '-i {} -t {} -J '.format(interval, duration) + if ipv6: + iperf_args = iperf_args + '-6 ' + if traffic_type.upper() == 'UDP': + iperf_args = iperf_args + '-u -b {} -l 1400 -P {} '.format( + udp_throughput, num_processes) + elif traffic_type.upper() == 'TCP': + iperf_args = iperf_args + '-P {} '.format(num_processes) + if socket_size: + iperf_args = iperf_args + '-w {} '.format(socket_size) + if reverse_direction: + iperf_args = iperf_args + ' -R' + return iperf_args + + # Rssi Utilities def empty_rssi_result(): return collections.OrderedDict([('data', []), ('mean', None), @@ -699,7 +741,8 @@ def get_connected_rssi(dut, polling_frequency=SHORT_SLEEP, first_measurement_delay=0, disconnect_warning=True, - ignore_samples=0): + ignore_samples=0, + interface=None): """Gets all RSSI values reported for the connected access point/BSSID. Args: @@ -716,7 +759,7 @@ def get_connected_rssi(dut, # yapf: disable connected_rssi = collections.OrderedDict( [('time_stamp', []), - ('bssid', []), ('frequency', []), + ('bssid', []), ('ssid', []), ('frequency', []), ('signal_poll_rssi', empty_rssi_result()), ('signal_poll_avg_rssi', empty_rssi_result()), ('chain_0_rssi', empty_rssi_result()), @@ -729,7 +772,11 @@ def get_connected_rssi(dut, measurement_start_time = time.time() connected_rssi['time_stamp'].append(measurement_start_time - t0) # Get signal poll RSSI - status_output = dut.adb.shell(WPA_CLI_STATUS) + if interface is None: + status_output = dut.adb.shell(WPA_CLI_STATUS) + else: + status_output = dut.adb.shell( + 'wpa_cli -i {} status'.format(interface)) match = re.search('bssid=.*', status_output) if match: current_bssid = match.group(0).split('=')[1] @@ -740,7 +787,17 @@ def get_connected_rssi(dut, if disconnect_warning and previous_bssid != 'disconnected': logging.warning('WIFI DISCONNECT DETECTED!') previous_bssid = current_bssid - signal_poll_output = dut.adb.shell(SIGNAL_POLL) + match = re.search('\s+ssid=.*', status_output) + if match: + ssid = match.group(0).split('=')[1] + connected_rssi['ssid'].append(ssid) + else: + connected_rssi['ssid'].append('disconnected') + if interface is None: + signal_poll_output = dut.adb.shell(SIGNAL_POLL) + else: + signal_poll_output = dut.adb.shell( + 'wpa_cli -i {} signal_poll'.format(interface)) match = re.search('FREQUENCY=.*', signal_poll_output) if match: frequency = int(match.group(0).split('=')[1]) @@ -764,8 +821,12 @@ def get_connected_rssi(dut, else: connected_rssi['signal_poll_avg_rssi']['data'].append( RSSI_ERROR_VAL) + # Get per chain RSSI - per_chain_rssi = dut.adb.shell(STATION_DUMP) + if interface is None: + per_chain_rssi = dut.adb.shell(STATION_DUMP) + else: + per_chain_rssi = '' match = re.search('.*signal avg:.*', per_chain_rssi) if match: per_chain_rssi = per_chain_rssi[per_chain_rssi.find('[') + @@ -808,10 +869,11 @@ def get_connected_rssi_nb(dut, polling_frequency=SHORT_SLEEP, first_measurement_delay=0, disconnect_warning=True, - ignore_samples=0): + ignore_samples=0, + interface=None): return get_connected_rssi(dut, num_measurements, polling_frequency, first_measurement_delay, disconnect_warning, - ignore_samples) + ignore_samples, interface) def get_scan_rssi(dut, tracked_bssids, num_measurements=1): @@ -1106,41 +1168,6 @@ def get_server_address(ssh_connection, dut_ip, subnet_mask): logging.error('No IP address found in requested subnet') -def get_iperf_arg_string(duration, - reverse_direction, - interval=1, - traffic_type='TCP', - tcp_window=None, - tcp_processes=1, - udp_throughput='1000M'): - """Function to format iperf client arguments. - - This function takes in iperf client parameters and returns a properly - formatter iperf arg string to be used in throughput tests. - - Args: - duration: iperf duration in seconds - reverse_direction: boolean controlling the -R flag for iperf clients - interval: iperf print interval - traffic_type: string specifying TCP or UDP traffic - tcp_window: string specifying TCP window, e.g., 2M - tcp_processes: int specifying number of tcp processes - udp_throughput: string specifying TX throughput in UDP tests, e.g. 100M - Returns: - iperf_args: string of formatted iperf args - """ - iperf_args = '-i {} -t {} -J '.format(interval, duration) - if traffic_type.upper() == 'UDP': - iperf_args = iperf_args + '-u -b {} -l 1400'.format(udp_throughput) - elif traffic_type.upper() == 'TCP': - iperf_args = iperf_args + '-P {}'.format(tcp_processes) - if tcp_window: - iperf_args = iperf_args + '-w {}'.format(tcp_window) - if reverse_direction: - iperf_args = iperf_args + ' -R' - return iperf_args - - def get_dut_temperature(dut): """Function to get dut temperature. 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 0f75b5a378..22cc69c717 100755 --- a/acts/framework/acts/test_utils/wifi/wifi_test_utils.py +++ b/acts/framework/acts/test_utils/wifi/wifi_test_utils.py @@ -16,6 +16,7 @@ import logging import os +import re import shutil import time @@ -49,7 +50,7 @@ SPEED_OF_LIGHT = 299792458 DEFAULT_PING_ADDR = "https://www.google.com/robots.txt" -roaming_attn = { +ROAMING_ATTN = { "AP1_on_AP2_off": [ 0, 0, @@ -73,24 +74,46 @@ roaming_attn = { class WifiEnums(): - SSID_KEY = "SSID" + SSID_KEY = "SSID" # Used for Wifi & SoftAp SSID_PATTERN_KEY = "ssidPattern" NETID_KEY = "network_id" - BSSID_KEY = "BSSID" + BSSID_KEY = "BSSID" # Used for Wifi & SoftAp BSSID_PATTERN_KEY = "bssidPattern" - PWD_KEY = "password" + PWD_KEY = "password" # Used for Wifi & SoftAp frequency_key = "frequency" - APBAND_KEY = "apBand" - HIDDEN_KEY = "hiddenSSID" + HIDDEN_KEY = "hiddenSSID" # Used for Wifi & SoftAp IS_APP_INTERACTION_REQUIRED = "isAppInteractionRequired" IS_USER_INTERACTION_REQUIRED = "isUserInteractionRequired" - IS_METERED = "isMetered" + IS_SUGGESTION_METERED = "isMetered" PRIORITY = "priority" - SECURITY = "security" - - WIFI_CONFIG_APBAND_2G = 0 - WIFI_CONFIG_APBAND_5G = 1 - WIFI_CONFIG_APBAND_AUTO = -1 + SECURITY = "security" # Used for Wifi & SoftAp + + # Used for SoftAp + AP_BAND_KEY = "apBand" + AP_CHANNEL_KEY = "apChannel" + AP_MAXCLIENTS_KEY = "MaxNumberOfClients" + AP_SHUTDOWNTIMEOUT_KEY = "ShutdownTimeoutMillis" + AP_SHUTDOWNTIMEOUTENABLE_KEY = "AutoShutdownEnabled" + AP_CLIENTCONTROL_KEY = "ClientControlByUserEnabled" + AP_ALLOWEDLIST_KEY = "AllowedClientList" + AP_BLOCKEDLIST_KEY = "BlockedClientList" + + WIFI_CONFIG_SOFTAP_BAND_2G = 1 + WIFI_CONFIG_SOFTAP_BAND_5G = 2 + WIFI_CONFIG_SOFTAP_BAND_2G_5G = 3 + WIFI_CONFIG_SOFTAP_BAND_6G = 4 + WIFI_CONFIG_SOFTAP_BAND_2G_6G = 5 + WIFI_CONFIG_SOFTAP_BAND_5G_6G = 6 + WIFI_CONFIG_SOFTAP_BAND_ANY = 7 + + # DO NOT USE IT for new test case! Replaced by WIFI_CONFIG_SOFTAP_BAND_ + WIFI_CONFIG_APBAND_2G = WIFI_CONFIG_SOFTAP_BAND_2G + WIFI_CONFIG_APBAND_5G = WIFI_CONFIG_SOFTAP_BAND_5G + WIFI_CONFIG_APBAND_AUTO = WIFI_CONFIG_SOFTAP_BAND_2G_5G + + WIFI_CONFIG_APBAND_2G_OLD = 0 + WIFI_CONFIG_APBAND_5G_OLD = 1 + WIFI_CONFIG_APBAND_AUTO_OLD = -1 WIFI_WPS_INFO_PBC = 0 WIFI_WPS_INFO_DISPLAY = 1 @@ -98,6 +121,12 @@ class WifiEnums(): WIFI_WPS_INFO_LABEL = 3 WIFI_WPS_INFO_INVALID = 4 + class SoftApSecurityType(): + OPEN = "NONE" + WPA2 = "WPA2_PSK" + WPA3_SAE_TRANSITION = "WPA3_SAE_TRANSITION" + WPA3_SAE = "WPA3_SAE" + class CountryCode(): CHINA = "CN" JAPAN = "JP" @@ -147,6 +176,7 @@ class WifiEnums(): FQDN = "FQDN" FRIENDLY_NAME = "providerFriendlyName" ROAMING_IDS = "roamingConsortiumIds" + OCSP = "ocsp" # End of Macros for EAP # Macros for wifi p2p. @@ -642,6 +672,7 @@ def _wifi_toggle_state(ad, new_state=None): ad.ed.clear_all_events() # Setting wifi state. ad.droid.wifiToggleState(new_state) + time.sleep(2) fail_msg = "Failed to set Wi-Fi state to %s on %s." % (new_state, ad.serial) try: @@ -923,7 +954,7 @@ def start_wifi_tethering(ad, ssid, password, band=None, hidden=None): if password: config[WifiEnums.PWD_KEY] = password if band: - config[WifiEnums.APBAND_KEY] = band + config[WifiEnums.AP_BAND_KEY] = band if hidden: config[WifiEnums.HIDDEN_KEY] = hidden asserts.assert_true( @@ -943,20 +974,121 @@ def start_wifi_tethering(ad, ssid, password, band=None, hidden=None): ad.droid.wifiStopTrackingTetherStateChange() -def save_wifi_soft_ap_config(ad, wifi_config, band=None, hidden=None): - """ Save a soft ap configuration """ +def save_wifi_soft_ap_config(ad, wifi_config, band=None, hidden=None, + security=None, password=None, + channel=None, max_clients=None, + shutdown_timeout_enable=None, + shutdown_timeout_millis=None, + client_control_enable=None, + allowedList=None, blockedList=None): + """ Save a soft ap configuration and verified + Args: + ad: android_device to set soft ap configuration. + wifi_config: a soft ap configuration object, at least include SSID. + band: specifies the band for the soft ap. + hidden: specifies the soft ap need to broadcast its SSID or not. + security: specifies the security type for the soft ap. + password: specifies the password for the soft ap. + channel: specifies the channel for the soft ap. + max_clients: specifies the maximum connected client number. + shutdown_timeout_enable: specifies the auto shut down enable or not. + shutdown_timeout_millis: specifies the shut down timeout value. + client_control_enable: specifies the client control enable or not. + allowedList: specifies allowed clients list. + blockedList: specifies blocked clients list. + """ + if security and password: + wifi_config[WifiEnums.SECURITY] = security + wifi_config[WifiEnums.PWD_KEY] = password if band: - wifi_config[WifiEnums.APBAND_KEY] = band + wifi_config[WifiEnums.AP_BAND_KEY] = band if hidden: wifi_config[WifiEnums.HIDDEN_KEY] = hidden + if channel and band: + wifi_config[WifiEnums.AP_BAND_KEY] = band + wifi_config[WifiEnums.AP_CHANNEL_KEY] = channel + if max_clients: + wifi_config[WifiEnums.AP_MAXCLIENTS_KEY] = max_clients + if shutdown_timeout_enable: + wifi_config[ + WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY] = shutdown_timeout_enable + if shutdown_timeout_millis: + wifi_config[ + WifiEnums.AP_SHUTDOWNTIMEOUT_KEY] = shutdown_timeout_millis + if client_control_enable: + wifi_config[WifiEnums.AP_CLIENTCONTROL_KEY] = client_control_enable + if allowedList: + wifi_config[WifiEnums.AP_ALLOWEDLIST_KEY] = allowedList + if blockedList: + wifi_config[WifiEnums.AP_BLOCKEDLIST_KEY] = blockedList + + if WifiEnums.AP_CHANNEL_KEY in wifi_config and wifi_config[ + WifiEnums.AP_CHANNEL_KEY] == 0: + del wifi_config[WifiEnums.AP_CHANNEL_KEY] + + if WifiEnums.SECURITY in wifi_config and wifi_config[ + WifiEnums.SECURITY] == WifiEnums.SoftApSecurityType.OPEN: + del wifi_config[WifiEnums.SECURITY] + del wifi_config[WifiEnums.PWD_KEY] + asserts.assert_true(ad.droid.wifiSetWifiApConfiguration(wifi_config), "Failed to set WifiAp Configuration") wifi_ap = ad.droid.wifiGetApConfiguration() asserts.assert_true( wifi_ap[WifiEnums.SSID_KEY] == wifi_config[WifiEnums.SSID_KEY], - "Hotspot SSID doesn't match with expected SSID") + "Hotspot SSID doesn't match") + if WifiEnums.SECURITY in wifi_config: + asserts.assert_true( + wifi_ap[WifiEnums.SECURITY] == wifi_config[WifiEnums.SECURITY], + "Hotspot Security doesn't match") + if WifiEnums.PWD_KEY in wifi_config: + asserts.assert_true( + wifi_ap[WifiEnums.PWD_KEY] == wifi_config[WifiEnums.PWD_KEY], + "Hotspot Password doesn't match") + if WifiEnums.HIDDEN_KEY in wifi_config: + asserts.assert_true( + wifi_ap[WifiEnums.HIDDEN_KEY] == wifi_config[WifiEnums.HIDDEN_KEY], + "Hotspot hidden setting doesn't match") + + if WifiEnums.AP_BAND_KEY in wifi_config: + asserts.assert_true( + wifi_ap[WifiEnums.AP_BAND_KEY] == wifi_config[WifiEnums.AP_BAND_KEY], + "Hotspot Band doesn't match") + if WifiEnums.AP_CHANNEL_KEY in wifi_config: + asserts.assert_true( + wifi_ap[WifiEnums.AP_CHANNEL_KEY] == wifi_config[ + WifiEnums.AP_CHANNEL_KEY], "Hotspot Channel doesn't match") + if WifiEnums.AP_MAXCLIENTS_KEY in wifi_config: + asserts.assert_true( + wifi_ap[WifiEnums.AP_MAXCLIENTS_KEY] == wifi_config[ + WifiEnums.AP_MAXCLIENTS_KEY], "Hotspot Max Clients doesn't match") + if WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY in wifi_config: + asserts.assert_true( + wifi_ap[WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY] == wifi_config[ + WifiEnums.AP_SHUTDOWNTIMEOUTENABLE_KEY], + "Hotspot ShutDown feature flag doesn't match") + if WifiEnums.AP_SHUTDOWNTIMEOUT_KEY in wifi_config: + asserts.assert_true( + wifi_ap[WifiEnums.AP_SHUTDOWNTIMEOUT_KEY] == wifi_config[ + WifiEnums.AP_SHUTDOWNTIMEOUT_KEY], + "Hotspot ShutDown timeout setting doesn't match") + if WifiEnums.AP_CLIENTCONTROL_KEY in wifi_config: + asserts.assert_true( + wifi_ap[WifiEnums.AP_CLIENTCONTROL_KEY] == wifi_config[ + WifiEnums.AP_CLIENTCONTROL_KEY], + "Hotspot Client control flag doesn't match") + if WifiEnums.AP_ALLOWEDLIST_KEY in wifi_config: + asserts.assert_true( + wifi_ap[WifiEnums.AP_ALLOWEDLIST_KEY] == wifi_config[ + WifiEnums.AP_ALLOWEDLIST_KEY], + "Hotspot Allowed List doesn't match") + if WifiEnums.AP_BLOCKEDLIST_KEY in wifi_config: + asserts.assert_true( + wifi_ap[WifiEnums.AP_BLOCKEDLIST_KEY] == wifi_config[ + WifiEnums.AP_BLOCKEDLIST_KEY], + "Hotspot Blocked List doesn't match") def start_wifi_tethering_saved_config(ad): """ Turn on wifi hotspot with a config that is already saved """ @@ -974,7 +1106,6 @@ def start_wifi_tethering_saved_config(ad): def stop_wifi_tethering(ad): """Stops wifi tethering on an android_device. - Args: ad: android_device to stop wifi tethering on. """ @@ -1029,7 +1160,7 @@ def toggle_wifi_and_wait_for_reconnection(ad, num_of_tries=num_of_tries) -def _toggle_wifi_and_wait_for_reconnection(ad, network, num_of_tries=1): +def _toggle_wifi_and_wait_for_reconnection(ad, network, num_of_tries=3): """Toggle wifi state and then wait for Android device to reconnect to the provided wifi network. @@ -1345,11 +1476,8 @@ def _wifi_connect(ad, network, num_of_tries=1, check_connectivity=True): ad.serial) ad.log.info("Connected to Wi-Fi network %s.", actual_ssid) - # Wait for data connection to stabilize. - time.sleep(5) - if check_connectivity: - internet = validate_connection(ad, DEFAULT_PING_ADDR, 10) + internet = validate_connection(ad, DEFAULT_PING_ADDR) if not internet: raise signals.TestFailure("Failed to connect to internet on %s" % expected_ssid) @@ -1422,9 +1550,6 @@ def _wifi_connect_by_id(ad, network_id, num_of_tries=1): ad.log.info("Connected to Wi-Fi network %s with %d network id.", expected_ssid, network_id) - # Wait for data connection to stabilize. - time.sleep(5) - internet = validate_connection(ad, DEFAULT_PING_ADDR) if not internet: raise signals.TestFailure("Failed to connect to internet on %s" % @@ -1652,9 +1777,6 @@ def _wifi_passpoint_connect(ad, passpoint_network, num_of_tries=1): "Connected to the wrong network on %s." % ad.serial) ad.log.info("Connected to Wi-Fi passpoint network %s.", actual_ssid) - # Wait for data connection to stabilize. - time.sleep(5) - internet = validate_connection(ad, DEFAULT_PING_ADDR) if not internet: raise signals.TestFailure("Failed to connect to internet on %s" % @@ -1782,7 +1904,8 @@ def convert_pem_key_to_pkcs8(in_file, out_file): utils.exe_cmd(cmd) -def validate_connection(ad, ping_addr=DEFAULT_PING_ADDR, wait_time=2): +def validate_connection(ad, ping_addr=DEFAULT_PING_ADDR, wait_time=15, + ping_gateway=True): """Validate internet connection by pinging the address provided. Args: @@ -1794,9 +1917,22 @@ def validate_connection(ad, ping_addr=DEFAULT_PING_ADDR, wait_time=2): ping output if successful, NULL otherwise. """ # wait_time to allow for DHCP to complete. - time.sleep(wait_time) - ping = ad.droid.httpPing(ping_addr) - ad.log.info("Http ping result: %s.", ping) + for i in range(wait_time): + if ad.droid.connectivityNetworkIsConnected(): + break + time.sleep(1) + ping = False + try: + ping = ad.droid.httpPing(ping_addr) + ad.log.info("Http ping result: %s.", ping) + except: + pass + if not ping and ping_gateway: + ad.log.info("Http ping failed. Pinging default gateway") + gw = ad.droid.connectivityGetIPv4DefaultGateway() + result = ad.adb.shell("ping -c 6 {}".format(gw)) + ad.log.info("Default gateway ping result: %s" % result) + ping = False if "100% packet loss" in result else True return ping @@ -1952,12 +2088,13 @@ def group_attenuators(attenuators): return [attn0, attn1] -def set_attns(attenuator, attn_val_name): +def set_attns(attenuator, attn_val_name, roaming_attn=ROAMING_ATTN): """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. + roaming_attn: Dictionary specifying the attenuation params. """ logging.info("Set attenuation values to %s", roaming_attn[attn_val_name]) try: @@ -1970,7 +2107,11 @@ def set_attns(attenuator, attn_val_name): attn_val_name) raise -def set_attns_steps(attenuators, atten_val_name, steps=10, wait_time=12): +def set_attns_steps(attenuators, + atten_val_name, + roaming_attn=ROAMING_ATTN, + steps=10, + wait_time=12): """Set attenuation values on attenuators used in this test. It will change the attenuation values linearly from current value to target value step by step. @@ -1979,6 +2120,7 @@ def set_attns_steps(attenuators, atten_val_name, steps=10, wait_time=12): attenuators: The list of attenuator objects that you want to change their attenuation value. atten_val_name: Name of the attenuation value pair to use. + roaming_attn: Dictionary specifying the attenuation params. steps: Number of attenuator changes to reach the target value. wait_time: Sleep time for each change of attenuator. """ @@ -1994,7 +2136,11 @@ def set_attns_steps(attenuators, atten_val_name, steps=10, wait_time=12): time.sleep(wait_time) -def trigger_roaming_and_validate(dut, attenuator, attn_val_name, expected_con): +def trigger_roaming_and_validate(dut, + attenuator, + attn_val_name, + expected_con, + roaming_attn=ROAMING_ATTN): """Sets attenuators to trigger roaming and validate the DUT connected to the BSSID expected. @@ -2002,14 +2148,13 @@ def trigger_roaming_and_validate(dut, attenuator, attn_val_name, expected_con): attenuator: The attenuator object. attn_val_name: Name of the attenuation value pair to use. expected_con: The network information of the expected network. + roaming_attn: Dictionary specifying the attenaution params. """ 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, roaming_attn) verify_wifi_connection_info(dut, expected_con) expected_bssid = expected_con[WifiEnums.BSSID_KEY] @@ -2038,6 +2183,13 @@ def start_softap_and_verify(ad, band): Returns: dict, the softAP config. """ + # Register before start the test. + callbackId = ad.dut.droid.registerSoftApCallback() + # Check softap info value is default + frequency, bandwdith = get_current_softap_info(ad.dut, callbackId, True) + asserts.assert_true(frequency == 0, "Softap frequency is not reset") + asserts.assert_true(bandwdith == 0, "Softap bandwdith is not reset") + config = create_softap_config() start_wifi_tethering(ad.dut, config[WifiEnums.SSID_KEY], @@ -2046,6 +2198,15 @@ def start_softap_and_verify(ad, band): "SoftAp is not reported as running") start_wifi_connection_scan_and_ensure_network_found(ad.dut_client, config[WifiEnums.SSID_KEY]) + + # Check softap info can get from callback succeed and assert value should be + # valid. + frequency, bandwdith = get_current_softap_info(ad.dut, callbackId, True) + asserts.assert_true(frequency > 0, "Softap frequency is not valid") + asserts.assert_true(bandwdith > 0, "Softap bandwdith is not valid") + # Unregister callback + ad.dut.droid.unregisterSoftApCallback(callbackId) + return config def wait_for_expected_number_of_softap_clients(ad, callbackId, @@ -2057,11 +2218,28 @@ def wait_for_expected_number_of_softap_clients(ad, callbackId, """ eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str( callbackId) + wifi_constants.SOFTAP_NUMBER_CLIENTS_CHANGED - asserts.assert_equal(ad.ed.pop_event(eventStr, - SHORT_TIMEOUT)['data'][wifi_constants. - SOFTAP_NUMBER_CLIENTS_CALLBACK_KEY], - expected_num_of_softap_clients, - "Number of softap clients doesn't match with expected number") + clientData = ad.ed.pop_event(eventStr, SHORT_TIMEOUT)['data'] + clientCount = clientData[wifi_constants.SOFTAP_NUMBER_CLIENTS_CALLBACK_KEY] + clientMacAddresses = clientData[wifi_constants.SOFTAP_CLIENTS_MACS_CALLBACK_KEY] + asserts.assert_equal(clientCount, expected_num_of_softap_clients, + "The number of softap clients doesn't match the expected number") + asserts.assert_equal(len(clientMacAddresses), expected_num_of_softap_clients, + "The number of mac addresses doesn't match the expected number") + for macAddress in clientMacAddresses: + asserts.assert_true(checkMacAddress(macAddress), "An invalid mac address was returned") + +def checkMacAddress(input): + """Validate whether a string is a valid mac address or not. + + Args: + input: The string to validate. + + Returns: True/False, returns true for a valid mac address and false otherwise. + """ + macValidationRegex = "[0-9a-f]{2}([-:]?)[0-9a-f]{2}(\\1[0-9a-f]{2}){4}$" + if re.match(macValidationRegex, input.lower()): + return True + return False def wait_for_expected_softap_state(ad, callbackId, expected_softap_state): """Wait for the expected softap state change. @@ -2096,6 +2274,41 @@ def get_current_number_of_softap_clients(ad, callbackId): return None return num_of_clients +def get_current_softap_info(ad, callbackId, least_one): + """pop up all of softap info changed event from queue. + Args: + callbackId: Id of the callback associated with registering. + least_one: Wait for the info callback event before pop all. + Returns: + Returns last updated information of softap. + """ + eventStr = wifi_constants.SOFTAP_CALLBACK_EVENT + str( + callbackId) + wifi_constants.SOFTAP_INFO_CHANGED + ad.log.info("softap info dump from eventStr %s", + eventStr) + frequency = 0 + bandwidth = 0 + if (least_one): + event = ad.ed.pop_event(eventStr, SHORT_TIMEOUT) + frequency = event['data'][wifi_constants. + SOFTAP_INFO_FREQUENCY_CALLBACK_KEY] + bandwidth = event['data'][wifi_constants. + SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY] + ad.log.info("softap info updated, frequency is %s, bandwidth is %s", + frequency, bandwidth) + + events = ad.ed.pop_all(eventStr) + for event in events: + frequency = event['data'][wifi_constants. + SOFTAP_INFO_FREQUENCY_CALLBACK_KEY] + bandwidth = event['data'][wifi_constants. + SOFTAP_INFO_BANDWIDTH_CALLBACK_KEY] + ad.log.info("softap info, frequency is %s, bandwidth is %s", + frequency, bandwidth) + return frequency, bandwidth + + + def get_ssrdumps(ad, test_name=""): """Pulls dumps in the ssrdump dir Args: @@ -2155,30 +2368,33 @@ def stop_pcap(pcap, procs, test_status=None): if test_status: shutil.rmtree(os.path.dirname(fname)) -def verify_mac_not_found_in_pcap(mac, packets): +def verify_mac_not_found_in_pcap(ad, mac, packets): """Verify that a mac address is not found in the captured packets. Args: + ad: android device object mac: string representation of the mac address packets: packets obtained by rdpcap(pcap_fname) """ for pkt in packets: logging.debug("Packet Summary = %s", pkt.summary()) if mac in pkt.summary(): - asserts.fail("Caught Factory MAC: %s in packet sniffer." - "Packet = %s" % (mac, pkt.show())) + asserts.fail("Device %s caught Factory MAC: %s in packet sniffer." + "Packet = %s" % (ad.serial, mac, pkt.show())) -def verify_mac_is_found_in_pcap(mac, packets): +def verify_mac_is_found_in_pcap(ad, mac, packets): """Verify that a mac address is found in the captured packets. Args: + ad: android device object mac: string representation of the mac address packets: packets obtained by rdpcap(pcap_fname) """ for pkt in packets: if mac in pkt.summary(): return - asserts.fail("Did not find MAC = %s in packet sniffer." % mac) + asserts.fail("Did not find MAC = %s in packet sniffer." + "for device %s" % (mac, ad.serial)) def start_cnss_diags(ads): for ad in ads: diff --git a/acts/framework/acts/tracelogger.py b/acts/framework/acts/tracelogger.py index c7d920fcdb..d230fadd0f 100644 --- a/acts/framework/acts/tracelogger.py +++ b/acts/framework/acts/tracelogger.py @@ -14,11 +14,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -import datetime import inspect -import logging import os -import xml.etree.cElementTree as et class TraceLogger(object): @@ -65,41 +62,3 @@ class TraceLogger(object): def __getattr__(self, name): return getattr(self._logger, name) - - -class TakoTraceLogger(TraceLogger): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.d = self.debug - self.e = self.error - self.i = self.info - self.t = self.step - self.w = self.warning - - def _logger_level(self, level_name): - level = logging.getLevelName(level_name) - return lambda *args, **kwargs: self._logger.log(level, *args, **kwargs) - - def step(self, msg, *args, **kwargs): - """Delegate a step call to the underlying logger.""" - self._log_with(self._logger_level('STEP'), 1, msg, *args, **kwargs) - - def device(self, msg, *args, **kwargs): - """Delegate a device call to the underlying logger.""" - self._log_with(self._logger_level('DEVICE'), 1, msg, *args, **kwargs) - - def suite(self, msg, *args, **kwargs): - """Delegate a device call to the underlying logger.""" - self._log_with(self._logger_level('SUITE'), 1, msg, *args, **kwargs) - - def case(self, msg, *args, **kwargs): - """Delegate a case call to the underlying logger.""" - self._log_with(self._logger_level('CASE'), 1, msg, *args, **kwargs) - - def flush_log(self): - """This function exists for compatibility with Tako's logserial module. - - Note that flushing the log is handled automatically by python's logging - module. - """ - pass diff --git a/acts/framework/acts/utils.py b/acts/framework/acts/utils.py index c38f7c145d..3f57c91bdb 100755 --- a/acts/framework/acts/utils.py +++ b/acts/framework/acts/utils.py @@ -556,7 +556,6 @@ def timeout(sec): Raises: TimeoutError is raised when time out happens. """ - def decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): @@ -952,10 +951,7 @@ def adb_shell_ping(ad, default www.google.com timeout: timeout for icmp pings to complete. """ - if is_valid_ipv6_address(dest_ip): - ping_cmd = "ping6 -W 1" - else: - ping_cmd = "ping -W 1" + ping_cmd = "ping -W 1" if count: ping_cmd += " -c %d" % count if dest_ip: @@ -1288,7 +1284,6 @@ class SuppressLogOutput(object): """Context manager used to suppress all logging output for the specified logger and level(s). """ - def __init__(self, logger=logging.getLogger(), log_levels=None): """Create a SuppressLogOutput context manager @@ -1321,7 +1316,6 @@ class BlockingTimer(object): """Context manager used to block until a specified amount of time has elapsed. """ - def __init__(self, secs): """Initializes a BlockingTimer @@ -1393,7 +1387,7 @@ def get_interface_ip_addresses(comm_channel, interface): Returns: A list of dictionaries of the the various IP addresses: - ipv4_private_local_addresses: Any 192.168, 172.16, 10, or 169.254 + ipv4_private_local_addresses: Any 192.168, 172.16, or 10 addresses ipv4_public_addresses: Any IPv4 public addresses ipv6_link_local_addresses: Any fe80:: addresses @@ -1501,6 +1495,14 @@ def get_interface_based_on_ip(comm_channel, desired_ip_address): all_ips_and_interfaces = comm_channel.run( '(ip -o -4 addr show; ip -o -6 addr show) | ' 'awk \'{print $2" "$4}\'').stdout + #ipv4_addresses = comm_channel.run( + # 'ip -o -4 addr show| awk \'{print $2": "$4}\'').stdout + #ipv6_addresses = comm_channel._ssh_session.run( + # 'ip -o -6 addr show| awk \'{print $2": "$4}\'').stdout + #if desired_ip_address in ipv4_addresses: + # ip_addresses_to_search = ipv4_addresses + #elif desired_ip_address in ipv6_addresses: + # ip_addresses_to_search = ipv6_addresses for ip_address_and_interface in all_ips_and_interfaces.split('\n'): if desired_ip_address in ip_address_and_interface: return ip_address_and_interface.split()[1][:-1] @@ -1510,54 +1512,189 @@ def get_interface_based_on_ip(comm_channel, desired_ip_address): def renew_linux_ip_address(comm_channel, interface): comm_channel.run('sudo ifconfig %s down' % interface) comm_channel.run('sudo ifconfig %s up' % interface) - comm_channel.run('sudo killall dhcpcd 2>/dev/null; echo""') - is_dhcpcd_dead = False - dhcpcd_counter = 0 - dhcpcd_checker_max_times = 3 - while not is_dhcpcd_dead: - if dhcpcd_counter == dhcpcd_checker_max_times: - raise TimeoutError('Unable to stop dhcpcd') - time.sleep(1) - if 'dhcpcd' in comm_channel.run('ps axu').stdout: - dhcpcd_counter += 1 - else: - is_dhcpcd_dead = True - comm_channel.run('sudo dhcpcd -q -b') comm_channel.run('sudo dhclient -r %s' % interface) comm_channel.run('sudo dhclient %s' % interface) -def is_pingable(ip): - """Returns whether an ip is pingable or not. +def get_ping_command(dest_ip, + count=3, + interval=1000, + timeout=1000, + size=56, + os_type='Linux', + additional_ping_params=None): + """Builds ping command string based on address type, os, and params. Args: - ip: string, ip address to ping + dest_ip: string, address to ping (ipv4 or ipv6) + count: int, number of requests to send + interval: int, time in seconds between requests + timeout: int, time in seconds to wait for response + size: int, number of bytes to send, + os_type: string, os type of the source device (supports 'Linux', + 'Darwin') + additional_ping_params: string, command option flags to + append to the command string + Returns: - True if ping was successful, else False + List of string, represetning the ping command. """ - if is_valid_ipv4_address(ip): + if is_valid_ipv4_address(dest_ip): ping_binary = 'ping' - elif is_valid_ipv6_address(ip): + elif is_valid_ipv6_address(dest_ip): ping_binary = 'ping6' else: - raise ValueError('Invalid ip addr: %s' % ip) + raise ValueError('Invalid ip addr: %s' % dest_ip) - os_type = platform.system() if os_type == 'Darwin': - if is_valid_ipv6_address(ip): + if is_valid_ipv6_address(dest_ip): # ping6 on MacOS doesn't support timeout + logging.warn( + 'Ignoring timeout, as ping6 on MacOS does not support it.') timeout_flag = [] else: - timeout_flag = ['-t', '1'] + timeout_flag = ['-t', str(timeout / 1000)] elif os_type == 'Linux': - timeout_flag = ['-W', '1'] + timeout_flag = ['-W', str(timeout / 1000)] else: raise ValueError('Invalid OS. Only Linux and MacOS are supported.') - ping_cmd = [ping_binary, *timeout_flag, '-c', '1', ip] + if not additional_ping_params: + additional_ping_params = '' + + ping_cmd = [ + ping_binary, *timeout_flag, '-c', + str(count), '-i', + str(interval / 1000), '-s', + str(size), additional_ping_params, dest_ip + ] + return ' '.join(ping_cmd) + + +def ping(comm_channel, + dest_ip, + count=3, + interval=1000, + timeout=1000, + size=56, + additional_ping_params=None): + """ Generic linux ping function, supports local (acts.libs.proc.job) and + SshConnections (acts.libs.proc.job over ssh) to Linux based OSs and MacOS. + + NOTES: This will work with Android over SSH, but does not function over ADB + as that has a unique return format. + + Args: + comm_channel: communication channel over which to send ping command. + Must have 'run' function that returns at least command, stdout, + stderr, and exit_status (see acts.libs.proc.job) + dest_ip: address to ping (ipv4 or ipv6) + count: int, number of packets to send + interval: int, time in milliseconds between pings + timeout: int, time in milliseconds to wait for response + size: int, size of packets in bytes + additional_ping_params: string, command option flags to + append to the command string + + Returns: + Dict containing: + command: string + exit_status: int (0 or 1) + stdout: string + stderr: string + transmitted: int, number of packets transmitted + received: int, number of packets received + packet_loss: int, percentage packet loss + time: int, time of ping command execution (in milliseconds) + rtt_min: float, minimum round trip time + rtt_avg: float, average round trip time + rtt_max: float, maximum round trip time + rtt_mdev: float, round trip time standard deviation + + Any values that cannot be parsed are left as None + """ + from acts.controllers.utils_lib.ssh.connection import SshConnection + is_local = comm_channel == job + os_type = platform.system() if is_local else 'Linux' + ping_cmd = get_ping_command(dest_ip, + count=count, + interval=interval, + timeout=timeout, + size=size, + os_type=os_type, + additional_ping_params=additional_ping_params) + + if (type(comm_channel) is SshConnection or is_local): + logging.debug( + 'Running ping with parameters (count: %s, interval: %s, timeout: ' + '%s, size: %s)' % (count, interval, timeout, size)) + ping_result = comm_channel.run(ping_cmd, ignore_status=True) + else: + raise ValueError('Unsupported comm_channel: %s' % type(comm_channel)) + + if isinstance(ping_result, job.Error): + ping_result = ping_result.result + + transmitted = None + received = None + packet_loss = None + time = None + rtt_min = None + rtt_avg = None + rtt_max = None + rtt_mdev = None + + summary = re.search( + '([0-9]+) packets transmitted.*?([0-9]+) received.*?([0-9]+)% packet ' + 'loss.*?time ([0-9]+)', ping_result.stdout) + if summary: + transmitted = summary[1] + received = summary[2] + packet_loss = summary[3] + time = summary[4] + + rtt_stats = re.search('= ([0-9.]+)/([0-9.]+)/([0-9.]+)/([0-9.]+)', + ping_result.stdout) + if rtt_stats: + rtt_min = rtt_stats[1] + rtt_avg = rtt_stats[2] + rtt_max = rtt_stats[3] + rtt_mdev = rtt_stats[4] + + return { + 'command': ping_result.command, + 'exit_status': ping_result.exit_status, + 'stdout': ping_result.stdout, + 'stderr': ping_result.stderr, + 'transmitted': transmitted, + 'received': received, + 'packet_loss': packet_loss, + 'time': time, + 'rtt_min': rtt_min, + 'rtt_avg': rtt_avg, + 'rtt_max': rtt_max, + 'rtt_mdev': rtt_mdev + } + - result = job.run(ping_cmd, timeout=10, ignore_status=True) - return result.exit_status == 0 +def can_ping(comm_channel, + dest_ip, + count=1, + interval=1000, + timeout=1000, + size=56, + additional_ping_params=None): + """Returns whether device connected via comm_channel can ping a dest + address""" + ping_results = ping(comm_channel, + dest_ip, + count=count, + interval=interval, + timeout=timeout, + size=size, + additional_ping_params=additional_ping_params) + + return ping_results['exit_status'] == 0 def ip_in_subnet(ip, subnet): diff --git a/acts/framework/tests/acts_confidence_test_config.json b/acts/framework/tests/acts_confidence_test_config.json new file mode 100644 index 0000000000..566bebada5 --- /dev/null +++ b/acts/framework/tests/acts_confidence_test_config.json @@ -0,0 +1,15 @@ +{ + "testbed": + [ + { + "_description": "ACTS confidence test bed, no device needed.", + "name": "Confidence", + "icecream": 42, + "MagicDevice": ["Magic!"] + } + ], + "logpath": "/tmp/logs", + "testpaths": ["./"], + "icecream": "mememe", + "extra_param": "haha" +} diff --git a/acts/framework/tests/acts_import_unit_test.py b/acts/framework/tests/acts_import_unit_test.py index 5e12e0f246..1d1ac7542c 100755 --- a/acts/framework/tests/acts_import_unit_test.py +++ b/acts/framework/tests/acts_import_unit_test.py @@ -47,7 +47,7 @@ else: PY_FILE_REGEX = re.compile('.+\.py$') -BLACKLIST = [ +DENYLIST = [ 'acts/controllers/rohdeschwarz_lib/contest.py', 'acts/controllers/native.py', 'acts/controllers/native_android_device.py', @@ -60,10 +60,9 @@ BLACKLIST = [ 'acts/test_utils/bt/bt_power_test_utils.py', 'acts/test_utils/coex/coex_test_utils.py', 'acts/test_utils/tel/twilio_client.py', - 'acts/test_utils/bt/A2dpBaseTest.py', - 'acts/test_utils/bt/BtSarBaseTest.py', 'tests/google/ble/beacon_tests/BeaconSwarmTest.py', 'tests/google/bt/pts/BtCmdLineTest.py', + 'tests/google/bt/performance/BtA2dpOtaRangeTest.py', 'tests/google/bt/headphone_automation/SineWaveQualityTest.py', 'tests/google/bt/audio_lab/BtChameleonTest.py', 'tests/google/native/bt/BtNativeTest.py', @@ -87,11 +86,12 @@ BLACKLIST = [ 'acts/test_utils/gnss/gnss_testlog_utils.py', ] -BLACKLIST_DIRECTORIES = [ +DENYLIST_DIRECTORIES = [ 'acts/controllers/buds_lib', 'acts/test_utils/audio_analysis_lib/', 'acts/test_utils/coex/', 'acts/test_utils/power/', + 'acts/test_utils/bt/', 'tests/google/coex/', 'tests/google/gnss/', 'tests/google/power/', @@ -125,9 +125,9 @@ class ActsImportUnitTest(unittest.TestCase): for root, _, files in os.walk(base_dir): for f in files: full_path = os.path.join(root, f) - if (any(full_path.endswith(e) for e in BLACKLIST) + if (any(full_path.endswith(e) for e in DENYLIST) or any(e in full_path - for e in BLACKLIST_DIRECTORIES)): + for e in DENYLIST_DIRECTORIES)): continue path = os.path.relpath(os.path.join(root, f), os.getcwd()) diff --git a/acts/framework/tests/acts_test_decorators_test.py b/acts/framework/tests/acts_test_decorators_test.py index c0e742a282..3ec357eeb6 100755 --- a/acts/framework/tests/acts_test_decorators_test.py +++ b/acts/framework/tests/acts_test_decorators_test.py @@ -238,16 +238,13 @@ class RepeatedTestTests(unittest.TestCase): self.assertIsInstance(results[3], IndexError) raise signals.TestPass('Expected failures occurred') - call_count = 0 @test_decorators.repeated_test(1, 3, result_selector) - def test_case(_): - nonlocal call_count - call_count += 1 - if call_count == 1: + def test_case(_, attempt_number): + if attempt_number == 1: raise AssertionError() - elif call_count == 2: + elif attempt_number == 2: raise signals.TestFailure('Failed') - elif call_count == 3: + elif attempt_number == 3: raise signals.TestError('Error') else: # Note that any Exception that does not fall into another bucket @@ -265,7 +262,7 @@ class RepeatedTestTests(unittest.TestCase): raise signals.TestPass('Expected passes occurred') @test_decorators.repeated_test(3, 0, result_selector) - def test_case(_): + def test_case(*_): raise signals.TestPass('Passed') with self.assertRaises(signals.TestPass): @@ -273,7 +270,7 @@ class RepeatedTestTests(unittest.TestCase): def test_abort_signals_are_uncaught(self): @test_decorators.repeated_test(3, 0) - def test_case(_): + def test_case(*_): raise signals.TestAbortClass('Abort All') with self.assertRaises(signals.TestAbortClass): @@ -281,7 +278,7 @@ class RepeatedTestTests(unittest.TestCase): def test_keyboard_interrupt_is_uncaught(self): @test_decorators.repeated_test(3, 0) - def test_case(_): + def test_case(*_): raise KeyboardInterrupt() with self.assertRaises(KeyboardInterrupt): @@ -290,7 +287,7 @@ class RepeatedTestTests(unittest.TestCase): def test_teardown_and_setup_are_called_between_test_cases(self): mock_test_class = mock.Mock() @test_decorators.repeated_test(1, 1) - def test_case(_): + def test_case(*_): raise signals.TestFailure('Failed') with self.assertRaises(signals.TestFailure): @@ -300,11 +297,11 @@ class RepeatedTestTests(unittest.TestCase): self.assertTrue(mock_test_class.teardown_test.called) def test_result_selector_returned_value_gets_raised(self): - def result_selector(_): + def result_selector(*_): return signals.TestPass('Expect this to be raised.') @test_decorators.repeated_test(3, 0, result_selector=result_selector) - def test_case(_): + def test_case(*_): raise signals.TestFailure('Result selector ignores this.') with self.assertRaises(signals.TestPass): diff --git a/acts/framework/tests/acts_utils_test.py b/acts/framework/tests/acts_utils_test.py index a08bf370bd..900a1e97a5 100755 --- a/acts/framework/tests/acts_utils_test.py +++ b/acts/framework/tests/acts_utils_test.py @@ -173,6 +173,7 @@ FUCHSIA_INIT_NETSTACK = ('acts.controllers.fuchsia_lib.netstack.' class ByPassSetupWizardTests(unittest.TestCase): """This test class for unit testing acts.utils.bypass_setup_wizard.""" + def test_start_standing_subproc(self): with self.assertRaisesRegex(utils.ActsUtilsError, 'Process .* has terminated'): @@ -306,6 +307,7 @@ class BypassSetupWizardReturn: class ConcurrentActionsTest(unittest.TestCase): """Tests acts.utils.run_concurrent_actions and related functions.""" + @staticmethod def function_returns_passed_in_arg(arg): return arg @@ -389,6 +391,7 @@ class ConcurrentActionsTest(unittest.TestCase): class SuppressLogOutputTest(unittest.TestCase): """Tests SuppressLogOutput""" + def test_suppress_log_output(self): """Tests that the SuppressLogOutput context manager removes handlers of the specified levels upon entry and re-adds handlers upon exit. @@ -411,6 +414,7 @@ class SuppressLogOutputTest(unittest.TestCase): class IpAddressUtilTest(unittest.TestCase): + def test_positive_ipv4_normal_address(self): ip_address = "192.168.1.123" self.assertTrue(utils.is_valid_ipv4_address(ip_address)) @@ -501,22 +505,20 @@ class IpAddressUtilTest(unittest.TestCase): utils.get_interface_ip_addresses(SshConnection('mock_settings'), 'wlan1'), CORRECT_EMPTY_IP_LIST) - @mock.patch('acts.controllers.adb.AdbProxy') + @mock.patch('acts.controllers.adb.AdbProxy.shell') def test_android_get_interface_ip_addresses_full(self, adb_mock): adb_mock().shell.side_effect = [ MOCK_IP_ADDRESSES, MOCK_IFCONFIG_OUTPUT ] self.assertEqual( utils.get_interface_ip_addresses(AndroidDevice(), 'eno1'), - CORRECT_FULL_IP_LIST) + CORRECT_FULL_IP_LIST) - @mock.patch('acts.controllers.adb.AdbProxy') + @mock.patch('acts.controllers.adb.AdbProxy.shell') def test_android_get_interface_ip_addresses_empty(self, adb_mock): - adb_mock().shell.side_effect = [ - MOCK_IP_ADDRESSES, MOCK_IFCONFIG_OUTPUT - ] - self.assertEqual( - utils.get_interface_ip_addresses(AndroidDevice(), 'wlan1'), + adb_mock.side_effect = [MOCK_IP_ADDRESSES, MOCK_IFCONFIG_OUTPUT] + self.assertTrue( + utils.get_interface_ip_addresses(AndroidDevice(), 'wlan1') == CORRECT_EMPTY_IP_LIST) @mock.patch(FUCHSIA_INIT_SERVER) diff --git a/acts/framework/tests/controllers/monsoon_lib/sampling/engine/transformers_test.py b/acts/framework/tests/controllers/monsoon_lib/sampling/engine/transformers_test.py index 4b6a7d0f73..0f97cec225 100755 --- a/acts/framework/tests/controllers/monsoon_lib/sampling/engine/transformers_test.py +++ b/acts/framework/tests/controllers/monsoon_lib/sampling/engine/transformers_test.py @@ -19,28 +19,15 @@ import unittest import mock from acts.controllers.monsoon_lib.sampling.engine.transformers import DownSampler +from acts.controllers.monsoon_lib.sampling.engine.transformers import PerfgateTee from acts.controllers.monsoon_lib.sampling.engine.transformers import SampleAggregator from acts.controllers.monsoon_lib.sampling.engine.transformers import Tee +from acts.controllers.monsoon_lib.sampling.hvpm.transformers import HvpmReading ARGS = 0 KWARGS = 1 -# TODO: Import HvpmReading directly when it is added to the codebase. -class HvpmReading(object): - def __init__(self, data, time): - self.main_current = data[0] - self.sample_time = time - - def __add__(self, other): - return HvpmReading([self.main_current + other.main_current], - self.sample_time + other.sample_time) - - def __truediv__(self, other): - return HvpmReading([self.main_current / other], - self.sample_time / other) - - class TeeTest(unittest.TestCase): """Unit tests the transformers.Tee class.""" @@ -67,8 +54,8 @@ class TeeTest(unittest.TestCase): tee.on_begin() expected_output = [ - '0.010000000s 1.414213562370\n', '0.020000000s 2.718281828460\n', - '0.030000000s 3.141592653590\n' + '0.010000000 1.414213562370\n', '0.020000000 2.718281828460\n', + '0.030000000 3.141592653590\n' ] tee._transform_buffer([ @@ -82,13 +69,55 @@ class TeeTest(unittest.TestCase): self.assertEqual(call[ARGS][0], out) +class PerfgateTeeTest(unittest.TestCase): + """Unit tests the transformers.PerfgateTee class.""" + + @mock.patch('builtins.open') + def test_begin_opens_file_on_expected_filename(self, open_mock): + expected_filename = 'foo' + + PerfgateTee(expected_filename).on_begin() + + open_mock.assert_called_with(expected_filename, 'w+') + + @mock.patch('builtins.open') + def test_end_closes_file(self, open_mock): + tee = PerfgateTee('foo') + tee.on_begin() + + tee.on_end() + + self.assertTrue(open_mock().close.called) + + @mock.patch('builtins.open') + def test_transform_buffer_outputs_correct_format(self, open_mock): + tee = PerfgateTee('foo') + tee.on_begin() + + expected_output = [ + '1596149635552503296,0.000223,4.193050\n', + '1596149635562476032,0.000212,4.193190\n', + '1596149635572549376,0.000225,4.193135\n', + ] + + tee._transform_buffer([ + HvpmReading([0.000223, 0, 0, 4.193050, 0], 1596149635.552503296), + HvpmReading([0.000212, 0, 0, 4.193190, 0], 1596149635.562476032), + HvpmReading([0.000225, 0, 0, 4.193135, 0], 1596149635.572549376), + ]) + + for call, out in zip(open_mock().write.call_args_list, + expected_output): + self.assertEqual(call[ARGS][0], out) + + class SampleAggregatorTest(unittest.TestCase): """Unit tests the transformers.SampleAggregator class.""" def test_transform_buffer_respects_start_after_seconds_flag(self): - sample_aggregator = SampleAggregator(start_after_seconds=1) + sample_aggregator = SampleAggregator(start_after_seconds=1.0) sample_aggregator._transform_buffer([ - HvpmReading([1.41421356237, 0, 0, 0, 0], 0.01), + HvpmReading([1.41421356237, 0, 0, 0, 0], 0.00), HvpmReading([2.71828182846, 0, 0, 0, 0], 0.99), HvpmReading([3.14159265359, 0, 0, 0, 0], 1.00), ]) diff --git a/acts/framework/tests/libs/proc/process_test.py b/acts/framework/tests/libs/proc/process_test.py index 600f5d6a3f..cb85782abf 100644 --- a/acts/framework/tests/libs/proc/process_test.py +++ b/acts/framework/tests/libs/proc/process_test.py @@ -13,12 +13,13 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +import subprocess import unittest -import mock -import subprocess from acts.libs.proc.process import Process from acts.libs.proc.process import ProcessError +import mock + class FakeThread(object): def __init__(self, target=None): @@ -137,6 +138,31 @@ class ProcessTest(unittest.TestCase): self.assertEqual(process._kill_process.called, True) + @mock.patch('os.getpgid', side_effect=lambda id: id) + @mock.patch('os.killpg') + def test_sends_signal(self, mock_os, *_): + """Tests that signal is sent to process..""" + process = Process('cmd') + mock_process = mock.Mock() + mock_process.pid = -1 + process._process = mock_process + + process.signal(51641) + + mock_os.assert_called_with(-1, 51641) + + def test_signal_raises_error_on_windows(self, *_): + """Tests that signaling is unsupported in windows with appropriate + error msg.""" + process = Process('cmd') + mock_inner_process = mock.Mock() + mock_inner_process.pid = -1 + process._process = mock_inner_process + + with mock.patch('acts.libs.proc.process._on_windows', True): + with self.assertRaises(ProcessError): + process.signal(51641) + @mock.patch.object(Process, '_kill_process') def test_wait_sets_stopped_to_true_before_process_kill(self, *_): """Tests that stop() sets the _stopped attribute to True. @@ -318,9 +344,9 @@ class ProcessTest(unittest.TestCase): self.assertEqual(Process._Process__start_process.call_count, 2) self.assertEqual(Process._Process__start_process.call_args_list[0][0], - (['1st'], )) + (['1st'],)) self.assertEqual(Process._Process__start_process.call_args_list[1][0], - (['2nd'], )) + (['2nd'],)) def test_exec_loop_does_not_loop_if_stopped(self): process = Process('1st') diff --git a/acts/framework/tests/test_utils/instrumentation/__init__.py b/acts/framework/tests/test_utils/instrumentation/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/acts/framework/tests/test_utils/instrumentation/__init__.py diff --git a/acts/framework/tests/test_utils/instrumentation/device/__init__.py b/acts/framework/tests/test_utils/instrumentation/device/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/acts/framework/tests/test_utils/instrumentation/device/__init__.py diff --git a/acts/framework/tests/test_utils/instrumentation/device/command/instrumentation_command_builder_test.py b/acts/framework/tests/test_utils/instrumentation/device/command/instrumentation_command_builder_test.py new file mode 100755 index 0000000000..954c908654 --- /dev/null +++ b/acts/framework/tests/test_utils/instrumentation/device/command/instrumentation_command_builder_test.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python3 +# +# Copyright 2019 - The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest + +from acts.test_utils.instrumentation.device.command.instrumentation_command_builder \ + import InstrumentationCommandBuilder +from acts.test_utils.instrumentation.device.command.instrumentation_command_builder \ + import InstrumentationTestCommandBuilder + + +class InstrumentationCommandBuilderTest(unittest.TestCase): + + def test__runner_and_manifest_package_definition(self): + builder = InstrumentationCommandBuilder() + builder.set_manifest_package('package') + builder.set_runner('runner') + call = builder.build() + self.assertIn('package/runner', call) + + def test__manifest_package_must_be_defined(self): + builder = InstrumentationCommandBuilder() + + with self.assertRaisesRegex(Exception, '.*package cannot be none.*'): + builder.build() + + def test__runner_must_be_defined(self): + builder = InstrumentationCommandBuilder() + + with self.assertRaisesRegex(Exception, '.*runner cannot be none.*'): + builder.build() + + def test_proto_flag_without_set_proto_path(self): + builder = InstrumentationCommandBuilder() + builder.set_runner('runner') + builder.set_manifest_package('some.manifest.package') + + call = builder.build() + self.assertIn('-f', call) + + def test_proto_flag_with_set_proto_path(self): + builder = InstrumentationCommandBuilder() + builder.set_runner('runner') + builder.set_manifest_package('some.manifest.package') + builder.set_proto_path('/some/proto/path') + + call = builder.build() + self.assertIn('-f /some/proto/path', call) + + def test_set_nohup(self): + builder = InstrumentationCommandBuilder() + builder.set_runner('runner') + builder.set_manifest_package('some.manifest.package') + builder.set_nohup() + + call = builder.build() + self.assertEqual( + call, 'nohup am instrument -f some.manifest.package/runner >> ' + '$EXTERNAL_STORAGE/nohup.log 2>&1') + + def test__key_value_param_definition(self): + builder = InstrumentationCommandBuilder() + builder.set_runner('runner') + builder.set_manifest_package('some.manifest.package') + + builder.add_key_value_param('my_key_1', 'my_value_1') + builder.add_key_value_param('my_key_2', 'my_value_2') + + call = builder.build() + self.assertIn('-e my_key_1 my_value_1', call) + self.assertIn('-e my_key_2 my_value_2', call) + + def test__flags(self): + builder = InstrumentationCommandBuilder() + builder.set_runner('runner') + builder.set_manifest_package('some.manifest.package') + + builder.add_flag('--flag1') + builder.add_flag('--flag2') + + call = builder.build() + self.assertIn('--flag1', call) + self.assertIn('--flag2', call) + + +class InstrumentationTestCommandBuilderTest(unittest.TestCase): + """Test class for + acts/test_utils/instrumentation/instrumentation_call_builder.py + """ + + def test__test_packages_can_not_be_added_if_classes_were_added_first(self): + builder = InstrumentationTestCommandBuilder() + builder.add_test_class('some.tests.Class') + + with self.assertRaisesRegex(Exception, '.*only a list of classes.*'): + builder.add_test_package('some.tests.package') + + def test__test_classes_can_not_be_added_if_packages_were_added_first(self): + builder = InstrumentationTestCommandBuilder() + builder.add_test_package('some.tests.package') + + with self.assertRaisesRegex(Exception, '.*only a list of classes.*'): + builder.add_test_class('some.tests.Class') + + def test__test_classes_and_test_methods_can_be_combined(self): + builder = InstrumentationTestCommandBuilder() + builder.set_runner('runner') + builder.set_manifest_package('some.manifest.package') + builder.add_test_class('some.tests.Class1') + builder.add_test_method('some.tests.Class2', 'favoriteTestMethod') + + call = builder.build() + self.assertIn('some.tests.Class1', call) + self.assertIn('some.tests.Class2', call) + self.assertIn('favoriteTestMethod', call) + + +if __name__ == '__main__': + unittest.main() diff --git a/acts/framework/tests/test_utils/power/tel/lab/init_simulation_test.py b/acts/framework/tests/test_utils/power/tel/lab/init_simulation_test.py index 1bd2f074fc..24fe91a457 100644 --- a/acts/framework/tests/test_utils/power/tel/lab/init_simulation_test.py +++ b/acts/framework/tests/test_utils/power/tel/lab/init_simulation_test.py @@ -17,8 +17,8 @@ import unittest import mobly.config_parser as mobly_config_parser import mock_bokeh -from acts.test_utils.power.tel_simulations.LteSimulation import LteSimulation -from acts.test_utils.power.tel_simulations.UmtsSimulation import UmtsSimulation +from acts.controllers.cellular_lib.LteSimulation import LteSimulation +from acts.controllers.cellular_lib.UmtsSimulation import UmtsSimulation from unittest import mock diff --git a/acts/framework/tests/test_utils/power/tel/lab/power_tel_traffic_e2e_test.py b/acts/framework/tests/test_utils/power/tel/lab/power_tel_traffic_e2e_test.py index ff9599665f..065543ff1e 100644 --- a/acts/framework/tests/test_utils/power/tel/lab/power_tel_traffic_e2e_test.py +++ b/acts/framework/tests/test_utils/power/tel/lab/power_tel_traffic_e2e_test.py @@ -18,7 +18,7 @@ import unittest import mock_bokeh import acts.test_utils.power.cellular.cellular_traffic_power_test as ctpt import mobly.config_parser as mobly_config_parser -from acts.test_utils.power.tel_simulations.LteSimulation import LteSimulation +from acts.controllers.cellular_lib.LteSimulation import LteSimulation from acts.controllers.rohdeschwarz_lib import cmw500_cellular_simulator as cmw from unittest import mock diff --git a/acts/framework/tests/test_utils/power/tel/lab/save_summary_to_file_test.py b/acts/framework/tests/test_utils/power/tel/lab/save_summary_to_file_test.py index 1e1554a0dc..900c3a74da 100644 --- a/acts/framework/tests/test_utils/power/tel/lab/save_summary_to_file_test.py +++ b/acts/framework/tests/test_utils/power/tel/lab/save_summary_to_file_test.py @@ -17,7 +17,7 @@ import unittest import mobly.config_parser as mobly_config_parser import mock_bokeh -from acts.test_utils.power.tel_simulations.LteSimulation import LteSimulation +from acts.controllers.cellular_lib.LteSimulation import LteSimulation from unittest import mock from unittest.mock import mock_open diff --git a/acts/tests/google/wifi/OWNERS b/acts/tests/google/wifi/OWNERS deleted file mode 100644 index 7e868cfe07..0000000000 --- a/acts/tests/google/wifi/OWNERS +++ /dev/null @@ -1,6 +0,0 @@ -bmahadev@google.com -etancohen@google.com -krisr@google.com -mplass@google.com -rpius@google.com -satk@google.com diff --git a/acts/tests/google/wifi/SetupWifiNetworkTest.py b/acts/tests/google/wifi/SetupWifiNetworkTest.py deleted file mode 100644 index 26026ff193..0000000000 --- a/acts/tests/google/wifi/SetupWifiNetworkTest.py +++ /dev/null @@ -1,107 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import logging -import socket -import sys - -from acts import base_test -from acts.controllers.ap_lib import hostapd_ap_preset -from acts.controllers.ap_lib import hostapd_bss_settings -from acts.controllers.ap_lib import hostapd_constants -from acts.controllers.ap_lib import hostapd_config -from acts.controllers.ap_lib import hostapd_security - - -class SetupWifiNetworkTest(base_test.BaseTestClass): - def wait_for_test_completion(self): - port = int(self.user_params["socket_port"]) - timeout = float(self.user_params["socket_timeout_secs"]) - - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) - - server_address = ('localhost', port) - logging.info("Starting server socket on localhost port %s", port) - sock.bind(('localhost', port)) - sock.settimeout(timeout) - sock.listen(1) - logging.info("Waiting for client socket connection") - try: - connection, client_address = sock.accept() - except socket.timeout: - logging.error("Did not receive signal. Shutting down AP") - except socket.error: - logging.error("Socket connection errored out. Shutting down AP") - finally: - connection.close() - sock.shutdown(socket.SHUT_RDWR) - sock.close() - - def setup_ap(self): - bss_settings = [] - self.access_point = self.access_points[0] - network_type = self.user_params["network_type"] - if (network_type == "2G"): - self.channel = hostapd_constants.AP_DEFAULT_CHANNEL_2G - else: - self.channel = hostapd_constants.AP_DEFAULT_CHANNEL_5G - - self.ssid = self.user_params["ssid"] - self.security = self.user_params["security"] - if self.security == "none": - self.config = hostapd_ap_preset.create_ap_preset( - channel=self.channel, - ssid=self.ssid, - bss_settings=bss_settings, - profile_name='whirlwind') - else: - self.passphrase = self.user_params["passphrase"] - self.hostapd_security = hostapd_security.Security( - security_mode=self.security, password=self.passphrase) - self.config = hostapd_ap_preset.create_ap_preset( - channel=self.channel, - ssid=self.ssid, - security=self.hostapd_security, - bss_settings=bss_settings, - profile_name='whirlwind') - self.access_point.start_ap(self.config) - - def test_set_up_single_ap(self): - req_params = [ - "AccessPoint", "network_type", "ssid", "passphrase", "security", - "socket_port", "socket_timeout_secs" - ] - opt_params = [] - self.unpack_userparams( - req_param_names=req_params, opt_param_names=opt_params) - # Setup the AP environment - self.setup_ap() - # AP enviroment created. Wait for client to teardown the environment - self.wait_for_test_completion() - - def test_set_up_open_ap(self): - req_params = [ - "AccessPoint", "network_type", "ssid", "security", "socket_port", - "socket_timeout_secs" - ] - opt_params = [] - self.unpack_userparams( - req_param_names=req_params, opt_param_names=opt_params) - # Setup the AP environment - self.setup_ap() - # AP enviroment created. Wait for client to teardown the environment - self.wait_for_test_completion() diff --git a/acts/tests/google/wifi/WifiAutoJoinTest.py b/acts/tests/google/wifi/WifiAutoJoinTest.py deleted file mode 100755 index 829fc6c0d3..0000000000 --- a/acts/tests/google/wifi/WifiAutoJoinTest.py +++ /dev/null @@ -1,491 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2016 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import time - -from acts import asserts -from acts import base_test -from acts.test_utils.wifi import wifi_constants -from acts.test_utils.wifi import wifi_test_utils as wutils - -WifiEnums = wutils.WifiEnums -NETWORK_ID_ERROR = "Network don't have ID" -NETWORK_ERROR = "Device is not connected to reference network" - - -class WifiAutoJoinTest(base_test.BaseTestClass): - def __init__(self, controllers): - base_test.BaseTestClass.__init__(self, controllers) - self.tests = ("test_autojoin_out_of_range", - "test_autojoin_Ap1_2g", - "test_autojoin_Ap1_2gto5g", - "test_autojoin_in_AP1_5gto2g", - "test_autojoin_swtich_AP1toAp2", - "test_autojoin_Ap2_2gto5g", - "test_autojoin_Ap2_5gto2g", - "test_autojoin_out_of_range", - "test_autojoin_Ap2_2g", - "test_autojoin_Ap2_2gto5g", - "test_autojoin_in_Ap2_5gto2g", - "test_autojoin_swtich_AP2toAp1", - "test_autojoin_Ap1_2gto5g", - "test_autojoin_Ap1_5gto2g", - "test_autojoin_swtich_to_blacklist_AP", - "test_autojoin_in_blacklist_AP", - "test_autojoin_back_from_blacklist_AP", ) - - def setup_class(self): - """It will setup the required dependencies from config file and configure - the required networks for auto-join testing. Configured networks will - not be removed. If networks are already configured it will skip - configuring the networks - - Returns: - True if successfully configured the requirements for testing. - """ - self.dut = self.android_devices[0] - wutils.wifi_test_device_init(self.dut) - req_params = ("reference_networks", "other_network", "atten_val", - "ping_addr", "max_bugreports") - self.unpack_userparams(req_params) - self.log.debug("Connect networks :: {}".format(self.other_network)) - configured_networks = self.dut.droid.wifiGetConfiguredNetworks() - self.log.debug("Configured networks :: {}".format(configured_networks)) - count_confnet = 0 - result = False - if self.reference_networks[0]['2g']['ssid'] == self.reference_networks[ - 0]['5g']['ssid']: - self.ref_ssid_count = 1 - else: - self.ref_ssid_count = 2 # Different SSID for 2g and 5g - for confnet in configured_networks: - if confnet[WifiEnums.SSID_KEY] == self.reference_networks[0]['2g'][ - 'ssid']: - count_confnet += 1 - elif confnet[WifiEnums.SSID_KEY] == self.reference_networks[0][ - '5g']['ssid']: - count_confnet += 1 - self.log.info("count_confnet {}".format(count_confnet)) - if count_confnet == self.ref_ssid_count: - return - else: - self.log.info("Configured networks for testing") - self.attenuators[0].set_atten(0) - self.attenuators[1].set_atten(90) - self.attenuators[2].set_atten(90) - wait_time = 15 - self.dut.droid.wakeLockAcquireBright() - self.dut.droid.wakeUpNow() - try: - self.dut.droid.wifiConnectByConfig(self.reference_networks[0][ - '2g']) - connect_result = self.dut.ed.pop_event( - wifi_constants.CONNECT_BY_CONFIG_SUCCESS, 1) - self.log.info(connect_result) - time.sleep(wait_time) - if self.ref_ssid_count == 2: #add 5g network as well - self.dut.droid.wifiConnectByConfig(self.reference_networks[ - 0]['5g']) - connect_result = self.dut.ed.pop_event( - wifi_constants.CONNECT_BY_CONFIG_SUCCESS, 1) - self.log.info(connect_result) - time.sleep(wait_time) - self.dut.droid.wifiConnectByConfig(self.other_network) - connect_result = self.dut.ed.pop_event( - wifi_constants.CONNECT_BY_CONFIG_SUCCESS) - self.log.info(connect_result) - wutils.track_connection(self.dut, self.other_network["ssid"], 1) - wutils.wifi_forget_network(self.dut, self.other_network["ssid"]) - time.sleep(wait_time) - current_network = self.dut.droid.wifiGetConnectionInfo() - self.log.info("Current network: {}".format(current_network)) - asserts.assert_true('network_id' in current_network, - NETWORK_ID_ERROR) - asserts.assert_true(current_network['network_id'] >= 0, - NETWORK_ERROR) - finally: - self.dut.droid.wifiLockRelease() - self.dut.droid.goToSleepNow() - - def check_connection(self, network_bssid): - """Check current wifi connection networks. - Args: - network_bssid: Network bssid to which connection. - Returns: - True if connection to given network happen, else return False. - """ - time.sleep(40) #time for connection state to be updated - self.log.info("Check network for {}".format(network_bssid)) - current_network = self.dut.droid.wifiGetConnectionInfo() - self.log.debug("Current network: {}".format(current_network)) - if WifiEnums.BSSID_KEY in current_network: - return current_network[WifiEnums.BSSID_KEY] == network_bssid - return False - - def set_attn_and_validate_connection(self, attn_value, bssid): - """Validate wifi connection status on different attenuation setting. - - Args: - attn_value: Attenuation value for different APs signal. - bssid: Bssid of excepted network. - - Returns: - True if bssid of current network match, else false. - """ - self.attenuators[0].set_atten(attn_value[0]) - self.attenuators[1].set_atten(attn_value[1]) - self.attenuators[2].set_atten(attn_value[2]) - self.dut.droid.wakeLockAcquireBright() - self.dut.droid.wakeUpNow() - try: - asserts.assert_true( - self.check_connection(bssid), - "Device is not connected to required bssid {}".format(bssid)) - time.sleep(10) #wait for connection to be active - asserts.assert_true( - wutils.validate_connection(self.dut, self.ping_addr), - "Error, No Internet connection for current bssid {}".format( - bssid)) - finally: - self.dut.droid.wifiLockRelease() - self.dut.droid.goToSleepNow() - - def on_fail(self, test_name, begin_time): - if self.max_bugreports > 0: - self.dut.take_bug_report(test_name, begin_time) - self.max_bugreports -= 1 - self.dut.cat_adb_log(test_name, begin_time) - - """ Tests Begin """ - - def test_autojoin_Ap1_2g(self): - """Test wifi auto join functionality move in range of AP1. - - 1. Attenuate the signal to low range of AP1 and Ap2 not visible at all. - 2. Wake up the device. - 3. Check that device is connected to right BSSID and maintain stable - connection to BSSID in range. - """ - att0, att1, att2 = self.atten_val["Ap1_2g"] - variance = 5 - attenuations = ([att0 + variance * 2, att1, att2], - [att0 + variance, att1, att2], [att0, att1, att2], - [att0 - variance, att1, att2]) - name_func = lambda att_value, bssid: ("test_autojoin_Ap1_2g_AP1_{}_AP2" - "_{}_AP3_{}").format(att_value[0], att_value[1], att_value[2]) - failed = self.run_generated_testcases( - self.set_attn_and_validate_connection, - attenuations, - args=(self.reference_networks[0]["2g"]['bssid'], ), - name_func=name_func) - asserts.assert_false( - failed, - "Number of test_autojoin_Ap1_2g failed {}".format(len(failed))) - - def test_autojoin_Ap1_2gto5g(self): - """Test wifi auto join functionality move to high range. - - 1. Attenuate the signal to high range of AP1. - 2. Wake up the device. - 3. Check that device is connected to right BSSID and maintain stable - connection to BSSID in range. - """ - att0, att1, att2 = self.atten_val["Ap1_2gto5g"] - variance = 5 - attenuations = ([att0 + variance * 2, att1, att2], - [att0 + variance, att1, att2], [att0, att1, att2]) - name_func = lambda att_value, bssid: ("test_autojoin_Ap1_2gto5g_AP1_{}_AP2" - "_{}_AP3_{}").format(att_value[0], att_value[1], att_value[2]) - failed = self.run_generated_testcases( - self.set_attn_and_validate_connection, - attenuations, - args=(self.reference_networks[0]["5g"]['bssid'], ), - name_func=name_func) - asserts.assert_false( - failed, - "Number of test_autojoin_Ap1_2gto5g failed {}".format(len(failed))) - - def test_autojoin_in_AP1_5gto2g(self): - """Test wifi auto join functionality move to low range toward AP2. - - 1. Attenuate the signal to medium range of AP1 and low range of AP2. - 2. Wake up the device. - 3. Check that device is connected to right BSSID and maintain stable - connection to BSSID in range. - """ - att0, att1, att2 = self.atten_val["In_AP1_5gto2g"] - variance = 5 - attenuations = ([att0 - variance, att1 + variance, att2], - [att0, att1, att2], - [att0 + variance, att1 - variance, att2]) - name_func = lambda att_value, bssid: ("test_autojoin_in_AP1_5gto2g_AP1_{}_AP2" - "_{}_AP3_{}").format(att_value[0], att_value[1], att_value[2]) - failed = self.run_generated_testcases( - self.set_attn_and_validate_connection, - attenuations, - args=(self.reference_networks[0]["2g"]['bssid'], ), - name_func=name_func) - asserts.assert_false( - failed, "Number of test_autojoin_in_AP1_5gto2g failed {}".format( - len(failed))) - - def test_autojoin_swtich_AP1toAp2(self): - """Test wifi auto join functionality move from low range of AP1 to better - range of AP2. - - 1. Attenuate the signal to low range of AP1 and medium range of AP2. - 2. Wake up the device. - 3. Check that device is connected to right BSSID and maintain stable - connection to BSSID in range. - """ - att0, att1, att2 = self.atten_val["Swtich_AP1toAp2"] - variance = 5 - attenuations = ([att0 - variance, att1 + variance, att2], - [att0, att1, att2], - [att0 + variance, att1 - variance, att2]) - name_func = lambda att_value, bssid: ("test_autojoin_swtich_AP1toAp2_AP1_{}_AP2" - "_{}_AP3_{}").format(att_value[0], att_value[1], att_value[2]) - failed = self.run_generated_testcases( - self.set_attn_and_validate_connection, - attenuations, - args=(self.reference_networks[1]["2g"]['bssid'], ), - name_func=name_func) - asserts.assert_false( - failed, "Number of test_autojoin_swtich_AP1toAp2 failed {}".format( - len(failed))) - - def test_autojoin_Ap2_2gto5g(self): - """Test wifi auto join functionality move to high range of AP2. - - 1. Attenuate the signal to out range of AP1 and high range of AP2. - 2. Wake up the device. - 3. Check that device is connected to right BSSID and maintain stable - connection to BSSID in range. - """ - att0, att1, att2 = self.atten_val["Ap2_2gto5g"] - variance = 5 - attenuations = ([att0 - variance, att1 + variance * 2, att2], - [att0, att1 + variance, att2], [att0, att1, att2]) - name_func = lambda att_value, bssid: ("test_autojoin_Ap2_2gto5g_AP1_{}_AP2" - "_{}_AP3_{}").format(att_value[0], att_value[1], att_value[2]) - failed = self.run_generated_testcases( - self.set_attn_and_validate_connection, - attenuations, - args=(self.reference_networks[1]["5g"]['bssid'], ), - name_func=name_func) - asserts.assert_false( - failed, - "Number of test_autojoin_Ap2_2gto5g failed {}".format(len(failed))) - - def test_autojoin_Ap2_5gto2g(self): - """Test wifi auto join functionality move to low range of AP2. - - 1. Attenuate the signal to low range of AP2. - 2. Wake up the device. - 3. Check that device is connected to right BSSID and maintain stable. - """ - att0, att1, att2 = self.atten_val["Ap2_5gto2g"] - variance = 5 - attenuations = ([att0, att1 - variance, att2], [att0, att1, att2], - [att0, att1 + variance, att2]) - name_func = lambda att_value, bssid: ("test_autojoin_Ap2_5gto2g_AP1_{}_AP2" - "_{}_AP3_{}").format(att_value[0], att_value[1], att_value[2]) - failed = self.run_generated_testcases( - self.set_attn_and_validate_connection, - attenuations, - args=(self.reference_networks[1]["2g"]['bssid'], ), - name_func=name_func) - asserts.assert_false( - failed, - "Number of test_autojoin_Ap2_5gto2g failed {}".format(len(failed))) - - def test_autojoin_out_of_range(self): - """Test wifi auto join functionality move to low range. - - 1. Attenuate the signal to out of range. - 2. Wake up the device. - 3. Start the scan. - 4. Check that device is not connected to any network. - """ - self.attenuators[0].set_atten(90) - self.attenuators[1].set_atten(90) - self.attenuators[2].set_atten(90) - self.dut.droid.wakeLockAcquireBright() - self.dut.droid.wakeUpNow() - try: - wutils.start_wifi_connection_scan(self.dut) - wifi_results = self.dut.droid.wifiGetScanResults() - self.log.debug("Scan result {}".format(wifi_results)) - time.sleep(20) - current_network = self.dut.droid.wifiGetConnectionInfo() - self.log.info("Current network: {}".format(current_network)) - asserts.assert_true( - ('network_id' in current_network and - current_network['network_id'] == -1), - "Device is connected to network {}".format(current_network)) - finally: - self.dut.droid.wifiLockRelease() - self.dut.droid.goToSleepNow() - - def test_autojoin_Ap2_2g(self): - """Test wifi auto join functionality move in low range of AP2. - - 1. Attenuate the signal to move in range of AP2 and Ap1 not visible at all. - 2. Wake up the device. - 3. Check that device is connected to right BSSID and maintain stable - connection to BSSID in range. - """ - att0, att1, att2 = self.atten_val["Ap2_2g"] - variance = 5 - attenuations = ([att0, att1 + variance * 2, att2], - [att0, att1 + variance, att2], [att0, att1, att2], - [att0, att1 - variance, att2]) - name_func = lambda att_value, bssid: ("test_autojoin_Ap2_2g_AP1_{}_AP2" - "_{}_AP3_{}").format(att_value[0], att_value[1], att_value[2]) - failed = self.run_generated_testcases( - self.set_attn_and_validate_connection, - attenuations, - args=(self.reference_networks[1]["2g"]['bssid'], ), - name_func=name_func) - asserts.assert_false( - failed, - "Number of test_autojoin_Ap2_2g failed {}".format(len(failed))) - - def test_autojoin_in_Ap2_5gto2g(self): - """Test wifi auto join functionality move to medium range of Ap2 and - low range of AP1. - - 1. Attenuate the signal to move in medium range of AP2 and low range of AP1. - 2. Wake up the device. - 3. Check that device is connected to right BSSID and maintain stable - connection to BSSID in range. - """ - att0, att1, att2 = self.atten_val["In_Ap2_5gto2g"] - variance = 5 - attenuations = ([att0, att1 - variance, att2], [att0, att1, att2], - [att0, att1 + variance, att2]) - name_func = lambda att_value, bssid: ("test_autojoin_in_Ap2_5gto2g_AP1_{}_AP2" - "_{}_AP3_{}").format(att_value[0], att_value[1], att_value[2]) - failed = self.run_generated_testcases( - self.set_attn_and_validate_connection, - attenuations, - args=(self.reference_networks[1]["2g"]['bssid'], ), - name_func=name_func) - asserts.assert_false( - failed, "Number of test_autojoin_in_Ap2_5gto2g failed {}".format( - len(failed))) - - def test_autojoin_swtich_AP2toAp1(self): - """Test wifi auto join functionality move from low range of AP2 to better - range of AP1. - - 1. Attenuate the signal to low range of AP2 and medium range of AP1. - 2. Wake up the device. - 3. Check that device is connected to right BSSID and maintain stable - connection to BSSID in range. - """ - att0, att1, att2 = self.atten_val["Swtich_AP2toAp1"] - variance = 5 - attenuations = ([att0 + variance, att1 - variance, att2], - [att0, att1, att2], - [att0 - variance, att1 + variance, att2]) - name_func = lambda att_value, bssid: ("test_autojoin_swtich_AP2toAp1_AP1_{}_AP2" - "_{}_AP3_{}").format(att_value[0], att_value[1], att_value[2]) - failed = self.run_generated_testcases( - self.set_attn_and_validate_connection, - attenuations, - args=(self.reference_networks[0]["2g"]['bssid'], ), - name_func=name_func) - asserts.assert_false( - failed, "Number of test_autojoin_swtich_AP2toAp1 failed {}".format( - len(failed))) - - def test_autojoin_Ap1_5gto2g(self): - """Test wifi auto join functionality move to medium range of AP1. - - 1. Attenuate the signal to medium range of AP1. - 2. Wake up the device. - 3. Check that device is connected to right BSSID and maintain stable - connection to BSSID in range. - """ - att0, att1, att2 = self.atten_val["Ap1_5gto2g"] - variance = 5 - attenuations = ([att0, att1, att2], [att0 + variance, att1, att2], - [att0 + variance * 2, att1, att2]) - name_func = lambda att_value, bssid: ("test_autojoin_Ap1_5gto2g_AP1_{}_AP2" - "_{}_AP3_{}").format(att_value[0], att_value[1], att_value[2]) - failed = self.run_generated_testcases( - self.set_attn_and_validate_connection, - attenuations, - args=(self.reference_networks[0]["2g"]['bssid'], ), - name_func=name_func) - asserts.assert_false( - failed, - "Number of test_autojoin_Ap1_5gto2g failed {}".format(len(failed))) - - def test_autojoin_swtich_to_blacklist_AP(self): - """Test wifi auto join functionality in medium range of blacklist BSSID. - - 1. Attenuate the signal to low range of AP1 and medium range of AP3. - 2. Wake up the device. - 3. Check that device is connected to AP1 BSSID and maintain stable - connection to BSSID. - """ - self.set_attn_and_validate_connection( - self.atten_val["Swtich_to_blacklist"], - self.reference_networks[0]["2g"]['bssid']) - - def test_autojoin_in_blacklist_AP(self): - """Test wifi auto join functionality in high range of blacklist BSSID. - - 1. Attenuate the signal to out of range of AP1 and full range of AP3. - 2. Wake up the device. - 3. Check that device is disconnected form all AP. - """ - attn0, attn1, attn2 = self.atten_val["In_blacklist"] - self.attenuators[0].set_atten(attn0) - self.attenuators[1].set_atten(attn1) - self.attenuators[2].set_atten(attn2) - self.dut.droid.wakeLockAcquireBright() - self.dut.droid.wakeUpNow() - try: - wutils.start_wifi_connection_scan(self.dut) - wifi_results = self.dut.droid.wifiGetScanResults() - self.log.debug("Scan result {}".format(wifi_results)) - time.sleep(20) - current_network = self.dut.droid.wifiGetConnectionInfo() - self.log.info("Current network: {}".format(current_network)) - asserts.assert_true( - ('network_id' in current_network and - current_network['network_id'] == -1), - "Device is still connected to blacklisted network {}".format( - current_network)) - finally: - self.dut.droid.wifiLockRelease() - self.dut.droid.goToSleepNow() - - def test_autojoin_back_from_blacklist_AP(self): - """Test wifi auto join functionality in medium range of blacklist BSSID. - - 1. Attenuate the signal to medium of range of AP1 and low range of AP3. - 2. Wake up the device. - 3. Check that device is disconnected form all AP. - """ - self.set_attn_and_validate_connection( - self.atten_val["Back_from_blacklist"], - self.reference_networks[0]["2g"]['bssid']) - - """ Tests End """ diff --git a/acts/tests/google/wifi/WifiAutoUpdateTest.py b/acts/tests/google/wifi/WifiAutoUpdateTest.py deleted file mode 100755 index 33369a2775..0000000000 --- a/acts/tests/google/wifi/WifiAutoUpdateTest.py +++ /dev/null @@ -1,242 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import itertools -import pprint -import queue -import time - -import acts.base_test -import acts.signals as signals -import acts.test_utils.wifi.wifi_test_utils as wutils -import acts.utils - -from acts import asserts -from acts.libs.ota import ota_updater -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest - -WifiEnums = wutils.WifiEnums -# Default timeout used for reboot, toggle WiFi and Airplane mode, -# for the system to settle down after the operation. -DEFAULT_TIMEOUT = 10 -BAND_2GHZ = 0 -BAND_5GHZ = 1 - - -class WifiAutoUpdateTest(WifiBaseTest): - """Tests for APIs in Android's WifiManager class. - - Test Bed Requirement: - * One Android device - * Several Wi-Fi networks visible to the device, including an open Wi-Fi - network. - """ - - def __init__(self, controllers): - WifiBaseTest.__init__(self, controllers) - self.tests = ( - "test_check_wifi_state_after_au", - "test_verify_networks_after_au", - "test_all_networks_connectable_after_au", - "test_connection_to_new_networks", - "test_check_wifi_toggling_after_au", - "test_reset_wifi_after_au") - - def setup_class(self): - super(WifiAutoUpdateTest, self).setup_class() - ota_updater.initialize(self.user_params, self.android_devices) - self.dut = self.android_devices[0] - wutils.wifi_test_device_init(self.dut) - req_params = [] - opt_param = [ - "open_network", "reference_networks", "iperf_server_address" - ] - self.unpack_userparams( - req_param_names=req_params, opt_param_names=opt_param) - - if "AccessPoint" in self.user_params: - self.legacy_configure_ap_and_start() - - asserts.assert_true( - len(self.reference_networks) > 0, - "Need at least two reference network with psk.") - asserts.assert_true( - len(self.open_network) > 0, - "Need at least two open network with psk.") - wutils.wifi_toggle_state(self.dut, True) - - self.wifi_config_list = [] - - # Disabling WiFi setup before OTA for debugging. - # Setup WiFi and add few open and wpa networks before OTA. - # self.add_network_and_enable(self.open_network[0]['2g']) - # self.add_network_and_enable(self.reference_networks[0]['5g']) - - # Add few dummy networks to the list. - # self.add_and_enable_dummy_networks() - - # Run OTA below, if ota fails then abort all tests. - try: - ota_updater.update(self.dut) - except Exception as err: - raise signals.TestAbortClass( - "Failed up apply OTA update. Aborting tests") - - def setup_test(self): - self.dut.droid.wakeLockAcquireBright() - self.dut.droid.wakeUpNow() - - def teardown_test(self): - self.dut.droid.wakeLockRelease() - self.dut.droid.goToSleepNow() - - def on_fail(self, test_name, begin_time): - self.dut.take_bug_report(test_name, begin_time) - self.dut.cat_adb_log(test_name, begin_time) - - def teardown_class(self): - if "AccessPoint" in self.user_params: - del self.user_params["reference_networks"] - del self.user_params["open_network"] - - """Helper Functions""" - - def add_network_and_enable(self, network): - """Add a network and enable it. - - Args: - network : Network details for the network to be added. - - """ - ret = self.dut.droid.wifiAddNetwork(network) - asserts.assert_true(ret != -1, "Add network %r failed" % network) - self.wifi_config_list.append({ - WifiEnums.SSID_KEY: network[WifiEnums.SSID_KEY], - WifiEnums.NETID_KEY: ret}) - self.dut.droid.wifiEnableNetwork(ret, 0) - - def add_and_enable_dummy_networks(self, num_networks=5): - """Add some dummy networks to the device and enable them. - - Args: - num_networks: Number of networks to add. - """ - ssid_name_base = "dummy_network_" - for i in range(0, num_networks): - network = {} - network[WifiEnums.SSID_KEY] = ssid_name_base + str(i) - network[WifiEnums.PWD_KEY] = "dummynet_password" - self.add_network_and_enable(network) - - def check_networks_after_autoupdate(self, networks): - """Verify that all previously configured networks are presistent after - reboot. - - Args: - networks: List of network dicts. - - Return: - None. Raises TestFailure. - - """ - network_info = self.dut.droid.wifiGetConfiguredNetworks() - if len(network_info) != len(networks): - msg = ( - "Number of configured networks before and after Auto-update " - "don't match. \nBefore reboot = %s \n After reboot = %s" % - (networks, network_info)) - raise signals.TestFailure(msg) - current_count = 0 - # For each network, check if it exists in configured list after Auto- - # update. - for network in networks: - exists = wutils.match_networks({ - WifiEnums.SSID_KEY: network[WifiEnums.SSID_KEY] - }, network_info) - if not len(exists): - raise signals.TestFailure("%s network is not present in the" - " configured list after Auto-update" % - network[WifiEnums.SSID_KEY]) - # Get the new network id for each network after reboot. - network[WifiEnums.NETID_KEY] = exists[0]['networkId'] - - """Tests""" - - @test_tracker_info(uuid="9ff1f01e-e5ff-408b-9a95-29e87a2df2d8") - def test_check_wifi_state_after_au(self): - """Check if the state of WiFi is enabled after Auto-update.""" - if not self.dut.droid.wifiCheckState(): - raise signals.TestFailure("WiFi is disabled after Auto-update!!!") - - @test_tracker_info(uuid="e3ebdbba-71dd-4281-aef8-5b3d42b88770") - def test_verify_networks_after_au(self): - """Check if the previously added networks are intact. - - Steps: - Number of networs should be the same and match each network. - - """ - self.check_networks_after_autoupdate(self.wifi_config_list) - - @test_tracker_info(uuid="b8e47a4f-62fe-4a0e-b999-27ae1ebf4d19") - def test_connection_to_new_networks(self): - """Check if we can connect to new networks after Auto-update. - - Steps: - 1. Connect to a PSK network. - 2. Connect to an open network. - 3. Forget ntworks added in 1 & 2. - TODO: (@bmahadev) Add WEP network once it's ready. - - """ - wutils.connect_to_wifi_network(self.dut, self.open_network[0]['5g']) - wutils.connect_to_wifi_network(self.dut, self.reference_networks[0]['2g']) - wutils.wifi_forget_network(self.dut, - self.reference_networks[0]['2g'][WifiEnums.SSID_KEY]) - wutils.wifi_forget_network(self.dut, - self.open_network[0]['5g'][WifiEnums.SSID_KEY]) - - @test_tracker_info(uuid="1d8309e4-d5a2-4f48-ba3b-895a58c9bf3a") - def test_all_networks_connectable_after_au(self): - """Check if previously added networks are connectable. - - Steps: - 1. Connect to previously added PSK network using network id. - 2. Connect to previously added open network using network id. - TODO: (@bmahadev) Add WEP network once it's ready. - - """ - for network in self.wifi_config_list: - if 'dummy' not in network[WifiEnums.SSID_KEY]: - if not wutils.connect_to_wifi_network_with_id(self.dut, - network[WifiEnums.NETID_KEY], - network[WifiEnums.SSID_KEY]): - raise signals.TestFailure("Failed to connect to %s after \ - Auto-update" % network[WifiEnums.SSID_KEY]) - - @test_tracker_info(uuid="05671859-38b1-4dbf-930c-18048971d075") - def test_check_wifi_toggling_after_au(self): - """Check if WiFi can be toggled ON/OFF after auto-update.""" - self.log.debug("Going from on to off.") - wutils.wifi_toggle_state(self.dut, False) - self.log.debug("Going from off to on.") - wutils.wifi_toggle_state(self.dut, True) - - @test_tracker_info(uuid="440edf32-4b00-42b0-9811-9f2bc4a83efb") - def test_reset_wifi_after_au(self): - """"Check if WiFi can be reset after auto-update.""" - wutils.reset_wifi(self.dut) diff --git a/acts/tests/google/wifi/WifiChaosTest.py b/acts/tests/google/wifi/WifiChaosTest.py deleted file mode 100755 index d0a3722f9f..0000000000 --- a/acts/tests/google/wifi/WifiChaosTest.py +++ /dev/null @@ -1,364 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2018 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# 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 -import acts.signals as signals -import acts.test_utils.wifi.rpm_controller_utils as rutils -import acts.test_utils.wifi.wifi_datastore_utils as dutils -import acts.test_utils.wifi.wifi_test_utils as wutils - -from acts import asserts -from acts.base_test import BaseTestClass -from acts.controllers.ap_lib import hostapd_constants -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest - -WifiEnums = wutils.WifiEnums - -WAIT_BEFORE_CONNECTION = 1 -SINGLE_BAND = 1 -DUAL_BAND = 2 - -TIMEOUT = 60 -TEST = 'test_' -PING_ADDR = 'www.google.com' - -NUM_LINK_PROBES = 3 -PROBE_DELAY_SEC = 1 - - -class WifiChaosTest(WifiBaseTest): - """ Tests for wifi IOT - - Test Bed Requirement: - * One Android device - * Wi-Fi IOT networks visible to the device - """ - - def __init__(self, configs): - 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. - - Args: - base_test: The base test case function to run. - testcase_name: The name of the test case. - ssid_dict: The information about the network under test. - """ - ssid = testcase_name - test_tracker_uuid = ssid_dict[testcase_name]['uuid'] - hostname = ssid_dict[testcase_name]['host'] - if not testcase_name.startswith('test_'): - testcase_name = 'test_%s' % testcase_name - test_case = test_tracker_info(uuid=test_tracker_uuid)( - lambda: base_test(ssid, hostname)) - setattr(self, testcase_name, test_case) - self.tests.append(testcase_name) - - def generate_interop_tests(self): - for ssid_dict in self.user_params['interop_ssid']: - 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". - wutils.set_wifi_country_code(self.dut, wutils.WifiEnums.CountryCode.US) - - asserts.assert_true( - self.lock_pcap(), - "Could not lock a Packet Capture. Aborting Interop test.") - - wutils.wifi_toggle_state(self.dut, True) - - def lock_pcap(self): - """Lock a Packet Capturere to use for the test.""" - - # Get list of devices from the datastore. - locked_pcap = False - devices = dutils.get_devices() - - for device in devices: - - device_name = device['hostname'] - device_type = device['ap_label'] - 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 - - pcap_config = {'ssh_config':{'user':'root'} } - pcap_config['ssh_config']['host'] = host - - self.pcap = packet_capture.PacketCapture(pcap_config) - return True - - def setup_test(self): - self.dut.droid.wakeLockAcquireBright() - self.dut.droid.wakeUpNow() - - def on_pass(self, test_name, begin_time): - wutils.stop_pcap(self.pcap, self.pcap_procs, True) - - def on_fail(self, test_name, begin_time): - # Sleep to ensure all failed packets are captured. - time.sleep(5) - wutils.stop_pcap(self.pcap, self.pcap_procs, 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() - - 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""" - - def scan_and_connect_by_id(self, network, net_id): - """Scan for network and connect using network id. - - Args: - net_id: Integer specifying the network id of the network. - - """ - ssid = network[WifiEnums.SSID_KEY] - wutils.start_wifi_connection_scan_and_ensure_network_found(self.dut, - ssid) - wutils.wifi_connect_by_id(self.dut, net_id) - - def run_ping(self, sec): - """Run ping for given number of seconds. - - Args: - sec: Time in seconds to run teh ping traffic. - - """ - self.log.info("Finding Gateway...") - route_response = self.dut.adb.shell("ip route get 8.8.8.8") - gateway_ip = re.search('via (.*) dev', str(route_response)).group(1) - self.log.info("Gateway IP = %s" % gateway_ip) - self.log.info("Running ping for %d seconds" % sec) - result = self.dut.adb.shell("ping -w %d %s" % (sec, gateway_ip), - timeout=sec + 1) - self.log.debug("Ping Result = %s" % result) - if "100% packet loss" in result: - raise signals.TestFailure("100% packet loss during ping") - - def send_link_probes(self, network): - """ - Send link probes, and verify that the device and AP did not crash. - Also verify that at least one link probe succeeded. - - Steps: - 1. Send a few link probes. - 2. Ensure that the device and AP did not crash (by checking that the - device remains connected to the expected network). - """ - results = wutils.send_link_probes( - self.dut, NUM_LINK_PROBES, PROBE_DELAY_SEC) - - self.log.info("Link Probe results: %s" % (results,)) - - wifi_info = self.dut.droid.wifiGetConnectionInfo() - expected = network[WifiEnums.SSID_KEY] - actual = wifi_info[WifiEnums.SSID_KEY] - asserts.assert_equal( - expected, actual, - "Device did not remain connected after sending link probes!") - - 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. - 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(5): - try: - begin_time = time.time() - ssid = network[WifiEnums.SSID_KEY] - net_id = self.dut.droid.wifiAddNetwork(network) - 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(10) - # TODO(b/133369482): uncomment once bug is resolved - # self.send_link_probes(network) - wutils.wifi_forget_network(self.dut, ssid) - time.sleep(WAIT_BEFORE_CONNECTION) - except Exception as e: - self.log.error("Connection to %s network failed on the %d " - "attempt with exception %s." % (ssid, attempt, e)) - # 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. - - Args: - ssid: string, SSID of the network to connect to. - hostname: string, hostname of the AP. - - Steps: - 1. Lock AP in datstore. - 2. Turn on AP on the rpm switch. - 3. Run connect-disconnect in loop. - 4. Turn off AP on the rpm switch. - 5. Unlock AP in datastore. - - """ - 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") - - 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") - - 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'] - rpm_port = ap_info['rpm_port'] - - rutils.turn_on_ap(self.pcap, ssid, rpm_port, rpm_ip=rpm_ip) - self.log.info("Finished turning ON AP.") - # Experimental. Some APs take upto a min to come online. - time.sleep(60) - - self.get_band_and_chan(ssid) - self.pcap.configure_monitor_mode(self.band, self.chan) - self.pcap_procs = wutils.start_pcap( - self.pcap, self.band.lower(), 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 release_ap: - self.unlock_and_turn_off_ap(hostname, rpm_port, rpm_ip) diff --git a/acts/tests/google/wifi/WifiConnectedMacRandomizationTest.py b/acts/tests/google/wifi/WifiConnectedMacRandomizationTest.py deleted file mode 100644 index bd10a8b9a7..0000000000 --- a/acts/tests/google/wifi/WifiConnectedMacRandomizationTest.py +++ /dev/null @@ -1,258 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2018 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import itertools -import pprint -import queue -import time - -import acts.base_test -import acts.signals as signals -from acts.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_2G -import acts.test_utils.wifi.wifi_test_utils as wutils -import acts.utils as utils - -from acts import asserts -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest - -WifiEnums = wutils.WifiEnums -# Default timeout used for reboot, toggle WiFi and Airplane mode, -# for the system to settle down after the operation. -DEFAULT_TIMEOUT = 10 -GET_MAC_ADDRESS= ("ip addr show wlan0" - "| grep 'link/ether'" - "| cut -d ' ' -f6") -MAC_SETTING = "wifi_connected_mac_randomization_enabled" -GET_MAC_RANDOMIZATION_STATUS = "settings get global {}".format(MAC_SETTING) -TURN_ON_MAC_RANDOMIZATION = "settings put global {} 1".format(MAC_SETTING) -TURN_OFF_MAC_RANDOMIZATION = "settings put global {} 0".format(MAC_SETTING) -LOG_CLEAR = "logcat -c" -LOG_GREP = "logcat -d | grep {}" - -class WifiConnectedMacRandomizationTest(WifiBaseTest): - """Tests for Connected MAC Randomization. - - Test Bed Requirement: - * Two Android devices with the first one supporting MAC randomization. - * At least two Wi-Fi networks to connect to. - """ - - def setup_class(self): - super().setup_class() - - self.dut = self.android_devices[0] - self.dut_softap = self.android_devices[1] - wutils.wifi_test_device_init(self.dut) - wutils.wifi_test_device_init(self.dut_softap) - - self.reset_mac_address_to_factory_mac() - self.dut.adb.shell(TURN_ON_MAC_RANDOMIZATION) - asserts.assert_equal( - self.dut.adb.shell(GET_MAC_RANDOMIZATION_STATUS), "1", - "Failed to enable Connected MAC Randomization on dut.") - - req_params = ["reference_networks"] - opt_param = [] - self.unpack_userparams( - req_param_names=req_params, opt_param_names=opt_param) - - if "AccessPoint" in self.user_params: - self.legacy_configure_ap_and_start() - - asserts.assert_true( - self.reference_networks[0]["2g"], - "Need at least 1 2.4Ghz reference network with psk.") - asserts.assert_true( - self.reference_networks[0]["5g"], - "Need at least 1 5Ghz reference network with psk.") - self.wpapsk_2g = self.reference_networks[0]["2g"] - self.wpapsk_5g = self.reference_networks[0]["5g"] - - def setup_test(self): - self.dut.droid.wakeLockAcquireBright() - self.dut.droid.wakeUpNow() - wutils.wifi_toggle_state(self.dut, True) - wutils.wifi_toggle_state(self.dut_softap, False) - - def teardown_test(self): - self.dut.droid.wakeLockRelease() - self.dut.droid.goToSleepNow() - wutils.reset_wifi(self.dut) - wutils.reset_wifi(self.dut_softap) - - def on_fail(self, test_name, begin_time): - self.dut.take_bug_report(test_name, begin_time) - self.dut.cat_adb_log(test_name, begin_time) - - def teardown_class(self): - wutils.stop_wifi_tethering(self.dut_softap) - self.reset_mac_address_to_factory_mac() - if "AccessPoint" in self.user_params: - del self.user_params["reference_networks"] - del self.user_params["open_network"] - - """Helper Functions""" - def get_current_mac_address(self, ad): - """Get the device's wlan0 MAC address. - - Args: - ad: AndroidDevice to get MAC address of. - - Returns: - A MAC address string in the format of "12:34:56:78:90:12". - """ - return ad.adb.shell(GET_MAC_ADDRESS) - - def is_valid_randomized_mac_address(self, mac): - """Check if the given MAC address is a valid randomized MAC address. - - Args: - mac: MAC address to check in the format of "12:34:56:78:90:12". - """ - asserts.assert_true( - mac != self.dut_factory_mac, - "Randomized MAC address is same as factory MAC address.") - first_byte = int(mac[:2], 16) - asserts.assert_equal(first_byte & 1, 0, "MAC address is not unicast.") - asserts.assert_equal(first_byte & 2, 2, "MAC address is not local.") - - def reset_mac_address_to_factory_mac(self): - """Reset dut to and store factory MAC address by turning off - Connected MAC Randomization and rebooting dut. - """ - self.dut.adb.shell(TURN_OFF_MAC_RANDOMIZATION) - asserts.assert_equal( - self.dut.adb.shell(GET_MAC_RANDOMIZATION_STATUS), "0", - "Failed to disable Connected MAC Randomization on dut.") - self.dut.reboot() - time.sleep(DEFAULT_TIMEOUT) - self.dut_factory_mac = self.get_current_mac_address(self.dut) - - def get_connection_data(self, ad, network): - """Connect and get network id and ssid info from connection data. - - Args: - ad: AndroidDevice to use for connection - network: network info of the network to connect to - - Returns: - A convenience dict with the connected network's ID and SSID. - """ - wutils.connect_to_wifi_network(ad, network) - connect_data = ad.droid.wifiGetConnectionInfo() - ssid_id_dict = dict() - ssid_id_dict[WifiEnums.NETID_KEY] = connect_data[WifiEnums.NETID_KEY] - ssid_id_dict[WifiEnums.SSID_KEY] = connect_data[WifiEnums.SSID_KEY] - return ssid_id_dict - - """Tests""" - @test_tracker_info(uuid="") - def test_wifi_connection_2G_with_mac_randomization(self): - """Tests connection to 2G network with Connected MAC Randomization. - """ - wutils.connect_to_wifi_network(self.dut, self.wpapsk_2g) - mac = self.get_current_mac_address(self.dut) - self.is_valid_randomized_mac_address(mac) - - @test_tracker_info(uuid="") - def test_wifi_connection_5G_with_mac_randomization(self): - """Tests connection to 5G network with Connected MAC Randomization. - """ - wutils.connect_to_wifi_network(self.dut, self.wpapsk_5g) - mac = self.get_current_mac_address(self.dut) - self.is_valid_randomized_mac_address(mac) - - @test_tracker_info(uuid="") - def test_randomized_mac_persistent_between_connections(self): - """Tests that randomized MAC address assigned to each network is - persistent between connections. - - Steps: - 1. Connect to a 2GHz network. - 2. Connect to a 5GHz network. - 3. Reconnect to the 2GHz network using its network id. - 4. Verify that MAC addresses in Steps 1 and 3 are equal. - 5. Reconnect to the 5GHz network using its network id. - 6. Verify that MAC addresses in Steps 2 and 5 are equal. - """ - connect_data_2g = self.get_connection_data(self.dut, self.wpapsk_2g) - old_mac_2g = self.get_current_mac_address(self.dut) - self.is_valid_randomized_mac_address(old_mac_2g) - - connect_data_5g = self.get_connection_data(self.dut, self.wpapsk_5g) - old_mac_5g = self.get_current_mac_address(self.dut) - self.is_valid_randomized_mac_address(old_mac_5g) - - asserts.assert_true( - old_mac_2g != old_mac_5g, - "Randomized MAC addresses for 2G and 5G networks are equal.") - - reconnect_2g = wutils.connect_to_wifi_network_with_id( - self.dut, - connect_data_2g[WifiEnums.NETID_KEY], - connect_data_2g[WifiEnums.SSID_KEY]) - if not reconnect_2g: - raise signals.TestFailure("Device did not connect to the correct" - " 2GHz network.") - new_mac_2g = self.get_current_mac_address(self.dut) - asserts.assert_equal( - old_mac_2g, - new_mac_2g, - "Randomized MAC for 2G is not persistent between connections.") - - reconnect_5g = wutils.connect_to_wifi_network_with_id( - self.dut, - connect_data_5g[WifiEnums.NETID_KEY], - connect_data_5g[WifiEnums.SSID_KEY]) - if not reconnect_5g: - raise signals.TestFailure("Device did not connect to the correct" - " 5GHz network.") - new_mac_5g = self.get_current_mac_address(self.dut) - asserts.assert_equal( - old_mac_5g, - new_mac_5g, - "Randomized MAC for 5G is not persistent between connections.") - - @test_tracker_info(uuid="") - def test_randomized_mac_used_during_connection(self): - """Verify that the randomized MAC address and not the factory - MAC address is used during connection by checking the softap logs. - - Steps: - 1. Set up softAP on dut_softap. - 2. Have dut connect to the softAp. - 3. Verify that only randomized MAC appears in softAp logs. - """ - self.dut_softap.adb.shell(LOG_CLEAR) - config = wutils.create_softap_config() - wutils.start_wifi_tethering(self.dut_softap, - config[wutils.WifiEnums.SSID_KEY], - config[wutils.WifiEnums.PWD_KEY], - WIFI_CONFIG_APBAND_2G) - - # Internet validation fails when dut_softap does not have a valid sim - # supporting softap. Since this test is not checking for internet - # validation, we suppress failure signals. - wutils.connect_to_wifi_network(self.dut, config, assert_on_fail=False) - mac = self.get_current_mac_address(self.dut) - wutils.stop_wifi_tethering(self.dut_softap) - - self.is_valid_randomized_mac_address(mac) - log = self.dut_softap.adb.shell(LOG_GREP.format(mac)) - asserts.assert_true(len(log) > 0, "Randomized MAC not in log.") - log = self.dut_softap.adb.shell(LOG_GREP.format(self.dut_factory_mac)) - asserts.assert_true(len(log) == 0, "Factory MAC is in log.") diff --git a/acts/tests/google/wifi/WifiCrashStressTest.py b/acts/tests/google/wifi/WifiCrashStressTest.py deleted file mode 100644 index 837112a62c..0000000000 --- a/acts/tests/google/wifi/WifiCrashStressTest.py +++ /dev/null @@ -1,218 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2018 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import time -import acts.signals as signals -import acts.test_utils.wifi.wifi_test_utils as wutils -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 - -WifiEnums = wutils.WifiEnums - -class WifiCrashStressTest(WifiBaseTest): - """Crash Tests for wifi stack. - - Test Bed Requirement: - * Two Android device - * One Wi-Fi network visible to the device. - """ - - def setup_class(self): - super().setup_class() - - self.dut = self.android_devices[0] - self.dut_client = self.android_devices[1] - wutils.wifi_test_device_init(self.dut) - wutils.wifi_test_device_init(self.dut_client) - if not self.dut.is_apk_installed("com.google.mdstest"): - raise signals.TestAbortClass("mdstest is not installed") - req_params = ["dbs_supported_models", "stress_count"] - opt_param = ["reference_networks"] - self.unpack_userparams( - req_param_names=req_params, opt_param_names=opt_param) - - if "AccessPoint" in self.user_params: - self.legacy_configure_ap_and_start() - - asserts.assert_true( - len(self.reference_networks) > 0, - "Need at least one reference network with psk.") - self.network = self.reference_networks[0]["2g"] - self.ap_iface = 'wlan0' - if self.dut.model in self.dbs_supported_models: - self.ap_iface = 'wlan1' - - def setup_test(self): - self.dut.droid.wakeLockAcquireBright() - self.dut.droid.wakeUpNow() - wutils.wifi_toggle_state(self.dut, True) - self.dut_client.droid.wakeLockAcquireBright() - self.dut_client.droid.wakeUpNow() - wutils.wifi_toggle_state(self.dut_client, True) - - def teardown_test(self): - if self.dut.droid.wifiIsApEnabled(): - wutils.stop_wifi_tethering(self.dut) - self.dut.droid.wakeLockRelease() - self.dut.droid.goToSleepNow() - wutils.reset_wifi(self.dut) - self.dut_client.droid.wakeLockRelease() - self.dut_client.droid.goToSleepNow() - wutils.reset_wifi(self.dut_client) - - def on_fail(self, test_name, begin_time): - self.dut.take_bug_report(test_name, begin_time) - self.dut.cat_adb_log(test_name, begin_time) - self.dut_client.take_bug_report(test_name, begin_time) - self.dut_client.cat_adb_log(test_name, begin_time) - - def teardown_class(self): - if "AccessPoint" in self.user_params: - del self.user_params["reference_networks"] - - """Helper Functions""" - 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) - cmd = ('am instrument -w -e request "4b 25 03 b0 00" ' - '"com.google.mdstest/com.google.mdstest.instrument.' - 'ModemCommandInstrumentation"') - ad.log.info("Crash wifi firmware by %s", cmd) - ad.adb.shell(cmd, ignore_status=True) - time.sleep(timeout) # sleep time for firmware restart - subsystem = ad.adb.getprop("vendor.debug.ssrdump.subsys") - timestamp = ad.adb.getprop("vendor.debug.ssrdump.timestamp") - asserts.assert_true(timestamp != pre_timestamp, - "SSR didn't happened %s %s" % (subsystem, timestamp)) - - """Tests""" - @test_tracker_info(uuid="b5a982ef-10ef-4f36-a1b5-1e5d1fec06a4") - def test_firmware_crash_wifi_reconnect_stress(self): - """Firmware crash stress test for station mode - - 1. Turn on Wi-Fi and connect to access point - 2. Trigger firmware crash - 3. Check ssr happened - 4. Check dut can connect to access point - 5. Repeat step 2~4 - """ - wutils.wifi_toggle_state(self.dut, True) - wutils.connect_to_wifi_network(self.dut, self.network) - 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) - self.trigger_wifi_firmware_crash(self.dut) - wutils.connect_to_wifi_network(self.dut, self.network) - - @test_tracker_info(uuid="204a921b-b0de-47f7-9b70-9384317051c8") - def test_firmware_crash_softap_reconnect_stress(self): - """Firmware crash stress test for softap mode - - 1. Turn off dut's Wi-Fi - 2. Turn on dut's hotspot and connected by dut client - 3. Trigger firmware crash - 4. Check ssr happened - 5. Check the connectivity of hotspot's client - 6. Repeat step 3~5 - """ - wutils.wifi_toggle_state(self.dut, False) - # Setup Soft AP - sap_config = wutils.create_softap_config() - wutils.start_wifi_tethering( - self.dut, sap_config[wutils.WifiEnums.SSID_KEY], - sap_config[wutils.WifiEnums.PWD_KEY], wutils.WifiEnums.WIFI_CONFIG_APBAND_2G) - config = { - "SSID": sap_config[wutils.WifiEnums.SSID_KEY], - "password": sap_config[wutils.WifiEnums.PWD_KEY] - } - # DUT client connects to softap - wutils.wifi_toggle_state(self.dut_client, True) - wutils.connect_to_wifi_network(self.dut_client, config, check_connectivity=False) - # Ping the DUT - dut_addr = self.dut.droid.connectivityGetIPv4Addresses( - self.ap_iface)[0] - 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)) - 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.connect_to_wifi_network(self.dut_client, config, check_connectivity=False) - # Ping the DUT - server_addr = self.dut.droid.connectivityGetIPv4Addresses( - self.ap_iface)[0] - asserts.assert_true( - utils.adb_shell_ping( - self.dut_client, - count=10, - dest_ip=server_addr, - timeout=20), - "%s ping %s failed" % (self.dut_client.serial, server_addr)) - wutils.stop_wifi_tethering(self.dut) - - @test_tracker_info(uuid="4b7f2d89-82be-41de-9277-e938cc1c318b") - def test_firmware_crash_concurrent_reconnect_stress(self): - """Firmware crash stress test for concurrent mode - - 1. Turn on dut's Wi-Fi and connect to access point - 2. Turn on dut's hotspot and connected by dut client - 3. Trigger firmware crash - 4. Check ssr happened - 5. Check dut can connect to access point - 6. Check the connectivity of hotspot's client - 7. Repeat step 3~6 - """ - if self.dut.model not in self.dbs_supported_models: - raise signals.TestSkip("%s does not support dual interfaces" % self.dut.model) - - # Connect DUT to Network - wutils.wifi_toggle_state(self.dut, True) - wutils.connect_to_wifi_network(self.dut, self.network) - # Setup Soft AP - sap_config = wutils.create_softap_config() - wutils.start_wifi_tethering( - self.dut, sap_config[wutils.WifiEnums.SSID_KEY], - sap_config[wutils.WifiEnums.PWD_KEY], wutils.WifiEnums.WIFI_CONFIG_APBAND_2G) - config = { - "SSID": sap_config[wutils.WifiEnums.SSID_KEY], - "password": sap_config[wutils.WifiEnums.PWD_KEY] - } - # Client connects to Softap - wutils.wifi_toggle_state(self.dut_client, True) - wutils.connect_to_wifi_network(self.dut_client, config) - 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) - wutils.connect_to_wifi_network(self.dut_client, config) - wutils.stop_wifi_tethering(self.dut) diff --git a/acts/tests/google/wifi/WifiCrashTest.py b/acts/tests/google/wifi/WifiCrashTest.py deleted file mode 100644 index d43a0b9c0c..0000000000 --- a/acts/tests/google/wifi/WifiCrashTest.py +++ /dev/null @@ -1,176 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2018 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import itertools -import pprint -import queue -import time - -import acts.base_test -import acts.signals as signals -import acts.test_utils.wifi.wifi_test_utils as wutils -import acts.utils - -from acts import asserts -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest - -WifiEnums = wutils.WifiEnums -# Default timeout used for reboot, toggle WiFi and Airplane mode, -# for the system to settle down after the operation. -DEFAULT_TIMEOUT = 10 -WIFICOND_KILL_SHELL_COMMAND = "killall wificond" -WIFI_VENDOR_HAL_KILL_SHELL_COMMAND = "killall android.hardware.wifi@1.0-service vendor.google.wifi_ext@1.0-service-vendor" -SUPPLICANT_KILL_SHELL_COMMAND = "killall wpa_supplicant" - -class WifiCrashTest(WifiBaseTest): - """Crash Tests for wifi stack. - - Test Bed Requirement: - * One Android device - * One Wi-Fi network visible to the device. - """ - - def setup_class(self): - super().setup_class() - - self.dut = self.android_devices[0] - wutils.wifi_test_device_init(self.dut) - req_params = [] - opt_param = ["reference_networks"] - self.unpack_userparams( - req_param_names=req_params, opt_param_names=opt_param) - - if "AccessPoint" in self.user_params: - self.legacy_configure_ap_and_start() - - asserts.assert_true( - len(self.reference_networks) > 0, - "Need at least one reference network with psk.") - self.network = self.reference_networks[0]["2g"] - - def setup_test(self): - self.dut.droid.wakeLockAcquireBright() - self.dut.droid.wakeUpNow() - wutils.wifi_toggle_state(self.dut, True) - - def teardown_test(self): - self.dut.droid.wakeLockRelease() - self.dut.droid.goToSleepNow() - wutils.reset_wifi(self.dut) - - def on_fail(self, test_name, begin_time): - self.dut.take_bug_report(test_name, begin_time) - self.dut.cat_adb_log(test_name, begin_time) - - def teardown_class(self): - if "AccessPoint" in self.user_params: - del self.user_params["reference_networks"] - - """Helper Functions""" - - """Tests""" - @test_tracker_info(uuid="b87fd23f-9bfc-406b-a5b2-17ce6be6c780") - def test_wifi_framework_crash_reconnect(self): - """Connect to a network, crash framework, then ensure - we connect back to the previously connected network. - - Steps: - 1. Connect to a network. - 2. Restart framework. - 3. Reconnect to the previous network. - - """ - wutils.wifi_connect(self.dut, self.network, num_of_tries=3) - # Restart framework - self.log.info("Crashing framework") - self.dut.restart_runtime() - # We won't get the disconnect broadcast because framework crashed. - # wutils.wait_for_disconnect(self.dut) - time.sleep(DEFAULT_TIMEOUT) - wifi_info = self.dut.droid.wifiGetConnectionInfo() - if wifi_info[WifiEnums.SSID_KEY] != self.network[WifiEnums.SSID_KEY]: - raise signals.TestFailure("Device did not connect to the" - " network after crashing framework.") - - @test_tracker_info(uuid="33f9e4f6-29b8-4116-8f9b-5b13d93b4bcb") - def test_wifi_cond_crash_reconnect(self): - """Connect to a network, crash wificond, then ensure - we connect back to the previously connected network. - - Steps: - 1. Connect to a network. - 2. Crash wificond. - 3. Ensure we get a disconnect. - 4. Ensure we reconnect to the previous network. - - """ - wutils.wifi_connect(self.dut, self.network, num_of_tries=3) - # Restart wificond - self.log.info("Crashing wificond") - self.dut.adb.shell(WIFICOND_KILL_SHELL_COMMAND) - wutils.wait_for_disconnect(self.dut) - time.sleep(DEFAULT_TIMEOUT) - wifi_info = self.dut.droid.wifiGetConnectionInfo() - if wifi_info[WifiEnums.SSID_KEY] != self.network[WifiEnums.SSID_KEY]: - raise signals.TestFailure("Device did not connect to the" - " network after crashing wificond.") - - @test_tracker_info(uuid="463e3d7b-b0b7-4843-b83b-5613a71ae2ac") - def test_wifi_vendorhal_crash_reconnect(self): - """Connect to a network, crash wifi HAL, then ensure - we connect back to the previously connected network. - - Steps: - 1. Connect to a network. - 2. Crash wifi HAL. - 3. Ensure we get a disconnect. - 4. Ensure we reconnect to the previous network. - - """ - wutils.wifi_connect(self.dut, self.network, num_of_tries=3) - # Restart wificond - self.log.info("Crashing wifi HAL") - self.dut.adb.shell(WIFI_VENDOR_HAL_KILL_SHELL_COMMAND) - wutils.wait_for_disconnect(self.dut) - time.sleep(DEFAULT_TIMEOUT) - wifi_info = self.dut.droid.wifiGetConnectionInfo() - if wifi_info[WifiEnums.SSID_KEY] != self.network[WifiEnums.SSID_KEY]: - raise signals.TestFailure("Device did not connect to the" - " network after crashing wifi HAL.") - - @test_tracker_info(uuid="7c5cd1fc-8f8d-494c-beaf-4eb61b48917b") - def test_wpa_supplicant_crash_reconnect(self): - """Connect to a network, crash wpa_supplicant, then ensure - we connect back to the previously connected network. - - Steps: - 1. Connect to a network. - 2. Crash wpa_supplicant. - 3. Ensure we get a disconnect. - 4. Ensure we reconnect to the previous network. - - """ - wutils.wifi_connect(self.dut, self.network, num_of_tries=3) - # Restart wificond - self.log.info("Crashing wpa_supplicant") - self.dut.adb.shell(SUPPLICANT_KILL_SHELL_COMMAND) - wutils.wait_for_disconnect(self.dut) - time.sleep(DEFAULT_TIMEOUT) - wifi_info = self.dut.droid.wifiGetConnectionInfo() - if wifi_info[WifiEnums.SSID_KEY] != self.network[WifiEnums.SSID_KEY]: - raise signals.TestFailure("Device did not connect to the" - " network after crashing wpa_supplicant.") diff --git a/acts/tests/google/wifi/WifiDiagnosticsTest.py b/acts/tests/google/wifi/WifiDiagnosticsTest.py deleted file mode 100644 index 8ef24bd24f..0000000000 --- a/acts/tests/google/wifi/WifiDiagnosticsTest.py +++ /dev/null @@ -1,101 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2018 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import itertools -import pprint -import queue -import time - -import acts.base_test -import acts.signals as signals -import acts.test_utils.wifi.wifi_test_utils as wutils -import acts.utils - -from acts import asserts -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest - -WifiEnums = wutils.WifiEnums - -DEFAULT_WAIT_TIME = 2 - - -class WifiDiagnosticsTest(WifiBaseTest): - """ - Test Bed Requirement: - * One Android device - * An open Wi-Fi network. - * Verbose logging is on. - """ - - def setup_class(self): - super().setup_class() - - self.dut = self.android_devices[0] - wutils.wifi_test_device_init(self.dut) - req_params = [] - opt_param = ["open_network"] - self.unpack_userparams( - req_param_names=req_params, opt_param_names=opt_param) - - if "AccessPoint" in self.user_params: - self.legacy_configure_ap_and_start() - wutils.wifi_toggle_state(self.dut, True) - asserts.assert_true( - len(self.open_network) > 0, - "Need at least one open network.") - self.open_network = self.open_network[0]["2g"] - - def setup_test(self): - self.dut.droid.wakeLockAcquireBright() - self.dut.droid.wakeUpNow() - - def teardown_test(self): - self.dut.droid.wakeLockRelease() - self.dut.droid.goToSleepNow() - wutils.reset_wifi(self.dut) - - - def on_fail(self, test_name, begin_time): - self.dut.take_bug_report(test_name, begin_time) - self.dut.cat_adb_log(test_name, begin_time) - - def teardown_class(self): - if "AccessPoint" in self.user_params: - del self.user_params["open_network"] - - """Tests""" - - @test_tracker_info(uuid="d6f1661b-6732-4939-8c28-f20917774ec0") - def test_ringbuffers_are_dumped_during_lsdebug(self): - """Steps: - 1. Connect to a open network. - 2. Delete old files under data/vendor/tombstones/wifi - 3. Call lshal debug on wifi hal component - 4. Verify that files are created under data/vender/tombstones/wifi - """ - wutils.connect_to_wifi_network(self.dut, self.open_network) - time.sleep(DEFAULT_WAIT_TIME) - self.dut.adb.shell("rm data/vendor/tombstones/wifi/*") - try: - self.dut.adb.shell("lshal debug android.hardware.wifi@1.2::IWifi") - except UnicodeDecodeError: - """ Gets this error because adb.shell trys to parse the output to a string - but ringbuffer dumps should already be generated """ - self.log.info("Unicode decode error occurred, but this is ok") - file_count_plus_one = self.dut.adb.shell("ls -l data/vendor/tombstones/wifi | wc -l") - if int(file_count_plus_one) <= 1: - raise signals.TestFailure("Failed to create ringbuffer debug files.")
\ No newline at end of file diff --git a/acts/tests/google/wifi/WifiDppTest.py b/acts/tests/google/wifi/WifiDppTest.py deleted file mode 100644 index 42591b03f2..0000000000 --- a/acts/tests/google/wifi/WifiDppTest.py +++ /dev/null @@ -1,795 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2018 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import binascii -import queue -import time - -from acts import asserts -from acts import utils -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi import wifi_constants -from acts.test_utils.wifi import wifi_test_utils as wutils -from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest -from acts.test_utils.wifi.aware import aware_test_utils as autils - -class WifiDppTest(WifiBaseTest): - """This class tests the DPP API surface. - - Attributes: The tests in this class require one DUT and one helper phone - device. - The tests in this class do not require a SIM. - """ - - DPP_TEST_TIMEOUT = 60 - DPP_TEST_SSID_PREFIX = "dpp_test_ssid_" - DPP_TEST_SECURITY_SAE = "SAE" - DPP_TEST_SECURITY_PSK_PASSPHRASE = "PSK_PASSPHRASE" - DPP_TEST_SECURITY_PSK = "PSK" - - DPP_TEST_EVENT_DPP_CALLBACK = "onDppCallback" - DPP_TEST_EVENT_DATA = "data" - DPP_TEST_EVENT_ENROLLEE_SUCCESS = "onEnrolleeSuccess" - DPP_TEST_EVENT_CONFIGURATOR_SUCCESS = "onConfiguratorSuccess" - DPP_TEST_EVENT_PROGRESS = "onProgress" - DPP_TEST_EVENT_FAILURE = "onFailure" - DPP_TEST_MESSAGE_TYPE = "Type" - DPP_TEST_MESSAGE_STATUS = "Status" - DPP_TEST_MESSAGE_NETWORK_ID = "NetworkId" - - DPP_TEST_NETWORK_ROLE_STA = "sta" - DPP_TEST_NETWORK_ROLE_AP = "ap" - - WPA_SUPPLICANT_SECURITY_SAE = "sae" - WPA_SUPPLICANT_SECURITY_PSK = "psk" - - def setup_class(self): - """ Sets up the required dependencies from the config file and configures the device for - WifiService API tests. - - Returns: - True is successfully configured the requirements for testig. - """ - - # Device 0 is under test. Device 1 performs the responder role - self.dut = self.android_devices[0] - self.helper_dev = self.android_devices[1] - - # Do a simple version of init - mainly just sync the time and enable - # verbose logging. We would also like to test with phones in less - # constrained states (or add variations where we specifically - # constrain). - utils.require_sl4a((self.dut,)) - utils.sync_device_time(self.dut) - - # Enable verbose logging on the dut - self.dut.droid.wifiEnableVerboseLogging(1) - asserts.assert_true(self.dut.droid.wifiGetVerboseLoggingLevel() == 1, - "Failed to enable WiFi verbose logging on the dut.") - - def teardown_class(self): - wutils.reset_wifi(self.dut) - - def on_fail(self, test_name, begin_time): - self.dut.take_bug_report(test_name, begin_time) - self.dut.cat_adb_log(test_name, begin_time) - - def create_and_save_wifi_network_config(self, security): - """ Create a config with random SSID and password. - - Args: - security: Security type: PSK or SAE - - Returns: - A tuple with the config and networkId for the newly created and - saved network. - """ - config_ssid = self.DPP_TEST_SSID_PREFIX + utils.rand_ascii_str(8) - config_password = utils.rand_ascii_str(8) - self.dut.log.info( - "creating config: %s %s %s" % (config_ssid, config_password, security)) - config = { - wutils.WifiEnums.SSID_KEY: config_ssid, - wutils.WifiEnums.PWD_KEY: config_password, - wutils.WifiEnums.SECURITY: security - } - - # Now save the config. - network_id = self.dut.droid.wifiAddNetwork(config) - self.dut.log.info("saved config: network_id = %d" % network_id) - return network_id - - def check_network_config_saved(self, expected_ssid, security, network_id): - """ Get the configured networks and check if the provided network ID is present. - - Args: - expected_ssid: Expected SSID to match with received configuration. - security: Security type to match, PSK or SAE - - Returns: - True if the WifiConfig is present. - """ - networks = self.dut.droid.wifiGetConfiguredNetworks() - if not networks: - return False - - # Normalize PSK and PSK Passphrase to PSK - if security == self.DPP_TEST_SECURITY_PSK_PASSPHRASE: - security = self.DPP_TEST_SECURITY_PSK - - # If the device doesn't support SAE, then the test fallbacks to PSK - if not self.dut.droid.wifiIsWpa3SaeSupported() and \ - security == self.DPP_TEST_SECURITY_SAE: - security = self.DPP_TEST_SECURITY_PSK - - for network in networks: - if network_id == network['networkId'] and \ - security == network[wutils.WifiEnums.SECURITY] and \ - expected_ssid == network[wutils.WifiEnums.SSID_KEY]: - self.log.info("Found SSID %s" % network[wutils.WifiEnums.SSID_KEY]) - return True - return False - - def forget_network(self, network_id): - """ Simple method to call wifiForgetNetwork and wait for confirmation callback. - - Returns: - True if network was successfully deleted. - """ - self.dut.log.info("Deleting config: networkId = %s" % network_id) - self.dut.droid.wifiForgetNetwork(network_id) - try: - event = self.dut.ed.pop_event(wifi_constants.WIFI_FORGET_NW_SUCCESS, 10) - return True - except queue.Empty: - self.dut.log.error("Failed to forget network") - return False - - def gen_uri(self, device, info="DPP_TESTER", chan="81/1", mac=None): - """Generate a URI on a device - - Args: - device: Device object - mac: MAC address to use - info: Optional info to be embedded in URI - chan: Optional channel info - - Returns: - URI ID to be used later - """ - - # Clean up any previous URIs - self.del_uri(device, "'*'") - - self.log.info("Generating a URI for the Responder") - cmd = "wpa_cli DPP_BOOTSTRAP_GEN type=qrcode info=%s" % info - - if mac: - cmd += " mac=%s" % mac - - if chan: - cmd += " chan=%s" % chan - - result = device.adb.shell(cmd) - - if "FAIL" in result: - asserts.fail("gen_uri: Failed to generate a URI. Command used: %s" % cmd) - - if not result.index("\n"): - asserts.fail("gen_uri: Helper device not responding correctly, may need to restart it." - " Command used: %s" % cmd) - - result = result[result.index("\n") + 1:] - device.log.info("Generated URI, id = %s" % result) - - return result - - def get_uri(self, device, uri_id): - """Get a previously generated URI from a device - - Args: - device: Device object - uri_id: URI ID returned by gen_uri method - - Returns: - URI string - - """ - self.log.info("Reading the contents of the URI of the Responder") - cmd = "wpa_cli DPP_BOOTSTRAP_GET_URI %s" % uri_id - result = device.adb.shell(cmd) - - if "FAIL" in result: - asserts.fail("get_uri: Failed to read URI. Command used: %s" % cmd) - - result = result[result.index("\n") + 1:] - device.log.info("URI contents = %s" % result) - - return result - - def del_uri(self, device, uri_id): - """Delete a previously generated URI - - Args: - device: Device object - uri_id: URI ID returned by gen_uri method - """ - self.log.info("Deleting the Responder URI") - cmd = "wpa_cli DPP_BOOTSTRAP_REMOVE %s" % uri_id - result = device.adb.shell(cmd) - - if "FAIL" in result: - asserts.fail("del_uri: Failed to delete URI. Command used: %s" % cmd) - device.log.info("Deleted URI, id = %s" % uri_id) - - def start_responder_configurator(self, - device, - freq=2412, - net_role=DPP_TEST_NETWORK_ROLE_STA, - security=DPP_TEST_SECURITY_SAE, - invalid_config=False): - """Start a responder on helper device - - Args: - device: Device object - freq: Frequency to listen on - net_role: Network role to configure - security: Security type: SAE or PSK - invalid_config: Send invalid configuration (negative test) - - Returns: - ssid: SSID name of the network to be configured - - """ - if not net_role or (net_role != self.DPP_TEST_NETWORK_ROLE_STA and - net_role != self.DPP_TEST_NETWORK_ROLE_AP): - asserts.fail("start_responder: Must specify net_role sta or ap") - - self.log.info("Starting Responder in Configurator mode, frequency %sMHz" % freq) - - conf = "conf=%s-" % net_role - - use_psk = False - - if security == self.DPP_TEST_SECURITY_SAE: - if not self.dut.droid.wifiIsWpa3SaeSupported(): - self.log.warning("SAE not supported on device! reverting to PSK") - security = self.DPP_TEST_SECURITY_PSK_PASSPHRASE - - if security == self.DPP_TEST_SECURITY_SAE: - conf += self.WPA_SUPPLICANT_SECURITY_SAE - elif security == self.DPP_TEST_SECURITY_PSK_PASSPHRASE: - conf += self.WPA_SUPPLICANT_SECURITY_PSK - else: - conf += self.WPA_SUPPLICANT_SECURITY_PSK - use_psk = True - - ssid = self.DPP_TEST_SSID_PREFIX + utils.rand_ascii_str(8) - self.log.debug("SSID = %s" % ssid) - - ssid_encoded = binascii.hexlify(ssid.encode()).decode() - - if use_psk: - psk = utils.rand_ascii_str(16) - if not invalid_config: - psk_encoded = binascii.b2a_hex(psk.encode()).decode() - else: - # Use the psk as is without hex encoding, will make it invalid - psk_encoded = psk - self.log.debug("PSK = %s" % psk) - else: - password = utils.rand_ascii_str(8) - if not invalid_config: - password_encoded = binascii.b2a_hex(password.encode()).decode() - else: - # Use the password as is without hex encoding, will make it invalid - password_encoded = password - self.log.debug("Password = %s" % password) - - conf += " ssid=%s" % ssid_encoded - - if password: # SAE password or PSK passphrase - conf += " pass=%s" % password_encoded - else: # PSK - conf += " psk=%s" % psk_encoded - - # Stop responder first - self.stop_responder(device) - - cmd = "wpa_cli set dpp_configurator_params guard=1 %s" % conf - device.log.debug("Command used: %s" % cmd) - result = self.helper_dev.adb.shell(cmd) - if "FAIL" in result: - asserts.fail( - "start_responder_configurator: Failure. Command used: %s" % cmd) - - cmd = "wpa_cli DPP_LISTEN %d role=configurator netrole=%s" % (freq, - net_role) - device.log.debug("Command used: %s" % cmd) - result = self.helper_dev.adb.shell(cmd) - if "FAIL" in result: - asserts.fail( - "start_responder_configurator: Failure. Command used: %s" % cmd) - - device.log.info("Started responder in configurator mode") - return ssid - - def start_responder_enrollee(self, - device, - freq=2412, - net_role=DPP_TEST_NETWORK_ROLE_STA): - """Start a responder-enrollee on helper device - - Args: - device: Device object - freq: Frequency to listen on - net_role: Network role to request - - Returns: - ssid: SSID name of the network to be configured - - """ - if not net_role or (net_role != self.DPP_TEST_NETWORK_ROLE_STA and - net_role != self.DPP_TEST_NETWORK_ROLE_AP): - asserts.fail("start_responder: Must specify net_role sta or ap") - - # Stop responder first - self.stop_responder(device) - self.log.info("Starting Responder in Enrollee mode, frequency %sMHz" % freq) - - cmd = "wpa_cli DPP_LISTEN %d role=enrollee netrole=%s" % (freq, net_role) - result = device.adb.shell(cmd) - - if "FAIL" in result: - asserts.fail("start_responder_enrollee: Failure. Command used: %s" % cmd) - - device.log.info("Started responder in enrollee mode") - - def stop_responder(self, device): - """Stop responder on helper device - - Args: - device: Device object - """ - result = device.adb.shell("wpa_cli DPP_STOP_LISTEN") - if "FAIL" in result: - asserts.fail("stop_responder: Failed to stop responder") - device.adb.shell("wpa_cli set dpp_configurator_params") - - device.log.info("Stopped responder") - - def start_dpp_as_initiator_configurator(self, - security, - use_mac, - responder_chan="81/1", - responder_freq=2412, - net_role=DPP_TEST_NETWORK_ROLE_STA, - cause_timeout=False, - fail_authentication=False, - invalid_uri=False): - """ Test Easy Connect (DPP) as initiator configurator. - - 1. Enable wifi, if needed - 2. Create and save a random config. - 3. Generate a URI using the helper device - 4. Start DPP as responder-enrollee on helper device - 5. Start DPP as initiator configurator on dut - 6. Check if configurator sent successfully - 7. Delete the URI from helper device - 8. Remove the config. - - Args: - security: Security type, a string "SAE" or "PSK" - use_mac: A boolean indicating whether to use the device's MAC - address (if True) or use a Broadcast (if False). - responder_chan: Responder channel to specify in the URI - responder_freq: Frequency that the Responder would actually listen on. - Note: To succeed, there must be a correlation between responder_chan, which is what - the URI advertises, and responder_freq which is the actual frequency. See: - https://en.wikipedia.org/wiki/List_of_WLAN_channels - net_role: Network role, a string "sta" or "ap" - cause_timeout: Intentionally don't start the responder to cause a - timeout - fail_authentication: Fail authentication by corrupting the - responder's key - invalid_uri: Use garbage string instead of a URI - """ - if not self.dut.droid.wifiIsEasyConnectSupported(): - self.log.warning("Easy Connect is not supported on device!") - return - - wutils.wifi_toggle_state(self.dut, True) - test_network_id = self.create_and_save_wifi_network_config(security) - - if use_mac: - mac = autils.get_mac_addr(self.helper_dev, "wlan0") - else: - mac = None - - if invalid_uri: - enrollee_uri = "dskjgnkdjfgnkdsjfgnsDFGDIFGKDSJFGFDbgjdsnbkjdfnkbgsdfgFDSGSDfgesouhgureho" \ - "iu3ht98368903434089ut4958763094u0934ujg094j5oifegjfds" - else: - # Generate a URI with default info and channel - uri_id = self.gen_uri(self.helper_dev, chan=responder_chan, mac=mac) - - # Get the URI. This is equal to scanning a QR code - enrollee_uri = self.get_uri(self.helper_dev, uri_id) - - # Corrupt the responder key if required - if fail_authentication: - enrollee_uri = enrollee_uri[:80] + "DeAdBeeF" + enrollee_uri[88:] - self.log.info("Corrupted enrollee URI: %s" % enrollee_uri) - - if not cause_timeout: - # Start DPP as an enrolle-responder for STA on helper device - self.start_responder_enrollee(self.helper_dev, freq=responder_freq, net_role=net_role) - else: - self.log.info("Not starting DPP responder on purpose") - - self.log.info("Starting DPP in Configurator-Initiator mode") - - # Start DPP as configurator-initiator on dut - self.dut.droid.startEasyConnectAsConfiguratorInitiator(enrollee_uri, - test_network_id, net_role) - - start_time = time.time() - while time.time() < start_time + self.DPP_TEST_TIMEOUT: - dut_event = self.dut.ed.pop_event(self.DPP_TEST_EVENT_DPP_CALLBACK, - self.DPP_TEST_TIMEOUT) - if dut_event[self.DPP_TEST_EVENT_DATA][self.DPP_TEST_MESSAGE_TYPE] \ - == self.DPP_TEST_EVENT_ENROLLEE_SUCCESS: - asserts.fail("DPP failure, unexpected result!") - break - if dut_event[self.DPP_TEST_EVENT_DATA][ - self - .DPP_TEST_MESSAGE_TYPE] == self.DPP_TEST_EVENT_CONFIGURATOR_SUCCESS: - if cause_timeout or fail_authentication or invalid_uri: - asserts.fail( - "Unexpected DPP success, status code: %s" % - dut_event[self.DPP_TEST_EVENT_DATA][self.DPP_TEST_MESSAGE_STATUS]) - else: - val = dut_event[self.DPP_TEST_EVENT_DATA][ - self.DPP_TEST_MESSAGE_STATUS] - if val == 0: - self.dut.log.info("DPP Configuration sent success") - break - if dut_event[self.DPP_TEST_EVENT_DATA][ - self.DPP_TEST_MESSAGE_TYPE] == self.DPP_TEST_EVENT_PROGRESS: - self.dut.log.info("DPP progress event") - val = dut_event[self.DPP_TEST_EVENT_DATA][self.DPP_TEST_MESSAGE_STATUS] - if val == 0: - self.dut.log.info("DPP Authentication success") - elif val == 1: - self.dut.log.info("DPP Response pending") - continue - if dut_event[self.DPP_TEST_EVENT_DATA][ - self.DPP_TEST_MESSAGE_TYPE] == self.DPP_TEST_EVENT_FAILURE: - if cause_timeout or fail_authentication or invalid_uri: - self.dut.log.info( - "Error %s occurred, as expected" % - dut_event[self.DPP_TEST_EVENT_DATA][self.DPP_TEST_MESSAGE_STATUS]) - else: - asserts.fail( - "DPP failure, status code: %s" % - dut_event[self.DPP_TEST_EVENT_DATA][self.DPP_TEST_MESSAGE_STATUS]) - break - - # Clear all pending events. - self.dut.ed.clear_all_events() - - # Stop responder - self.stop_responder(self.helper_dev) - - if not invalid_uri: - # Delete URI - self.del_uri(self.helper_dev, uri_id) - - asserts.assert_true( - self.forget_network(test_network_id), - "Test network not deleted from configured networks.") - - def start_dpp_as_initiator_enrollee(self, - security, - use_mac, - cause_timeout=False, - invalid_config=False): - """ Test Easy Connect (DPP) as initiator enrollee. - - 1. Enable wifi, if needed - 2. Start DPP as responder-configurator on helper device - 3. Start DPP as initiator enrollee on dut - 4. Check if configuration received successfully - 5. Delete the URI from helper device - 6. Remove the config. - - Args: - security: Security type, a string "SAE" or "PSK" - use_mac: A boolean indicating whether to use the device's MAC - address (if True) or use a Broadcast (if False). - cause_timeout: Intentionally don't start the responder to cause a - timeout - invalid_config: Responder to intentionally send malformed - configuration - """ - if not self.dut.droid.wifiIsEasyConnectSupported(): - self.log.warning("Easy Connect is not supported on device!") - return - - wutils.wifi_toggle_state(self.dut, True) - - if use_mac: - mac = autils.get_mac_addr(self.helper_dev, "wlan0") - else: - mac = None - - # Generate a URI with default info and channel - uri_id = self.gen_uri(self.helper_dev, mac=mac) - - # Get the URI. This is equal to scanning a QR code - configurator_uri = self.get_uri(self.helper_dev, uri_id) - - if not cause_timeout: - # Start DPP as an configurator-responder for STA on helper device - ssid = self.start_responder_configurator( - self.helper_dev, security=security, invalid_config=invalid_config) - else: - self.log.info( - "Not starting a responder configurator on helper device, on purpose") - ssid = self.DPP_TEST_SSID_PREFIX + utils.rand_ascii_str(8) - - self.log.info("Starting DPP in Enrollee-Initiator mode") - - # Start DPP as enrollee-initiator on dut - self.dut.droid.startEasyConnectAsEnrolleeInitiator(configurator_uri) - - network_id = 0 - - start_time = time.time() - while time.time() < start_time + self.DPP_TEST_TIMEOUT: - dut_event = self.dut.ed.pop_event(self.DPP_TEST_EVENT_DPP_CALLBACK, - self.DPP_TEST_TIMEOUT) - if dut_event[self.DPP_TEST_EVENT_DATA][ - self.DPP_TEST_MESSAGE_TYPE] == self.DPP_TEST_EVENT_ENROLLEE_SUCCESS: - if cause_timeout or invalid_config: - asserts.fail( - "Unexpected DPP success, status code: %s" % - dut_event[self.DPP_TEST_EVENT_DATA][self.DPP_TEST_MESSAGE_STATUS]) - else: - self.dut.log.info("DPP Configuration received success") - network_id = dut_event[self.DPP_TEST_EVENT_DATA][ - self.DPP_TEST_MESSAGE_NETWORK_ID] - self.dut.log.info("NetworkID: %d" % network_id) - break - if dut_event[self.DPP_TEST_EVENT_DATA][ - self - .DPP_TEST_MESSAGE_TYPE] == self.DPP_TEST_EVENT_CONFIGURATOR_SUCCESS: - asserts.fail( - "DPP failure, unexpected result: %s" % - dut_event[self.DPP_TEST_EVENT_DATA][self.DPP_TEST_MESSAGE_STATUS]) - break - if dut_event[self.DPP_TEST_EVENT_DATA][ - self.DPP_TEST_MESSAGE_TYPE] == self.DPP_TEST_EVENT_PROGRESS: - self.dut.log.info("DPP progress event") - val = dut_event[self.DPP_TEST_EVENT_DATA][self.DPP_TEST_MESSAGE_STATUS] - if val == 0: - self.dut.log.info("DPP Authentication success") - elif val == 1: - self.dut.log.info("DPP Response pending") - continue - if dut_event[self.DPP_TEST_EVENT_DATA][ - self.DPP_TEST_MESSAGE_TYPE] == self.DPP_TEST_EVENT_FAILURE: - if cause_timeout or invalid_config: - self.dut.log.info( - "Error %s occurred, as expected" % - dut_event[self.DPP_TEST_EVENT_DATA][self.DPP_TEST_MESSAGE_STATUS]) - else: - asserts.fail( - "DPP failure, status code: %s" % - dut_event[self.DPP_TEST_EVENT_DATA][self.DPP_TEST_MESSAGE_STATUS]) - break - asserts.fail("Unknown message received") - - # Clear all pending events. - self.dut.ed.clear_all_events() - - # Stop responder - self.stop_responder(self.helper_dev) - - # Delete URI - self.del_uri(self.helper_dev, uri_id) - - if not (invalid_config or cause_timeout): - # Check that the saved network is what we expect - asserts.assert_true( - self.check_network_config_saved(ssid, security, network_id), - "Could not find the expected network: %s" % ssid) - - asserts.assert_true( - self.forget_network(network_id), - "Test network not deleted from configured networks.") - - """ Tests Begin """ - - @test_tracker_info(uuid="30893d51-2069-4e1c-8917-c8a840f91b59") - @WifiBaseTest.wifi_test_wrap - def test_dpp_as_initiator_configurator_with_psk_5G(self): - asserts.skip_if(not self.dut.droid.wifiIs5GHzBandSupported() or - not self.helper_dev.droid.wifiIs5GHzBandSupported(), - "5G not supported on at least on test device") - self.start_dpp_as_initiator_configurator( - security=self.DPP_TEST_SECURITY_PSK, responder_chan="126/149", responder_freq=5745, - use_mac=True) - - @test_tracker_info(uuid="54d1d19a-aece-459c-b819-9d4b1ae63f77") - @WifiBaseTest.wifi_test_wrap - def test_dpp_as_initiator_configurator_with_psk_5G_broadcast(self): - asserts.skip_if(not self.dut.droid.wifiIs5GHzBandSupported() or - not self.helper_dev.droid.wifiIs5GHzBandSupported(), - "5G not supported on at least on test device") - self.start_dpp_as_initiator_configurator( - security=self.DPP_TEST_SECURITY_PSK, responder_chan="126/149", responder_freq=5745, - use_mac=False) - - @test_tracker_info(uuid="18270a69-300c-4f54-87fd-c19073a2854e ") - @WifiBaseTest.wifi_test_wrap - def test_dpp_as_initiator_configurator_with_psk_no_chan_in_uri_listen_on_5745_broadcast(self): - asserts.skip_if(not self.dut.droid.wifiIs5GHzBandSupported() or - not self.helper_dev.droid.wifiIs5GHzBandSupported(), - "5G not supported on at least on test device") - self.start_dpp_as_initiator_configurator( - security=self.DPP_TEST_SECURITY_PSK, responder_chan=None, responder_freq=5745, use_mac=False) - - @test_tracker_info(uuid="fbdd687c-954a-400b-9da3-2d17e28b0798") - @WifiBaseTest.wifi_test_wrap - def test_dpp_as_initiator_configurator_with_psk_no_chan_in_uri_listen_on_5745(self): - asserts.skip_if(not self.dut.droid.wifiIs5GHzBandSupported() or - not self.helper_dev.droid.wifiIs5GHzBandSupported(), - "5G not supported on at least on test device") - self.start_dpp_as_initiator_configurator( - security=self.DPP_TEST_SECURITY_PSK, responder_chan=None, responder_freq=5745, use_mac=True) - - @test_tracker_info(uuid="570f499f-ab12-4405-af14-c9ed36da2e01") - @WifiBaseTest.wifi_test_wrap - def test_dpp_as_initiator_configurator_with_psk_no_chan_in_uri_listen_on_2462_broadcast(self): - self.start_dpp_as_initiator_configurator( - security=self.DPP_TEST_SECURITY_PSK, responder_chan=None, responder_freq=2462, use_mac=False) - - @test_tracker_info(uuid="e1f083e0-0878-4c49-8ac5-d7c6bba24625") - @WifiBaseTest.wifi_test_wrap - def test_dpp_as_initiator_configurator_with_psk_no_chan_in_uri_listen_on_2462(self): - self.start_dpp_as_initiator_configurator( - security=self.DPP_TEST_SECURITY_PSK, responder_chan=None, responder_freq=2462, use_mac=True) - - @test_tracker_info(uuid="d2a526f5-4269-493d-bd79-4e6d1b7b00f0") - @WifiBaseTest.wifi_test_wrap - def test_dpp_as_initiator_configurator_with_psk(self): - self.start_dpp_as_initiator_configurator( - security=self.DPP_TEST_SECURITY_PSK, use_mac=True) - - @test_tracker_info(uuid="6ead218c-222b-45b8-8aad-fe7d883ed631") - @WifiBaseTest.wifi_test_wrap - def test_dpp_as_initiator_configurator_with_sae(self): - self.start_dpp_as_initiator_configurator( - security=self.DPP_TEST_SECURITY_SAE, use_mac=True) - - @test_tracker_info(uuid="1686adb5-1b3c-4e6d-a969-6b007bdd990d") - @WifiBaseTest.wifi_test_wrap - def test_dpp_as_initiator_configurator_with_psk_passphrase(self): - self.start_dpp_as_initiator_configurator( - security=self.DPP_TEST_SECURITY_PSK_PASSPHRASE, use_mac=True) - - @test_tracker_info(uuid="3958feb5-1a0c-4487-9741-ac06f04c55a2") - @WifiBaseTest.wifi_test_wrap - def test_dpp_as_initiator_configurator_with_sae_broadcast(self): - self.start_dpp_as_initiator_configurator( - security=self.DPP_TEST_SECURITY_SAE, use_mac=False) - - @test_tracker_info(uuid="fe6d66f5-73a1-46e9-8f49-73b8f332cc8c") - @WifiBaseTest.wifi_test_wrap - def test_dpp_as_initiator_configurator_with_psk_passphrase_broadcast(self): - self.start_dpp_as_initiator_configurator( - security=self.DPP_TEST_SECURITY_PSK_PASSPHRASE, use_mac=False) - - @test_tracker_info(uuid="9edd372d-e2f1-4545-8d04-6a1636fcbc4b") - @WifiBaseTest.wifi_test_wrap - def test_dpp_as_initiator_configurator_with_sae_for_ap(self): - self.start_dpp_as_initiator_configurator( - security=self.DPP_TEST_SECURITY_SAE, - use_mac=True, - net_role=self.DPP_TEST_NETWORK_ROLE_AP) - - @test_tracker_info(uuid="e9eec912-d665-4926-beac-859cb13dc17b") - @WifiBaseTest.wifi_test_wrap - def test_dpp_as_initiator_configurator_with_psk_passphrase_for_ap(self): - self.start_dpp_as_initiator_configurator( - security=self.DPP_TEST_SECURITY_PSK_PASSPHRASE, - use_mac=True, - net_role=self.DPP_TEST_NETWORK_ROLE_AP) - - @test_tracker_info(uuid="8055694f-606f-41dd-9826-3ea1e9b007f8") - @WifiBaseTest.wifi_test_wrap - def test_dpp_as_initiator_enrollee_with_sae(self): - self.start_dpp_as_initiator_enrollee( - security=self.DPP_TEST_SECURITY_SAE, use_mac=True) - - @test_tracker_info(uuid="c1e9f605-b5c0-4e53-8a08-1b0087a667fa") - @WifiBaseTest.wifi_test_wrap - def test_dpp_as_initiator_enrollee_with_psk_passphrase(self): - self.start_dpp_as_initiator_enrollee( - security=self.DPP_TEST_SECURITY_PSK_PASSPHRASE, use_mac=True) - - @test_tracker_info(uuid="1d7f30ad-2f9a-427a-8059-651dc8827ae2") - @WifiBaseTest.wifi_test_wrap - def test_dpp_as_initiator_enrollee_with_sae_broadcast(self): - self.start_dpp_as_initiator_enrollee( - security=self.DPP_TEST_SECURITY_SAE, use_mac=False) - - @test_tracker_info(uuid="0cfc2645-600e-4f2b-ab5c-fcee6d363a9a") - @WifiBaseTest.wifi_test_wrap - def test_dpp_as_initiator_enrollee_with_psk_passphrase_broadcast(self): - self.start_dpp_as_initiator_enrollee( - security=self.DPP_TEST_SECURITY_PSK_PASSPHRASE, use_mac=False) - - @test_tracker_info(uuid="2e26b248-65dd-41f6-977b-e223d72b2de9") - @WifiBaseTest.wifi_test_wrap - def test_start_dpp_as_initiator_enrollee_receive_invalid_config(self): - self.start_dpp_as_initiator_enrollee( - security=self.DPP_TEST_SECURITY_PSK_PASSPHRASE, - use_mac=True, - invalid_config=True) - - @test_tracker_info(uuid="ed189661-d1c1-4626-9f01-3b7bb8a417fe") - @WifiBaseTest.wifi_test_wrap - def test_dpp_as_initiator_configurator_fail_authentication(self): - self.start_dpp_as_initiator_configurator( - security=self.DPP_TEST_SECURITY_PSK_PASSPHRASE, - use_mac=True, - fail_authentication=True) - - @test_tracker_info(uuid="5a8c6587-fbb4-4a27-9cba-af6f8935833a") - @WifiBaseTest.wifi_test_wrap - def test_dpp_as_initiator_configurator_fail_unicast_timeout(self): - self.start_dpp_as_initiator_configurator( - security=self.DPP_TEST_SECURITY_PSK_PASSPHRASE, - use_mac=True, - cause_timeout=True) - - @test_tracker_info(uuid="b12353ac-1a04-4036-81a4-2d2d0c653dbb") - @WifiBaseTest.wifi_test_wrap - def test_dpp_as_initiator_configurator_fail_broadcast_timeout(self): - self.start_dpp_as_initiator_configurator( - security=self.DPP_TEST_SECURITY_PSK_PASSPHRASE, - use_mac=False, - cause_timeout=True) - - @test_tracker_info(uuid="eeff91be-09ce-4a33-8b4f-ece40eb51c76") - @WifiBaseTest.wifi_test_wrap - def test_dpp_as_initiator_configurator_invalid_uri(self): - self.start_dpp_as_initiator_configurator( - security=self.DPP_TEST_SECURITY_PSK_PASSPHRASE, - use_mac=True, - invalid_uri=True) - - @test_tracker_info(uuid="1fa25f58-0d0e-40bd-8714-ab78957514d9") - @WifiBaseTest.wifi_test_wrap - def test_start_dpp_as_initiator_enrollee_fail_timeout(self): - self.start_dpp_as_initiator_enrollee( - security=self.DPP_TEST_SECURITY_PSK_PASSPHRASE, - use_mac=True, - cause_timeout=True) - - """ Tests End """ diff --git a/acts/tests/google/wifi/WifiEnterpriseRoamingTest.py b/acts/tests/google/wifi/WifiEnterpriseRoamingTest.py deleted file mode 100644 index 0cebd42e28..0000000000 --- a/acts/tests/google/wifi/WifiEnterpriseRoamingTest.py +++ /dev/null @@ -1,240 +0,0 @@ -# -# Copyright 2016 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import pprint -import random -import time - -from acts import asserts -from acts import signals -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi import wifi_test_utils as wutils -from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest - -WifiEnums = wutils.WifiEnums - -# EAP Macros -EAP = WifiEnums.Eap -EapPhase2 = WifiEnums.EapPhase2 - -# Enterprise Config Macros -Ent = WifiEnums.Enterprise - - -class WifiEnterpriseRoamingTest(WifiBaseTest): - def setup_class(self): - super().setup_class() - - self.dut = self.android_devices[0] - wutils.wifi_test_device_init(self.dut) - req_params = ( - "attn_vals", - # Expected time within which roaming should finish, in seconds. - "roam_interval", - "ca_cert", - "client_cert", - "client_key", - "eap_identity", - "eap_password", - "device_password", - "radius_conf_2g", - "radius_conf_5g") - self.unpack_userparams(req_params) - if "AccessPoint" in self.user_params: - self.legacy_configure_ap_and_start( - mirror_ap=True, - ent_network=True, - ap_count=2, - radius_conf_2g=self.radius_conf_2g, - radius_conf_5g=self.radius_conf_5g,) - self.ent_network_2g_a = self.ent_networks[0]["2g"] - self.ent_network_2g_b = self.ent_networks[1]["2g"] - self.bssid_2g_a = self.ent_network_2g_a[WifiEnums.BSSID_KEY.lower()] - self.bssid_2g_b = self.ent_network_2g_b[WifiEnums.BSSID_KEY.lower()] - self.ent_roaming_ssid = self.ent_network_2g_a[WifiEnums.SSID_KEY] - self.bssid_a = self.bssid_2g_a - self.bssid_b = self.bssid_2g_b - - self.config_peap = { - Ent.EAP: int(EAP.PEAP), - Ent.CA_CERT: self.ca_cert, - Ent.IDENTITY: self.eap_identity, - Ent.PASSWORD: self.eap_password, - Ent.PHASE2: int(EapPhase2.MSCHAPV2), - WifiEnums.SSID_KEY: self.ent_roaming_ssid - } - self.config_tls = { - Ent.EAP: int(EAP.TLS), - Ent.CA_CERT: self.ca_cert, - WifiEnums.SSID_KEY: self.ent_roaming_ssid, - Ent.CLIENT_CERT: self.client_cert, - Ent.PRIVATE_KEY_ID: self.client_key, - Ent.IDENTITY: self.eap_identity, - } - self.config_ttls = { - Ent.EAP: int(EAP.TTLS), - Ent.CA_CERT: self.ca_cert, - Ent.IDENTITY: self.eap_identity, - Ent.PASSWORD: self.eap_password, - Ent.PHASE2: int(EapPhase2.MSCHAPV2), - WifiEnums.SSID_KEY: self.ent_roaming_ssid - } - self.config_sim = { - Ent.EAP: int(EAP.SIM), - WifiEnums.SSID_KEY: self.ent_roaming_ssid, - } - self.attn_a = self.attenuators[0] - self.attn_b = self.attenuators[2] - # Set screen lock password so ConfigStore is unlocked. - self.dut.droid.setDevicePassword(self.device_password) - self.set_attns("default") - - def teardown_class(self): - wutils.reset_wifi(self.dut) - self.dut.droid.disableDevicePassword(self.device_password) - self.dut.ed.clear_all_events() - self.set_attns("default") - - def setup_test(self): - self.dut.droid.wifiStartTrackingStateChange() - self.dut.droid.wakeLockAcquireBright() - self.dut.droid.wakeUpNow() - wutils.reset_wifi(self.dut) - self.dut.ed.clear_all_events() - - def teardown_test(self): - self.dut.droid.wakeLockRelease() - self.dut.droid.goToSleepNow() - self.dut.droid.wifiStopTrackingStateChange() - self.set_attns("default") - - def on_fail(self, test_name, begin_time): - self.dut.take_bug_report(test_name, begin_time) - self.dut.cat_adb_log(test_name, begin_time) - - def set_attns(self, attn_val_name): - """Sets attenuation values on attenuators used in this test. - - 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.attn_a.set_atten(self.attn_vals[attn_val_name][0]) - self.attn_b.set_atten(self.attn_vals[attn_val_name][1]) - except: - self.log.exception("Failed to set attenuation values %s.", - attn_val_name) - raise - - def trigger_roaming_and_validate(self, attn_val_name, expected_con): - """Sets attenuators to trigger roaming and validate the DUT connected - to the BSSID expected. - - 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. - """ - self.set_attns(attn_val_name) - self.log.info("Wait %ss for roaming to finish.", self.roam_interval) - time.sleep(self.roam_interval) - try: - self.dut.droid.wakeLockAcquireBright() - self.dut.droid.wakeUpNow() - wutils.verify_wifi_connection_info(self.dut, expected_con) - expected_bssid = expected_con[WifiEnums.BSSID_KEY] - self.log.info("Roamed to %s successfully", expected_bssid) - finally: - self.dut.droid.wifiLockRelease() - self.dut.droid.goToSleepNow() - - def roaming_between_a_and_b_logic(self, config): - """Test roaming between two enterprise APs. - - Steps: - 1. Make bssid_a visible, bssid_b not visible. - 2. Connect to ent_roaming_ssid. Expect DUT to connect to bssid_a. - 3. Make bssid_a not visible, bssid_b visible. - 4. Expect DUT to roam to bssid_b. - 5. Make bssid_a visible, bssid_b not visible. - 6. Expect DUT to roam back to bssid_a. - """ - expected_con_to_a = { - WifiEnums.SSID_KEY: self.ent_roaming_ssid, - WifiEnums.BSSID_KEY: self.bssid_a, - } - expected_con_to_b = { - WifiEnums.SSID_KEY: self.ent_roaming_ssid, - WifiEnums.BSSID_KEY: self.bssid_b, - } - self.set_attns("a_on_b_off") - wutils.wifi_connect(self.dut, config) - wutils.verify_wifi_connection_info(self.dut, expected_con_to_a) - self.log.info("Roaming from %s to %s", self.bssid_a, self.bssid_b) - self.trigger_roaming_and_validate("b_on_a_off", expected_con_to_b) - self.log.info("Roaming from %s to %s", self.bssid_b, self.bssid_a) - self.trigger_roaming_and_validate("a_on_b_off", expected_con_to_a) - - """ Tests Begin """ - - @test_tracker_info(uuid="b15e4b3f-841d-428d-87ac-272f29f06e14") - def test_roaming_with_config_tls(self): - self.roaming_between_a_and_b_logic(self.config_tls) - - @test_tracker_info(uuid="d349cfec-b4af-48b2-88b7-744f5de25d43") - def test_roaming_with_config_ttls_none(self): - config = dict(self.config_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.NONE.value - self.roaming_between_a_and_b_logic(config) - - @test_tracker_info(uuid="89b8161c-754e-4138-831d-5fe40f521ce4") - def test_roaming_with_config_ttls_pap(self): - config = dict(self.config_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.PAP.value - self.roaming_between_a_and_b_logic(config) - - @test_tracker_info(uuid="d4925470-924b-4d03-8437-83e26b5f2df3") - def test_roaming_with_config_ttls_mschap(self): - config = dict(self.config_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.MSCHAP.value - self.roaming_between_a_and_b_logic(config) - - @test_tracker_info(uuid="206b1327-dd9c-4742-8717-e7bf2a04eed6") - def test_roaming_with_config_ttls_mschapv2(self): - config = dict(self.config_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.MSCHAPV2.value - self.roaming_between_a_and_b_logic(config) - - @test_tracker_info(uuid="c2c0168b-2933-4954-af62-fb41f42dc45a") - def test_roaming_with_config_ttls_gtc(self): - config = dict(self.config_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.GTC.value - self.roaming_between_a_and_b_logic(config) - - @test_tracker_info(uuid="481c4102-8f5b-4fcd-95cc-5e3285f47985") - def test_roaming_with_config_peap_mschapv2(self): - config = dict(self.config_peap) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.MSCHAPV2.value - self.roaming_between_a_and_b_logic(config) - - @test_tracker_info(uuid="404155d4-33a7-42b3-b369-5f2d63d19f16") - def test_roaming_with_config_peap_gtc(self): - config = dict(self.config_peap) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.GTC.value - self.roaming_between_a_and_b_logic(config) - - """ Tests End """ diff --git a/acts/tests/google/wifi/WifiEnterpriseTest.py b/acts/tests/google/wifi/WifiEnterpriseTest.py deleted file mode 100644 index 6ba5eb4fb5..0000000000 --- a/acts/tests/google/wifi/WifiEnterpriseTest.py +++ /dev/null @@ -1,756 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2016 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import pprint -import random -import time - -from acts import asserts -from acts import signals -from acts.test_decorators import test_tracker_info -from acts.test_utils.net.net_test_utils import start_tcpdump -from acts.test_utils.net.net_test_utils import stop_tcpdump -from acts.test_utils.wifi import wifi_test_utils as wutils -from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest - -WifiEnums = wutils.WifiEnums - -# EAP Macros -EAP = WifiEnums.Eap -EapPhase2 = WifiEnums.EapPhase2 -# Enterprise Config Macros -Ent = WifiEnums.Enterprise - - -class WifiEnterpriseTest(WifiBaseTest): - def setup_class(self): - super().setup_class() - - self.dut = self.android_devices[0] - wutils.wifi_test_device_init(self.dut) - # If running in a setup with attenuators, set attenuation on all - # channels to zero. - if getattr(self, "attenuators", []): - for a in self.attenuators: - a.set_atten(0) - required_userparam_names = ( - "ca_cert", "client_cert", "client_key", "passpoint_ca_cert", - "passpoint_client_cert", "passpoint_client_key", "eap_identity", - "eap_password", "invalid_ca_cert", "invalid_client_cert", - "invalid_client_key", "fqdn", "provider_friendly_name", "realm", - "device_password", "ping_addr", "radius_conf_2g", "radius_conf_5g", - "radius_conf_pwd") - self.unpack_userparams(required_userparam_names, - roaming_consortium_ids=None, - plmn=None) - - if "AccessPoint" in self.user_params: - self.legacy_configure_ap_and_start( - ent_network=True, - radius_conf_2g=self.radius_conf_2g, - radius_conf_5g=self.radius_conf_5g, - ent_network_pwd=True, - radius_conf_pwd=self.radius_conf_pwd,) - self.ent_network_2g = self.ent_networks[0]["2g"] - self.ent_network_5g = self.ent_networks[0]["5g"] - self.ent_network_pwd = self.ent_networks_pwd[0]["2g"] - - # Default configs for EAP networks. - self.config_peap0 = { - Ent.EAP: int(EAP.PEAP), - Ent.CA_CERT: self.ca_cert, - Ent.IDENTITY: self.eap_identity, - Ent.PASSWORD: self.eap_password, - Ent.PHASE2: int(EapPhase2.MSCHAPV2), - WifiEnums.SSID_KEY: self.ent_network_5g[WifiEnums.SSID_KEY], - } - self.config_peap1 = dict(self.config_peap0) - self.config_peap1[WifiEnums.SSID_KEY] = \ - self.ent_network_2g[WifiEnums.SSID_KEY] - self.config_tls = { - Ent.EAP: int(EAP.TLS), - Ent.CA_CERT: self.ca_cert, - WifiEnums.SSID_KEY: self.ent_network_2g[WifiEnums.SSID_KEY], - Ent.CLIENT_CERT: self.client_cert, - Ent.PRIVATE_KEY_ID: self.client_key, - Ent.IDENTITY: self.eap_identity, - } - self.config_ttls = { - Ent.EAP: int(EAP.TTLS), - Ent.CA_CERT: self.ca_cert, - Ent.IDENTITY: self.eap_identity, - Ent.PASSWORD: self.eap_password, - Ent.PHASE2: int(EapPhase2.MSCHAPV2), - WifiEnums.SSID_KEY: self.ent_network_2g[WifiEnums.SSID_KEY], - } - self.config_pwd = { - Ent.EAP: int(EAP.PWD), - Ent.IDENTITY: self.eap_identity, - Ent.PASSWORD: self.eap_password, - WifiEnums.SSID_KEY: self.ent_network_pwd[WifiEnums.SSID_KEY], - } - self.config_sim = { - Ent.EAP: int(EAP.SIM), - WifiEnums.SSID_KEY: self.ent_network_2g[WifiEnums.SSID_KEY], - } - self.config_aka = { - Ent.EAP: int(EAP.AKA), - WifiEnums.SSID_KEY: self.ent_network_2g[WifiEnums.SSID_KEY], - } - self.config_aka_prime = { - Ent.EAP: int(EAP.AKA_PRIME), - WifiEnums.SSID_KEY: self.ent_network_2g[WifiEnums.SSID_KEY], - } - - # Base config for passpoint networks. - self.config_passpoint = { - Ent.FQDN: self.fqdn, - Ent.FRIENDLY_NAME: self.provider_friendly_name, - Ent.REALM: self.realm, - Ent.CA_CERT: self.passpoint_ca_cert - } - if self.plmn: - self.config_passpoint[Ent.PLMN] = self.plmn - if self.roaming_consortium_ids: - self.config_passpoint[ - Ent.ROAMING_IDS] = self.roaming_consortium_ids - - # Default configs for passpoint networks. - self.config_passpoint_tls = dict(self.config_tls) - self.config_passpoint_tls.update(self.config_passpoint) - self.config_passpoint_tls[Ent.CLIENT_CERT] = self.passpoint_client_cert - self.config_passpoint_tls[ - Ent.PRIVATE_KEY_ID] = self.passpoint_client_key - del self.config_passpoint_tls[WifiEnums.SSID_KEY] - self.config_passpoint_ttls = dict(self.config_ttls) - self.config_passpoint_ttls.update(self.config_passpoint) - del self.config_passpoint_ttls[WifiEnums.SSID_KEY] - # Set screen lock password so ConfigStore is unlocked. - self.dut.droid.setDevicePassword(self.device_password) - self.tcpdump_pid = None - - def teardown_class(self): - wutils.reset_wifi(self.dut) - self.dut.droid.disableDevicePassword(self.device_password) - self.dut.ed.clear_all_events() - - def setup_test(self): - self.dut.droid.wifiStartTrackingStateChange() - self.dut.droid.wakeLockAcquireBright() - self.dut.droid.wakeUpNow() - wutils.reset_wifi(self.dut) - self.dut.ed.clear_all_events() - self.tcpdump_pid = start_tcpdump(self.dut, self.test_name) - - def teardown_test(self): - stop_tcpdump(self.dut, self.tcpdump_pid, self.test_name) - self.dut.droid.wakeLockRelease() - self.dut.droid.goToSleepNow() - self.dut.droid.wifiStopTrackingStateChange() - - def on_fail(self, test_name, begin_time): - self.dut.take_bug_report(test_name, begin_time) - self.dut.cat_adb_log(test_name, begin_time) - - """Helper Functions""" - - def eap_negative_connect_logic(self, config, ad): - """Tries to connect to an enterprise network with invalid credentials - and expect a failure. - - Args: - config: A dict representing an invalid EAP credential. - - Returns: - True if connection failed as expected, False otherwise. - """ - with asserts.assert_raises(signals.TestFailure, extras=config): - verdict = wutils.wifi_connect(ad, config) - asserts.explicit_pass("Connection failed as expected.") - - def gen_negative_configs(self, config, neg_params): - """Generic function used to generate negative configs. - - For all the valid configurations, if a param in the neg_params also - exists in a config, a copy of the config is made with an invalid value - of the param. - - Args: - config: A valid configuration. - neg_params: A dict that has all the invalid values. - - Returns: - An invalid configurations generated based on the valid - configuration. Each invalid configuration has a different invalid - field. - """ - negative_config = dict(config) - if negative_config in [self.config_sim, self.config_aka, - self.config_aka_prime]: - negative_config[WifiEnums.SSID_KEY] = 'wrong_hostapd_ssid' - for k, v in neg_params.items(): - # Skip negative test for TLS's identity field since it's not - # used for auth. - if config[Ent.EAP] == EAP.TLS and k == Ent.IDENTITY: - continue - if k in config: - negative_config[k] = v - negative_config["invalid_field"] = k - return negative_config - - def gen_negative_eap_configs(self, config): - """Generates invalid configurations for different EAP authentication - types. - - For all the valid EAP configurations, if a param that is part of the - authentication info exists in a config, a copy of the config is made - with an invalid value of the param. - - Args: - A valid network configration - - Returns: - An invalid EAP configuration. - """ - neg_params = { - Ent.CLIENT_CERT: self.invalid_client_cert, - Ent.CA_CERT: self.invalid_ca_cert, - Ent.PRIVATE_KEY_ID: self.invalid_client_key, - Ent.IDENTITY: "fake_identity", - Ent.PASSWORD: "wrong_password" - } - return self.gen_negative_configs(config, neg_params) - - def gen_negative_passpoint_configs(self, config): - """Generates invalid configurations for different EAP authentication - types with passpoint support. - - Args: - A valid network configration - - Returns: - An invalid EAP configuration with passpoint fields. - """ - neg_params = { - Ent.CLIENT_CERT: self.invalid_client_cert, - Ent.CA_CERT: self.invalid_ca_cert, - Ent.PRIVATE_KEY_ID: self.invalid_client_key, - Ent.IDENTITY: "fake_identity", - Ent.PASSWORD: "wrong_password", - Ent.FQDN: "fake_fqdn", - Ent.REALM: "where_no_one_has_gone_before", - Ent.PLMN: "fake_plmn", - Ent.ROAMING_IDS: [1234567890, 9876543210] - } - return self.gen_negative_configs(config, neg_params) - - def eap_connect_toggle_wifi(self, - config, - *args): - """Connects to an enterprise network, toggles wifi state and ensures - that the device reconnects. - - This logic expect the enterprise network to have Internet access. - - Args: - config: A dict representing a wifi enterprise configuration. - args: args to be passed to |wutils.eap_connect|. - - Returns: - True if the connection is successful and Internet access works. - """ - ad = args[0] - wutils.wifi_connect(ad, config) - wutils.toggle_wifi_and_wait_for_reconnection(ad, config, num_of_tries=5) - - """ Tests """ - - # EAP connect tests - """ Test connecting to enterprise networks of different authentication - types. - - The authentication types tested are: - EAP-TLS - EAP-PEAP with different phase2 types. - EAP-TTLS with different phase2 types. - - Procedures: - For each enterprise wifi network - 1. Connect to the network. - 2. Send a GET request to a website and check response. - - Expect: - Successful connection and Internet access through the enterprise - networks. - """ - @test_tracker_info(uuid="4e720cac-ea17-4de7-a540-8dc7c49f9713") - def test_eap_connect_with_config_tls(self): - wutils.wifi_connect(self.dut, self.config_tls) - - @test_tracker_info(uuid="10e3a5e9-0018-4162-a9fa-b41500f13340") - def test_eap_connect_with_config_pwd(self): - wutils.wifi_connect(self.dut, self.config_pwd) - - @test_tracker_info(uuid="b4513f78-a1c4-427f-bfc7-2a6b3da714b5") - def test_eap_connect_with_config_sim(self): - wutils.wifi_connect(self.dut, self.config_sim) - - @test_tracker_info(uuid="7d390e30-cb67-4b55-bf00-567adad2d9b0") - def test_eap_connect_with_config_aka(self): - wutils.wifi_connect(self.dut, self.config_aka) - - @test_tracker_info(uuid="742f921b-27c3-4b68-a3ca-88e64fe79c1d") - def test_eap_connect_with_config_aka_prime(self): - wutils.wifi_connect(self.dut, self.config_aka_prime) - - @test_tracker_info(uuid="d34e30f3-6ef6-459f-b47a-e78ed90ce4c6") - def test_eap_connect_with_config_ttls_none(self): - config = dict(self.config_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.NONE.value - wutils.wifi_connect(self.dut, config) - - @test_tracker_info(uuid="0dca3a15-472e-427c-8e06-4e38088ee973") - def test_eap_connect_with_config_ttls_pap(self): - config = dict(self.config_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.PAP.value - wutils.wifi_connect(self.dut, config) - - @test_tracker_info(uuid="47c4b459-2cb1-4fc7-b4e7-82534e8e090e") - def test_eap_connect_with_config_ttls_mschap(self): - config = dict(self.config_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.MSCHAP.value - wutils.wifi_connect(self.dut, config) - - @test_tracker_info(uuid="fdb286c7-8069-481d-baf0-c5dd7a31ff03") - def test_eap_connect_with_config_ttls_mschapv2(self): - config = dict(self.config_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.MSCHAPV2.value - wutils.wifi_connect(self.dut, config) - - @test_tracker_info(uuid="d9315962-7987-4ee7-905d-6972c78ce8a1") - def test_eap_connect_with_config_ttls_gtc(self): - config = dict(self.config_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.GTC.value - wutils.wifi_connect(self.dut, config) - - @test_tracker_info(uuid="90a67bd3-30da-4daf-8ab0-d964d7ad19be") - def test_eap_connect_with_config_peap0_mschapv2(self): - config = dict(self.config_peap0) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.MSCHAPV2.value - wutils.wifi_connect(self.dut, config) - - @test_tracker_info(uuid="3c451ba4-0c83-4eef-bc95-db4c21893008") - def test_eap_connect_with_config_peap0_gtc(self): - config = dict(self.config_peap0) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.GTC.value - wutils.wifi_connect(self.dut, config) - - @test_tracker_info(uuid="6b45157d-0325-417a-af18-11af5d240d79") - def test_eap_connect_with_config_peap1_mschapv2(self): - config = dict(self.config_peap1) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.MSCHAPV2.value - wutils.wifi_connect(self.dut, config) - - @test_tracker_info(uuid="1663decc-71ae-4f95-a027-8a6dbf9c337f") - def test_eap_connect_with_config_peap1_gtc(self): - config = dict(self.config_peap1) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.GTC.value - wutils.wifi_connect(self.dut, config) - - # EAP connect negative tests - """ Test connecting to enterprise networks. - - Procedures: - For each enterprise wifi network - 1. Connect to the network with invalid credentials. - - Expect: - Fail to establish connection. - """ - @test_tracker_info(uuid="b2a91f1f-ccd7-4bd1-ab81-19aab3d8ee38") - def test_eap_connect_negative_with_config_tls(self): - config = self.gen_negative_eap_configs(self.config_tls) - self.eap_negative_connect_logic(config, self.dut) - - @test_tracker_info(uuid="6466abde-1d16-4168-9dd8-1e7a0a19889b") - def test_eap_connect_negative_with_config_pwd(self): - config = self.gen_negative_eap_configs(self.config_pwd) - self.eap_negative_connect_logic(config, self.dut) - - @test_tracker_info(uuid="d7742a2a-85b0-409a-99d8-47711ddc5612") - def test_eap_connect_negative_with_config_sim(self): - config = self.gen_negative_eap_configs(self.config_sim) - self.eap_negative_connect_logic(config, self.dut) - - @test_tracker_info(uuid="0ec0de93-cab3-4f41-960b-c0af64ff48c4") - def test_eap_connect_negative_with_config_aka(self): - config = self.gen_negative_eap_configs(self.config_aka) - self.eap_negative_connect_logic(config, self.dut) - - @test_tracker_info(uuid="bb640ea4-32a6-48ea-87c9-f7128fffbbf6") - def test_eap_connect_negative_with_config_aka_prime(self): - config = self.gen_negative_eap_configs(self.config_aka_prime) - self.eap_negative_connect_logic(config, self.dut) - - @test_tracker_info(uuid="86336ada-0ced-45a4-8a22-c4aa23c81111") - def test_eap_connect_negative_with_config_ttls_none(self): - config = dict(self.config_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.NONE.value - config = self.gen_negative_eap_configs(config) - self.eap_negative_connect_logic(config, self.dut) - - @test_tracker_info(uuid="71e0498d-9973-4958-94bd-79051c328920") - def test_eap_connect_negative_with_config_ttls_pap(self): - config = dict(self.config_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.PAP.value - config = self.gen_negative_eap_configs(config) - self.eap_negative_connect_logic(config, self.dut) - - @test_tracker_info(uuid="c04142a8-b204-4d2d-98dc-150b16c8397e") - def test_eap_connect_negative_with_config_ttls_mschap(self): - config = dict(self.config_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.MSCHAP.value - config = self.gen_negative_eap_configs(config) - self.eap_negative_connect_logic(config, self.dut) - - @test_tracker_info(uuid="625e7aa5-e3e6-4bbe-98c0-5aad8ca1555b") - def test_eap_connect_negative_with_config_ttls_mschapv2(self): - config = dict(self.config_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.MSCHAPV2.value - config = self.gen_negative_eap_configs(config) - self.eap_negative_connect_logic(config, self.dut) - - @test_tracker_info(uuid="24ea0d80-0a3f-41c2-8e05-d6387e589058") - def test_eap_connect_negative_with_config_ttls_gtc(self): - config = dict(self.config_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.GTC.value - config = self.gen_negative_eap_configs(config) - self.eap_negative_connect_logic(config, self.dut) - - @test_tracker_info(uuid="b7c1f0f8-6338-4501-8e1d-c9b136aaba88") - def test_eap_connect_negative_with_config_peap0_mschapv2(self): - config = dict(self.config_peap0) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.MSCHAPV2.value - config = self.gen_negative_eap_configs(config) - self.eap_negative_connect_logic(config, self.dut) - - @test_tracker_info(uuid="9cf83dcb-38ad-4f75-9ea9-98de1cfaf7f3") - def test_eap_connect_negative_with_config_peap0_gtc(self): - config = dict(self.config_peap0) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.GTC.value - config = self.gen_negative_eap_configs(config) - self.eap_negative_connect_logic(config, self.dut) - - @test_tracker_info(uuid="89bb2b6b-d073-402a-bdc1-68ac5f8752a3") - def test_eap_connect_negative_with_config_peap1_mschapv2(self): - config = dict(self.config_peap1) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.MSCHAPV2.value - config = self.gen_negative_eap_configs(config) - self.eap_negative_connect_logic(config, self.dut) - - @test_tracker_info(uuid="2252a864-9ff7-43b5-82d9-afe57d1f5e5f") - def test_eap_connect_negative_with_config_peap1_gtc(self): - config = dict(self.config_peap1) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.GTC.value - config = self.gen_negative_eap_configs(config) - self.eap_negative_connect_logic(config, self.dut) - - # EAP connect config store tests - """ Test connecting to enterprise networks of different authentication - types after wifi toggle. - - The authentication types tested are: - EAP-TLS - EAP-PEAP with different phase2 types. - EAP-TTLS with different phase2 types. - - Procedures: - For each enterprise wifi network - 1. Connect to the network. - 2. Send a GET request to a website and check response. - 3. Toggle wifi. - 4. Ensure that the device reconnects to the same network. - - Expect: - Successful connection and Internet access through the enterprise - networks. - """ - @test_tracker_info(uuid="2a933b7f-27d7-4201-a34f-25b9d8072a8c") - def test_eap_connect_config_store_with_config_tls(self): - self.eap_connect_toggle_wifi(self.config_tls, self.dut) - - @test_tracker_info(uuid="08dc071b-9fea-408a-a3f6-d3493869f6d4") - def test_eap_connect_config_store_with_config_pwd(self): - self.eap_connect_toggle_wifi(self.config_pwd, self.dut) - - @test_tracker_info(uuid="230cb03e-58bc-41cb-b9b3-7215c2ab2325") - def test_eap_connect_config_store_with_config_sim(self): - self.eap_connect_toggle_wifi(self.config_sim, self.dut) - - @test_tracker_info(uuid="dfc3e59c-2309-4598-8c23-bb3fe95ef89f") - def test_eap_connect_config_store_with_config_aka(self): - self.eap_connect_toggle_wifi(self.config_aka, self.dut) - - @test_tracker_info(uuid="6050a1d1-4f3a-476d-bf93-638abd066790") - def test_eap_connect_config_store_with_config_aka_prime(self): - self.eap_connect_toggle_wifi(self.config_aka_prime, self.dut) - - @test_tracker_info(uuid="03108057-cc44-4a80-8331-77c93694099c") - def test_eap_connect_config_store_with_config_ttls_none(self): - config = dict(self.config_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.NONE.value - self.eap_connect_toggle_wifi(config, self.dut) - - @test_tracker_info(uuid="53dd8195-e272-4589-a261-b8fa3607ad8d") - def test_eap_connect_config_store_with_config_ttls_pap(self): - config = dict(self.config_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.PAP.value - self.eap_connect_toggle_wifi(config, self.dut) - - @test_tracker_info(uuid="640f697b-9c62-4b19-bd76-53b236a152e0") - def test_eap_connect_config_store_with_config_ttls_mschap(self): - config = dict(self.config_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.MSCHAP.value - self.eap_connect_toggle_wifi(config, self.dut) - - @test_tracker_info(uuid="f0243684-fae0-46f3-afbd-bf525fc712e2") - def test_eap_connect_config_store_with_config_ttls_mschapv2(self): - config = dict(self.config_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.MSCHAPV2.value - self.eap_connect_toggle_wifi(config, self.dut) - - @test_tracker_info(uuid="49ec7202-3b00-49c3-970a-201360888c74") - def test_eap_connect_config_store_with_config_ttls_gtc(self): - config = dict(self.config_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.GTC.value - self.eap_connect_toggle_wifi(config, self.dut) - - @test_tracker_info(uuid="1c6abfa3-f344-4e28-b891-5481ab79efcf") - def test_eap_connect_config_store_with_config_peap0_mschapv2(self): - config = dict(self.config_peap0) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.MSCHAPV2.value - self.eap_connect_toggle_wifi(config, self.dut) - - @test_tracker_info(uuid="2815bc76-49fa-43a5-a4b6-84788f9809d5") - def test_eap_connect_config_store_with_config_peap0_gtc(self): - config = dict(self.config_peap0) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.GTC.value - self.eap_connect_toggle_wifi(config, self.dut) - - @test_tracker_info(uuid="e93f7472-6895-4e36-bff2-9b2dcfd07ad0") - def test_eap_connect_config_store_with_config_peap1_mschapv2(self): - config = dict(self.config_peap1) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.MSCHAPV2.value - self.eap_connect_toggle_wifi(config, self.dut) - - @test_tracker_info(uuid="6da72fa0-b858-4475-9559-46fe052d0d64") - def test_eap_connect_config_store_with_config_peap1_gtc(self): - config = dict(self.config_peap1) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.GTC.value - self.eap_connect_toggle_wifi(config, self.dut) - - # Removing 'test_' for all passpoint based testcases as we want to disable - # them. Adding the valid test cases to self.tests make them run in serial - # (TODO): gmoturu - Update the passpoint tests to test the valid scenario - # Passpoint connect tests - """ Test connecting to enterprise networks of different authentication - types with passpoint support. - - The authentication types tested are: - EAP-TLS - EAP-TTLS with MSCHAPV2 as phase2. - - Procedures: - For each enterprise wifi network - 1. Connect to the network. - 2. Send a GET request to a website and check response. - - Expect: - Successful connection and Internet access through the enterprise - networks with passpoint support. - """ - @test_tracker_info(uuid="0b942524-bde9-4fc6-ac6a-fef1c247cb8e") - def passpoint_connect_with_config_passpoint_tls(self): - asserts.skip_if(not self.dut.droid.wifiIsPasspointSupported(), - "Passpoint is not supported on %s" % self.dut.model) - wutils.wifi_connect(self.dut, self.config_passpoint_tls) - - @test_tracker_info(uuid="33a014aa-99e7-4612-b732-54fabf1bf922") - def passpoint_connect_with_config_passpoint_ttls_none(self): - asserts.skip_if(not self.dut.droid.wifiIsPasspointSupported(), - "Passpoint is not supported on %s" % self.dut.model) - config = dict(self.config_passpoint_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.NONE.value - wutils.wifi_connect(self.dut, config) - - @test_tracker_info(uuid="1aba8bf9-2b09-4956-b418-c3f4dadab330") - def passpoint_connect_with_config_passpoint_ttls_pap(self): - asserts.skip_if(not self.dut.droid.wifiIsPasspointSupported(), - "Passpoint is not supported on %s" % self.dut.model) - config = dict(self.config_passpoint_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.PAP.value - wutils.wifi_connect(self.dut, config) - - @test_tracker_info(uuid="cd978fc9-a393-4b1e-bba3-1efc52224500") - def passpoint_connect_with_config_passpoint_ttls_mschap(self): - asserts.skip_if(not self.dut.droid.wifiIsPasspointSupported(), - "Passpoint is not supported on %s" % self.dut.model) - config = dict(self.config_passpoint_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.MSCHAP.value - wutils.wifi_connect(self.dut, config) - - @test_tracker_info(uuid="bc311ee7-ba64-4c76-a629-b916701bf6a5") - def passpoint_connect_with_config_passpoint_ttls_mschapv2(self): - asserts.skip_if(not self.dut.droid.wifiIsPasspointSupported(), - "Passpoint is not supported on %s" % self.dut.model) - config = dict(self.config_passpoint_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.MSCHAPV2.value - wutils.wifi_connect(self.dut, config) - - @test_tracker_info(uuid="357e5162-5081-4149-bedd-ef2c0f88b97e") - def passpoint_connect_with_config_passpoint_ttls_gtc(self): - asserts.skip_if(not self.dut.droid.wifiIsPasspointSupported(), - "Passpoint is not supported on %s" % self.dut.model) - config = dict(self.config_passpoint_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.GTC.value - wutils.wifi_connect(self.dut, config) - - # Passpoint connect negative tests - """ Test connecting to enterprise networks. - - Procedures: - For each enterprise wifi network - 1. Connect to the network with invalid credentials. - - Expect: - Fail to establish connection. - """ - @test_tracker_info(uuid="7b6b44a0-ff70-49b4-94ca-a98bedc18f92") - def passpoint_connect_negative_with_config_passpoint_tls(self): - asserts.skip_if(not self.dut.droid.wifiIsPasspointSupported(), - "Passpoint is not supported on %s" % self.dut.model) - config = self.gen_negative_passpoint_configs(self.config_passpoint_tls) - self.eap_negative_connect_logic(config, self.dut) - - @test_tracker_info(uuid="3dbde40a-e88c-4166-b932-163663a10a41") - def passpoint_connect_negative_with_config_passpoint_ttls_none(self): - asserts.skip_if(not self.dut.droid.wifiIsPasspointSupported(), - "Passpoint is not supported on %s" % self.dut.model) - config = dict(self.config_passpoint_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.NONE.value - config = self.gen_negative_passpoint_configs(config) - self.eap_negative_connect_logic(config, self.dut) - - @test_tracker_info(uuid="8ee22ad6-d561-4ca2-a808-9f372fce56b4") - def passpoint_connect_negative_with_config_passpoint_ttls_pap(self): - asserts.skip_if(not self.dut.droid.wifiIsPasspointSupported(), - "Passpoint is not supported on %s" % self.dut.model) - config = dict(self.config_passpoint_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.PAP.value - config = self.gen_negative_passpoint_configs(config) - self.eap_negative_connect_logic(config, self.dut) - - @test_tracker_info(uuid="db5cefe7-9cb8-47a6-8635-006c80b97012") - def passpoint_connect_negative_with_config_passpoint_ttls_mschap(self): - asserts.skip_if(not self.dut.droid.wifiIsPasspointSupported(), - "Passpoint is not supported on %s" % self.dut.model) - config = dict(self.config_passpoint_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.MSCHAP.value - config = self.gen_negative_passpoint_configs(config) - self.eap_negative_connect_logic(config, self.dut) - - @test_tracker_info(uuid="8f49496e-80df-48ce-9c51-42f0c6b81aff") - def passpoint_connect_negative_with_config_passpoint_ttls_mschapv2(self): - asserts.skip_if(not self.dut.droid.wifiIsPasspointSupported(), - "Passpoint is not supported on %s" % self.dut.model) - config = dict(self.config_passpoint_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.MSCHAPV2.value - config = self.gen_negative_passpoint_configs(config) - self.eap_negative_connect_logic(config, self.dut) - - @test_tracker_info(uuid="6561508f-598e-408d-96b6-15b631664be6") - def passpoint_connect_negative_with_config_passpoint_ttls_gtc(self): - asserts.skip_if(not self.dut.droid.wifiIsPasspointSupported(), - "Passpoint is not supported on %s" % self.dut.model) - config = dict(self.config_passpoint_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.GTC.value - config = self.gen_negative_passpoint_configs(config) - self.eap_negative_connect_logic(config, self.dut) - - # Passpoint connect config store tests - """ Test connecting to enterprise networks of different authentication - types with passpoint support after wifi toggle. - - The authentication types tested are: - EAP-TLS - EAP-TTLS with MSCHAPV2 as phase2. - - Procedures: - For each enterprise wifi network - 1. Connect to the network. - 2. Send a GET request to a website and check response. - 3. Toggle wifi. - 4. Ensure that the device reconnects to the same network. - - Expect: - Successful connection and Internet access through the enterprise - networks with passpoint support. - """ - @test_tracker_info(uuid="5d5e6bb0-faea-4a6e-a6bc-c87de997a4fd") - def passpoint_connect_config_store_with_config_passpoint_tls(self): - asserts.skip_if(not self.dut.droid.wifiIsPasspointSupported(), - "Passpoint is not supported on %s" % self.dut.model) - self.eap_connect_toggle_wifi(self.config_passpoint_tls, self.dut) - - @test_tracker_info(uuid="0c80262d-23c1-439f-ad64-7b8ada5d1962") - def passpoint_connect_config_store_with_config_passpoint_ttls_none(self): - asserts.skip_if(not self.dut.droid.wifiIsPasspointSupported(), - "Passpoint is not supported on %s" % self.dut.model) - config = dict(self.config_passpoint_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.NONE.value - self.eap_connect_toggle_wifi(config, self.dut) - - @test_tracker_info(uuid="786e424c-b5a6-4fe9-a951-b3de16ebb6db") - def passpoint_connect_config_store_with_config_passpoint_ttls_pap(self): - asserts.skip_if(not self.dut.droid.wifiIsPasspointSupported(), - "Passpoint is not supported on %s" % self.dut.model) - config = dict(self.config_passpoint_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.PAP.value - self.eap_connect_toggle_wifi(config, self.dut) - - @test_tracker_info(uuid="22fd61bf-722a-4016-a778-fc33e94ed211") - def passpoint_connect_config_store_with_config_passpoint_ttls_mschap(self): - asserts.skip_if(not self.dut.droid.wifiIsPasspointSupported(), - "Passpoint is not supported on %s" % self.dut.model) - config = dict(self.config_passpoint_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.MSCHAP.value - self.eap_connect_toggle_wifi(config, self.dut) - - @test_tracker_info(uuid="2abd348c-9c66-456b-88ad-55f971717620") - def passpoint_connect_config_store_with_config_passpoint_ttls_mschapv2(self): - asserts.skip_if(not self.dut.droid.wifiIsPasspointSupported(), - "Passpoint is not supported on %s" % self.dut.model) - config = dict(self.config_passpoint_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.MSCHAPV2.value - self.eap_connect_toggle_wifi(config, self.dut) - - @test_tracker_info(uuid="043e8cdd-db95-4f03-b308-3c8cecf874b1") - def passpoint_connect_config_store_with_config_passpoint_ttls_gtc(self): - asserts.skip_if(not self.dut.droid.wifiIsPasspointSupported(), - "Passpoint is not supported on %s" % self.dut.model) - config = dict(self.config_passpoint_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.GTC.value - self.eap_connect_toggle_wifi(config, self.dut) diff --git a/acts/tests/google/wifi/WifiHiddenSSIDTest.py b/acts/tests/google/wifi/WifiHiddenSSIDTest.py deleted file mode 100644 index a68144d35a..0000000000 --- a/acts/tests/google/wifi/WifiHiddenSSIDTest.py +++ /dev/null @@ -1,162 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2018 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import itertools -import pprint -import queue -import time - -import acts.base_test -import acts.signals -import acts.test_utils.wifi.wifi_test_utils as wutils -import acts.utils - -from acts import asserts -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest - - -class WifiHiddenSSIDTest(WifiBaseTest): - """Tests for APIs in Android's WifiManager class. - - Test Bed Requirement: - * One Android device - * Several Wi-Fi networks visible to the device, including an open Wi-Fi - network. - """ - - def setup_class(self): - super().setup_class() - - self.dut = self.android_devices[0] - wutils.wifi_test_device_init(self.dut) - req_params = [] - opt_param = [ - "open_network", "reference_networks"] - self.unpack_userparams( - req_param_names=req_params, opt_param_names=opt_param) - - if "AccessPoint" in self.user_params: - self.legacy_configure_ap_and_start(hidden=True) - - asserts.assert_true( - len(self.reference_networks) > 0, - "Need at least one reference network with psk.") - self.open_hidden_2g = self.open_network[0]["2g"] - self.open_hidden_5g = self.open_network[0]["5g"] - self.wpa_hidden_2g = self.reference_networks[0]["2g"] - self.wpa_hidden_5g = self.reference_networks[0]["5g"] - - def setup_test(self): - self.dut.droid.wakeLockAcquireBright() - self.dut.droid.wakeUpNow() - - def teardown_test(self): - self.dut.droid.wakeLockRelease() - self.dut.droid.goToSleepNow() - - def on_fail(self, test_name, begin_time): - self.dut.take_bug_report(test_name, begin_time) - self.dut.cat_adb_log(test_name, begin_time) - - def teardown_class(self): - wutils.reset_wifi(self.dut) - if "AccessPoint" in self.user_params: - del self.user_params["reference_networks"] - del self.user_params["open_network"] - - """Helper Functions""" - - def check_hiddenSSID_in_scan(self, ap_ssid, max_tries=2): - """Check if the ap started by wifi tethering is seen in scan results. - - Args: - ap_ssid: SSID of the ap we are looking for. - max_tries: Number of scans to try. - Returns: - True: if ap_ssid is found in scan results. - False: if ap_ssid is not found in scan results. - """ - for num_tries in range(max_tries): - wutils.start_wifi_connection_scan(self.dut) - scan_results = self.dut.droid.wifiGetScanResults() - match_results = wutils.match_networks( - {wutils.WifiEnums.SSID_KEY: ap_ssid}, scan_results) - if len(match_results) > 0: - return True - return False - - def add_hiddenSSID_and_connect(self, hidden_network): - """Add the hidden network and connect to it. - - Args: - hidden_network: The hidden network config to connect to. - - """ - wutils.connect_to_wifi_network(self.dut, hidden_network, hidden=True) - if not wutils.validate_connection(self.dut): - raise signals.TestFailure("Fail to connect to internet on %s" % - hidden_network) - - """Tests""" - - @test_tracker_info(uuid="d0871f98-6049-4937-a288-ec4a2746c771") - def test_connect_to_wpa_hidden_2g(self): - """Connect to a WPA, 2G network. - - Steps: - 1. Add a WPA, 2G hidden network. - 2. Ensure the network is visible in scan. - 3. Connect and run ping. - - """ - self.add_hiddenSSID_and_connect(self.wpa_hidden_2g) - - @test_tracker_info(uuid="c558b31a-549a-4012-9052-275623992187") - def test_connect_to_wpa_hidden_5g(self): - """Connect to a WPA, 5G hidden network. - - Steps: - 1. Add a WPA, 5G hidden network. - 2. Ensure the network is visible in scan. - 3. Connect and run ping. - - """ - self.add_hiddenSSID_and_connect(self.wpa_hidden_5g) - - @test_tracker_info(uuid="cdfce76f-6374-439d-aa1d-e920508269d2") - def test_connect_to_open_hidden_2g(self): - """Connect to a Open, 2G hidden network. - - Steps: - 1. Add a Open, 2G hidden network. - 2. Ensure the network is visible in scan. - 3. Connect and run ping. - - """ - self.add_hiddenSSID_and_connect(self.open_hidden_2g) - - @test_tracker_info(uuid="29ccbae4-4382-4df8-8fc5-00e3104230d0") - def test_connect_to_open_hidden_5g(self): - """Connect to a Open, 5G hidden network. - - Steps: - 1. Add a Open, 5G hidden network. - 2. Ensure the network is visible in scan. - 3. Connect and run ping. - - """ - self.add_hiddenSSID_and_connect(self.open_hidden_5g) diff --git a/acts/tests/google/wifi/WifiIFSTwTest.py b/acts/tests/google/wifi/WifiIFSTwTest.py deleted file mode 100644 index 5b1603dd4a..0000000000 --- a/acts/tests/google/wifi/WifiIFSTwTest.py +++ /dev/null @@ -1,295 +0,0 @@ -# -# Copyright 2019 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import math -import os - -import time - -import threading -from acts import utils -from acts import signals -from acts import asserts -from acts.controllers import attenuator -from acts.controllers.sl4a_lib import rpc_client -from acts.test_decorators import test_tracker_info -from acts.test_utils.net.net_test_utils import start_tcpdump, stop_tcpdump -from acts.test_utils.wifi import wifi_test_utils as wutils -from acts.test_utils.wifi.wifi_test_utils import WifiEnums -from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest -from acts.utils import stop_standing_subprocess - -TCPDUMP_PATH = '/data/local/tmp/tcpdump' - - -class WifiIFSTwTest(WifiBaseTest): - """Tests for wifi IFS - - Test Bed Requirement: - *One Android device - *Two Visible Wi-Fi Access Points - *One attenuator with 4 ports - """ - - def setup_class(self): - """Setup required dependencies from config file and configure - the required networks for testing roaming. - - Returns: - True if successfully configured the requirements for testing. - """ - super().setup_class() - self.simulation_thread_running = False - self.atten_roaming_count = 0 - self.start_db = 30 - self.roaming_cycle_seconds = 20 - self.fail_count = 0 - self.retry_pass_count = 0 - self.ping_count = 0 - - self.dut = self.android_devices[0] - wutils.wifi_test_device_init(self.dut) - req_params = ["attenuators", "ifs_params"] - opt_param = [] - - self.unpack_userparams( - req_param_names=req_params, opt_param_names=opt_param) - - if "AccessPoint" in self.user_params: - self.legacy_configure_ap_and_start(ap_count=2, same_ssid=True) - - wutils.wifi_toggle_state(self.dut, True) - if "ifs_params" in self.user_params: - self.attn_start_db = self.ifs_params[0]["start_db"] - self.gateway = self.ifs_params[0]["gateway"] - self.roaming_cycle_seconds = self.ifs_params[0][ - "roaming_cycle_seconds"] - self.total_test_hour = self.ifs_params[0]["total_test_hour"] - self.log_capture_period_hour = self.ifs_params[0][ - "log_capture_period_hour"] - self.on_active_port = self.ifs_params[0]["on_active_port"] - asserts.assert_true( - len(self.on_active_port) == 2, "Need setup 2 port.") - - self.tcpdump_pid = None - utils.set_location_service(self.dut, True) - - def setup_test(self): - self.dut.droid.wakeLockAcquireBright() - self.dut.droid.wakeUpNow() - self.dut.unlock_screen() - self.tcpdump_pid = start_tcpdump(self.dut, self.test_name) - - def teardown_class(self): - self.dut.ed.clear_all_events() - - def teardown_test(self): - self.dut.droid.wakeLockRelease() - self.dut.droid.goToSleepNow() - wutils.reset_wifi(self.dut) - - def simulate_roaming(self): - """ - To simulate user move between ap1 and ap2: - - 1. Move to ap2: - Set ap1's signal attenuation gradually changed from 0 to max_db - Set ap2's signal attenuation gradually changed from start_db to 0 - - 2. Then move to ap1: - Set ap1's signal attenuation gradually changed from start_db to 0 - Set ap2's signal attenuation gradually changed from 0 to max_db - - * 0<start_db<max_db - """ - attn_max = 95 - attn_min = 0 - - #on_active_port value should between [0-1,2-3] - active_attenuator = { - "1": self.attenuators[self.on_active_port[0]], - "2": self.attenuators[self.on_active_port[1]] - } - - for attenuator in self.attenuators: - attenuator.set_atten(attn_max) - - self.simulation_thread_running = True - while self.simulation_thread_running: - active_attenuator["1"].set_atten(attn_min) - active_attenuator["2"].set_atten(attn_max) - self.log_attens() - time.sleep(10) - - active_attenuator["2"].set_atten(self.start_db) - self.log_attens() - time.sleep(5) - for i in range(self.roaming_cycle_seconds): - db1 = math.ceil(attn_max / self.roaming_cycle_seconds * - (i + 1)) - db2 = self.start_db - math.ceil( - self.start_db / self.roaming_cycle_seconds * (i + 1)) - active_attenuator["1"].set_atten(db1) - active_attenuator["2"].set_atten(db2) - self.log_attens() - time.sleep(1) - - active_attenuator["1"].set_atten(self.start_db) - self.log_attens() - time.sleep(5) - for i in range(self.roaming_cycle_seconds): - db1 = math.ceil(attn_max / self.roaming_cycle_seconds * - (i + 1)) - db2 = self.start_db - math.ceil( - self.start_db / self.roaming_cycle_seconds * (i + 1)) - active_attenuator["1"].set_atten(db2) - active_attenuator["2"].set_atten(db1) - self.log_attens() - time.sleep(1) - self.atten_roaming_count += 1 - - def catch_log(self): - """Capture logs include bugreport, ANR, mount,ps,vendor,tcpdump""" - - self.log.info("Get log for regular capture.") - file_name = time.strftime("%Y-%m-%d_%H:%M:%S", time.localtime()) - current_path = os.path.join(self.dut.log_path, file_name) - os.makedirs(current_path, exist_ok=True) - serial_number = self.dut.serial - - try: - out = self.dut.adb.shell("bugreportz", timeout=240) - if not out.startswith("OK"): - raise AndroidDeviceError( - 'Failed to take bugreport on %s: %s' % (serial_number, - out), - serial=serial_number) - br_out_path = out.split(':')[1].strip().split()[0] - self.dut.adb.pull("%s %s" % (br_out_path, self.dut.log_path)) - self.dut.adb.pull("/data/anr {}".format(current_path), timeout=600) - self.dut.adb._exec_adb_cmd("shell", "mount > {}".format( - os.path.join(current_path, "mount.txt"))) - self.dut.adb._exec_adb_cmd("shell", "ps > {}".format( - os.path.join(current_path, "ps.txt"))) - self.dut.adb.pull("/data/misc/logd {}".format(current_path)) - self.dut.adb.pull( - "/data/vendor {}".format(current_path), timeout=800) - stop_tcpdump( - self.dut, self.tcpdump_pid, file_name, adb_pull_timeout=600) - self.tcpdump_pid = start_tcpdump(self.dut, file_name) - except TimeoutError as e: - self.log.error(e) - - def http_request(self, url="https://www.google.com/"): - """Get the result via string from target url - - Args: - url: target url to loading - - Returns: - True if http_request pass - """ - - self.ping_count += 1 - try: - self.dut.droid.httpRequestString(url) - self.log.info("httpRequest Finish") - time.sleep(1) - return True - except rpc_client.Sl4aApiError as e: - self.log.warning("httpRequest Fail.") - self.log.warning(e) - # Set check delay if http request fail during device roaming. - # Except finish roaming within 10s. - time.sleep(10) - self.log.warning("Ping Google DNS response : {}".format( - self.can_ping("8.8.8.8"))) - for gate in self.gateway: - ping_result = self.can_ping(gate) - self.log.warning("Ping AP Gateway[{}] response : {}".format( - gate, ping_result)) - if ping_result: - self.retry_pass_count += 1 - return True - self.fail_count += 1 - return False - - def log_attens(self): - """Log DB from channels""" - - attenuation = ', '.join('{:>5.2f}dB '.format(atten.get_atten()) - for atten in self.attenuators) - self.log.debug('[Attenuation] %s', attenuation) - - def can_ping(self, ip_addr): - """A function to check ping pass. - - Args: - ip_addr: target ip address to ping - - Returns: - True if ping pass - """ - ping_result = self.dut.adb.shell("ping -c 1 {}".format(ip_addr)) - return '0%' in ping_result.split(' ') - - def browsing_test(self, stress_hour_time): - """Continue stress http_request and capture log if any fail - - Args: - stress_hour_time: hour of time to stress http_request - """ - t = threading.Thread(target=self.simulate_roaming) - t.start() - start_time = time.time() - http_request_failed = False - while time.time() < start_time + stress_hour_time * 3600: - if not self.http_request(): - http_request_failed = True - self.simulation_thread_running = False - t.join() - if http_request_failed: - self.catch_log() - else: - stop_standing_subprocess(self.tcpdump_pid) - file_name = time.strftime("%Y-%m-%d_%H:%M:%S", time.localtime()) - self.tcpdump_pid = start_tcpdump(self.dut, file_name) - - def test_roaming(self): - network = self.reference_networks[0]["2g"] - wutils.connect_to_wifi_network(self.dut, network) - - time.sleep(10) - test_time_slot = int( - self.total_test_hour / self.log_capture_period_hour) - edge_time_slot = int( - self.total_test_hour % self.log_capture_period_hour) - - for i in range(test_time_slot): - self.browsing_test(self.log_capture_period_hour) - if edge_time_slot: - self.browsing_test(edge_time_slot) - - self.log.info("Total roaming times: {}".format( - self.atten_roaming_count)) - self.log.info("Total ping times: {}".format(self.ping_count)) - self.log.info("Retry pass times: {}".format(self.retry_pass_count)) - self.log.info("Total fail times: {}".format(self.fail_count)) - if self.fail_count: - signals.TestFailure( - 'Find roaming fail condition', - extras={ - 'Roaming fail times': self.fail_count - }) diff --git a/acts/tests/google/wifi/WifiIOTTest.py b/acts/tests/google/wifi/WifiIOTTest.py deleted file mode 100644 index 1daf346dca..0000000000 --- a/acts/tests/google/wifi/WifiIOTTest.py +++ /dev/null @@ -1,376 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import itertools -import pprint -import time - -import acts.signals -import acts.test_utils.wifi.wifi_test_utils as wutils - -from acts import asserts -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest - -WifiEnums = wutils.WifiEnums - - -class WifiIOTTest(WifiBaseTest): - """ Tests for wifi IOT - - Test Bed Requirement: - * One Android device - * Wi-Fi IOT networks visible to the device - """ - - def setup_class(self): - super().setup_class() - - self.dut = self.android_devices[0] - wutils.wifi_test_device_init(self.dut) - - req_params = [ "iot_networks", ] - opt_params = [ "open_network", "iperf_server_address" ] - self.unpack_userparams(req_param_names=req_params, - opt_param_names=opt_params) - - asserts.assert_true( - len(self.iot_networks) > 0, - "Need at least one iot network with psk.") - - if getattr(self, 'open_network', False): - self.iot_networks.append(self.open_network) - - wutils.wifi_toggle_state(self.dut, True) - if "iperf_server_address" in self.user_params: - self.iperf_server = self.iperf_servers[0] - self.iperf_server.start() - - # create hashmap for testcase name and SSIDs - self.iot_test_prefix = "test_iot_connection_to_" - self.ssid_map = {} - for network in self.iot_networks: - SSID = network['SSID'].replace('-','_') - self.ssid_map[SSID] = network - - def setup_test(self): - self.dut.droid.wakeLockAcquireBright() - self.dut.droid.wakeUpNow() - - def teardown_test(self): - self.dut.droid.wakeLockRelease() - self.dut.droid.goToSleepNow() - wutils.reset_wifi(self.dut) - - def teardown_class(self): - if "iperf_server_address" in self.user_params: - self.iperf_server.stop() - - def on_fail(self, test_name, begin_time): - self.dut.take_bug_report(test_name, begin_time) - self.dut.cat_adb_log(test_name, begin_time) - - """Helper Functions""" - - def connect_to_wifi_network(self, network): - """Connection logic for open and psk wifi networks. - - Args: - params: Dictionary with network info. - """ - SSID = network[WifiEnums.SSID_KEY] - self.dut.ed.clear_all_events() - wutils.start_wifi_connection_scan(self.dut) - scan_results = self.dut.droid.wifiGetScanResults() - wutils.assert_network_in_list({WifiEnums.SSID_KEY: SSID}, scan_results) - wutils.wifi_connect(self.dut, network, num_of_tries=3) - - def run_iperf_client(self, network): - """Run iperf traffic after connection. - - Args: - params: Dictionary with network info. - """ - if "iperf_server_address" in self.user_params: - wait_time = 5 - SSID = network[WifiEnums.SSID_KEY] - self.log.info("Starting iperf traffic through {}".format(SSID)) - time.sleep(wait_time) - port_arg = "-p {}".format(self.iperf_server.port) - success, data = self.dut.run_iperf_client(self.iperf_server_address, - port_arg) - self.log.debug(pprint.pformat(data)) - asserts.assert_true(success, "Error occurred in iPerf traffic.") - - def connect_to_wifi_network_and_run_iperf(self, network): - """Connection logic for open and psk wifi networks. - - Logic steps are - 1. Connect to the network. - 2. Run iperf traffic. - - Args: - params: A dictionary with network info. - """ - self.connect_to_wifi_network(network) - self.run_iperf_client(network) - - """Tests""" - - @test_tracker_info(uuid="a57cc861-b6c2-47e4-9db6-7a3ab32c6e20") - def test_iot_connection_to_ubiquity_ap1_2g(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="2065c2f7-2b89-4da7-a15d-e5dc17b88d52") - def test_iot_connection_to_ubiquity_ap1_5g(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="6870e35b-f7a7-45bf-b021-fea049ae53de") - def test_iot_connection_to_AirportExpress_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="95f4b405-79d7-4873-a152-4384acc88f41") - def test_iot_connection_to_AirportExpress_5G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="02a8cc75-6781-4153-8d90-bed7568a1e78") - def test_iot_connection_to_AirportExtreme_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="83a42c97-1358-4ba7-bdb2-238fdb1c945e") - def test_iot_connection_to_AirportExtreme_5G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="d56cc46a-f772-4c96-b84e-4e05c82f5f9d") - def test_iot_connection_to_AirportExtremeOld_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="4b57277d-ea96-4379-bd71-8b4f03253ec8") - def test_iot_connection_to_AirportExtremeOld_5G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="2503d9ed-35df-4be0-b838-590324cecaee") - def iot_connection_to_Dlink_AC1200_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="0a44e148-a4bf-43f4-88eb-e4c1ffa850ce") - def iot_connection_to_Dlink_AC1200_5G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="6bd77417-089f-4fb1-b4c2-2cd673c64bcb") - def test_iot_connection_to_Dlink_AC3200_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="9fbff6e7-36c8-4342-9c29-bce6a8ef04ec") - def test_iot_connection_to_Dlink_AC3200_5G_1(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="bfccdaa9-8e01-488c-9768-8c71ab5ec157") - def test_iot_connection_to_Dlink_AC3200_5G_2(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="0e4978de-0435-4856-ae5a-c39cc64e375b") - def test_iot_connection_to_Dlink_N750_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="cdb82797-9981-4ba6-8958-025f59c60e83") - def test_iot_connection_to_Dlink_N750_5G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="0bf8f129-eb96-4b1e-94bd-8dd93e8731e3") - def iot_connection_to_Linksys_E800_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="f231216d-6ab6-46b7-a0a5-1ac15935e412") - def test_iot_connection_to_Linksys_AC1900_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="5acd4bec-b210-4b4c-8b2c-60f3f67798a9") - def test_iot_connection_to_Linksys_AC1900_5G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="f4fd9877-b13f-47b0-9523-1ce363200c2f") - def iot_connection_to_Linksys_AC2400_2g(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="438d679a-4f6c-476d-9eba-63b6f1f2bef4") - def iot_connection_to_Linksys_AC2400_5g(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="b9bc00d8-46c5-4c5e-bd58-93ab1ca8d53b") - def iot_connection_to_NETGEAR_AC1900_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="fb4c7d80-4c12-4b08-a40a-2745e2bd167b") - def iot_connection_to_NETGEAR_AC1900_5G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="054d2ffc-97fd-4613-bf47-acedd0fa4701") - def test_iot_connection_to_NETGEAR_AC3200_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="d15a789a-def5-4c6a-b59e-1a75f73cc6a9") - def test_iot_connection_to_NETGEAR_AC3200_5G_1(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="1de6369e-97da-479f-b17c-9144bb814f51") - def test_iot_connection_to_NETGEAR_AC3200_5G_2(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="008ec18e-fd48-4359-8a0d-223c921a1faa") - def iot_connection_to_NETGEAR_N300_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="c61eeaf0-af02-46bf-bcec-871e2f9dee71") - def iot_connection_to_WNDR4500v2_AES_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="dcad3474-4022-48bc-8529-07321611b616") - def iot_connection_to_WNDR4500v2_WEP_SHARED128_5G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="3573a880-4542-4dea-9909-aa2f9865a059") - def iot_connection_to_ARCHER_WEP_OPEN_64_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="9c15c52e-945a-4b9b-bf0e-5bd6293dad1c") - def iot_connection_to_ARCHER_WEP_OPEN_128_5G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="e5517b82-c225-449d-83ac-055a561a764f") - def test_iot_connection_to_TP_LINK_AC1700_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="9531d3cc-129d-4501-a5e3-d7502120cd8b") - def test_iot_connection_to_TP_LINK_AC1700_5G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="eab810d4-8e07-49c9-86c1-cb8d1a0285d0") - def iot_connection_to_TP_LINK_N300_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="05d4cb25-a58d-46b4-a5ff-6e3fe28f2b16") - def iot_connection_to_fritz_7490_5g(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="8333e5e6-72fd-4957-bab0-fa45ce1d765a") - def iot_connection_to_NETGEAR_R8500_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="c88053fb-730f-4447-a802-1fb9721f69df") - def iot_connection_to_NETGEAR_R8500_5G1(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="f5d1e44b-396b-4976-bb0c-160bdce89a59") - def iot_connection_to_NETGEAR_R8500_5G2(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="7c12f943-d9e2-45b1-aa84-fcb43efbbb04") - def test_iot_connection_to_TP_LINK_5504_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="52be6b76-5e43-4289-83e1-4cd0d995d39b") - def test_iot_connection_to_TP_LINK_5504_5G_1(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="0b43d1da-e207-443d-b16c-c4ee3e924036") - def test_iot_connection_to_TP_LINK_5504_5G_2(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="4adcef5c-589a-4398-a28c-28a56d762f72") - def test_iot_connection_to_TP_LINK_C2600_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="3955a443-505b-4015-9daa-f52abbad8377") - def test_iot_connection_to_TP_LINK_C2600_5G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="3e9115dd-adb6-40a4-9831-dca8f1f32abe") - def test_iot_connection_to_Linksys06832_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="5dca028a-7384-444f-b231-973054afe215") - def test_iot_connection_to_Linksys06832_5G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="e639f6db-ad8e-4b4f-91f3-10acdf93142a") - def test_iot_connection_to_AmpedAthena_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="3dd90d80-952f-4f17-a48a-fe42e7d6e1ff") - def test_iot_connection_to_AmpedAthena_5G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="b9babe3a-ecba-4c5c-bc6b-0ba48c744e66") - def test_iot_connection_to_ASUS_AC3100_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="f8f06f92-821d-4e80-8f1e-efb6c6adc12a") - def test_iot_connection_to_ASUS_AC3100_5G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="f4d227df-1151-469a-b01c-f4b1c1f7a84b") - def iot_connection_to_NETGEAR_WGR614_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) diff --git a/acts/tests/google/wifi/WifiIOTTwPkg1Test.py b/acts/tests/google/wifi/WifiIOTTwPkg1Test.py deleted file mode 100644 index c6f8c3dc98..0000000000 --- a/acts/tests/google/wifi/WifiIOTTwPkg1Test.py +++ /dev/null @@ -1,362 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2018 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import itertools -import pprint -import time - -import acts.signals -import acts.test_utils.wifi.wifi_test_utils as wutils - -from acts import asserts -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest -from acts.controllers import iperf_server as ipf - -import json -import logging -import math -import os -from acts import utils -import csv - -WifiEnums = wutils.WifiEnums - - -class WifiIOTTwPkg1Test(WifiBaseTest): - """ Tests for wifi IOT - - Test Bed Requirement: - * One Android device - * Wi-Fi IOT networks visible to the device - """ - - def setup_class(self): - super().setup_class() - - self.dut = self.android_devices[0] - wutils.wifi_test_device_init(self.dut) - - req_params = [ "iot_networks", ] - opt_params = [ "open_network", - "iperf_server_address","iperf_port_arg", - "pdu_address" , "pduon_wait_time","pduon_address" - ] - self.unpack_userparams(req_param_names=req_params, - opt_param_names=opt_params) - - asserts.assert_true( - len(self.iot_networks) > 0, - "Need at least one iot network with psk.") - - if getattr(self, 'open_network', False): - self.iot_networks.append(self.open_network) - - wutils.wifi_toggle_state(self.dut, True) - if "iperf_server_address" in self.user_params: - self.iperf_server = self.iperf_servers[0] - - # create hashmap for testcase name and SSIDs - self.iot_test_prefix = "test_iot_connection_to_" - self.ssid_map = {} - for network in self.iot_networks: - SSID = network['SSID'].replace('-','_') - self.ssid_map[SSID] = network - - # create folder for IOT test result - self.log_path = os.path.join(logging.log_path, "IOT_results") - os.makedirs(self.log_path, exist_ok=True) - - Header=("test_name","throughput_TX","throughput_RX") - self.csv_write(Header) - - # check pdu_address - if "pdu_address" and "pduon_wait_time" in self.user_params: - self.pdu_func() - - def setup_test(self): - self.dut.droid.wakeLockAcquireBright() - self.dut.droid.wakeUpNow() - - def teardown_test(self): - self.dut.droid.wakeLockRelease() - self.dut.droid.goToSleepNow() - wutils.reset_wifi(self.dut) - - def teardown_class(self): - if "iperf_server_address" in self.user_params: - self.iperf_server.stop() - - def on_fail(self, test_name, begin_time): - self.dut.take_bug_report(test_name, begin_time) - self.dut.cat_adb_log(test_name, begin_time) - - """Helper Functions""" - - def connect_to_wifi_network(self, network): - """Connection logic for open and psk wifi networks. - - Args: - params: Dictionary with network info. - """ - SSID = network[WifiEnums.SSID_KEY] - self.dut.ed.clear_all_events() - wutils.start_wifi_connection_scan(self.dut) - scan_results = self.dut.droid.wifiGetScanResults() - wutils.assert_network_in_list({WifiEnums.SSID_KEY: SSID}, scan_results) - wutils.wifi_connect(self.dut, network, num_of_tries=3) - - def run_iperf_client(self, network): - """Run iperf TX throughput after connection. - - Args: - params: Dictionary with network info. - """ - if "iperf_server_address" in self.user_params: - - # Add iot_result - iot_result = [] - self.iperf_server.start(tag="TX_server_{}".format( - self.current_test_name)) - wait_time = 5 - SSID = network[WifiEnums.SSID_KEY] - self.log.info("Starting iperf traffic TX through {}".format(SSID)) - time.sleep(wait_time) - port_arg = "-p {} -J {}".format(self.iperf_server.port,self.iperf_port_arg) - success, data = self.dut.run_iperf_client(self.iperf_server_address, - port_arg) - # Parse and log result - client_output_path = os.path.join( - self.iperf_server.log_path, "IperfDUT,{},TX_client_{}".format( - self.iperf_server.port,self.current_test_name)) - with open(client_output_path, 'w') as out_file: - out_file.write("\n".join(data)) - self.iperf_server.stop() - - iperf_file = self.iperf_server.log_files[-1] - try: - iperf_result = ipf.IPerfResult(iperf_file) - curr_throughput = math.fsum(iperf_result.instantaneous_rates) - except: - self.log.warning( - "ValueError: Cannot get iperf result. Setting to 0") - curr_throughput = 0 - iot_result.append(curr_throughput) - self.log.info("Throughput is {0:.2f} Mbps".format(curr_throughput)) - - self.log.debug(pprint.pformat(data)) - asserts.assert_true(success, "Error occurred in iPerf traffic.") - return iot_result - - def run_iperf_server(self, network): - """Run iperf RX throughput after connection. - - Args: - params: Dictionary with network info. - - Returns: - iot_result: dict containing iot_results - """ - if "iperf_server_address" in self.user_params: - - # Add iot_result - iot_result = [] - self.iperf_server.start(tag="RX_client_{}".format( - self.current_test_name)) - wait_time = 5 - SSID = network[WifiEnums.SSID_KEY] - self.log.info("Starting iperf traffic RX through {}".format(SSID)) - time.sleep(wait_time) - port_arg = "-p {} -J -R {}".format(self.iperf_server.port,self.iperf_port_arg) - success, data = self.dut.run_iperf_client(self.iperf_server_address, - port_arg) - client_output_path = os.path.join( - self.iperf_server.log_path, "IperfDUT,{},RX_server_{}".format( - self.iperf_server.port,self.current_test_name)) - with open(client_output_path, 'w') as out_file: - out_file.write("\n".join(data)) - self.iperf_server.stop() - - iperf_file = client_output_path - try: - iperf_result = ipf.IPerfResult(iperf_file) - curr_throughput = math.fsum(iperf_result.instantaneous_rates) - except: - self.log.warning( - "ValueError: Cannot get iperf result. Setting to 0") - curr_throughput = 0 - iot_result.append(curr_throughput) - self.log.info("Throughput is {0:.2f} Mbps".format(curr_throughput)) - - self.log.debug(pprint.pformat(data)) - asserts.assert_true(success, "Error occurred in iPerf traffic.") - return iot_result - - def iperf_test_func(self,network): - """Main function to test iperf TX/RX. - - Args: - params: Dictionary with network info - """ - # Initialize - iot_result = {} - - # Run RvR and log result - iot_result["throughput_TX"] = self.run_iperf_client(network) - iot_result["throughput_RX"] = self.run_iperf_server(network) - iot_result["test_name"] = self.current_test_name - - # Save output as text file - results_file_path = "{}/{}.json".format(self.log_path, - self.current_test_name) - with open(results_file_path, 'w') as results_file: - json.dump(iot_result, results_file, indent=4) - - data=(iot_result["test_name"],iot_result["throughput_TX"][0], - iot_result["throughput_RX"][0]) - self.csv_write(data) - - def csv_write(self,data): - with open("{}/Result.csv".format(self.log_path), "a", newline="") as csv_file: - csv_writer = csv.writer(csv_file,delimiter=',') - csv_writer.writerow(data) - csv_file.close() - - def pdu_func(self): - """control Power Distribution Units on local machine. - - Logic steps are - 1. Turn off PDU for all port. - 2. Turn on PDU for specified port. - """ - out_file_name = "PDU.log" - self.full_out_path = os.path.join(self.log_path, out_file_name) - cmd = "curl http://snmp:1234@{}/offs.cgi?led=11111111> {}".format(self.pdu_address, - self.full_out_path) - self.pdu_process = utils.start_standing_subprocess(cmd) - wait_time = 10 - self.log.info("Starting set PDU to OFF") - time.sleep(wait_time) - self.full_out_path = os.path.join(self.log_path, out_file_name) - cmd = "curl http://snmp:1234@{}/ons.cgi?led={}> {}".format(self.pdu_address, - self.pduon_address, - self.full_out_path) - self.pdu_process = utils.start_standing_subprocess(cmd) - wait_time = int("{}".format(self.pduon_wait_time)) - self.log.info("Starting set PDU to ON for port1," - "wait for {}s".format(self.pduon_wait_time)) - time.sleep(wait_time) - self.log.info("PDU setup complete") - - def connect_to_wifi_network_and_run_iperf(self, network): - """Connection logic for open and psk wifi networks. - - Logic steps are - 1. Connect to the network. - 2. Run iperf throghput. - - Args: - params: A dictionary with network info. - """ - self.connect_to_wifi_network(network) - self.iperf_test_func(network) - - """Tests""" - - @test_tracker_info(uuid="0e4ad6ed-595c-4629-a4c9-c6be9c3c58e0") - def test_iot_connection_to_ASUS_RT_AC68U_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="a76d8acc-808e-4a5d-a52b-5ba07d07b810") - def test_iot_connection_to_ASUS_RT_AC68U_5G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="659a3e5e-07eb-4905-9cda-92e959c7b674") - def test_iot_connection_to_D_Link_DIR_868L_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="6bcfd736-30fc-48a8-b4fb-723d1d113f3c") - def test_iot_connection_to_D_Link_DIR_868L_5G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="c9da945a-2c4a-44e1-881d-adf307b39b21") - def test_iot_connection_to_TP_LINK_WR940N_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="db0d224d-df81-401f-bf35-08ad02e41a71") - def test_iot_connection_to_ASUS_RT_N66U_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="845ff1d6-618d-40f3-81c3-6ed3a0751fde") - def test_iot_connection_to_ASUS_RT_N66U_5G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="6908039b-ccc9-4777-a0f1-3494ce642014") - def test_iot_connection_to_ASUS_RT_AC54U_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="2647c15f-2aad-47d7-8dee-b2ee1ac4cef6") - def test_iot_connection_to_ASUS_RT_AC54U_5G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="99678f66-ddf1-454d-87e4-e55177ec380d") - def test_iot_connection_to_ASUS_RT_N56U_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="4dd75e81-9a8e-44fd-9449-09f5ab8a63c3") - def test_iot_connection_to_ASUS_RT_N56U_5G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="315397ce-50d5-4abf-a11c-1abcaef832d3") - def test_iot_connection_to_BELKIN_F9K1002v1_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="05ba464a-b1ef-4ac1-a32f-c919ec4aa1dd") - def test_iot_connection_to_CISCO_E1200_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="04912868-4a47-40ce-877e-4e4c89849557") - def test_iot_connection_to_TP_LINK_C2_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="53517a21-3802-4185-b8bb-6eaace063a42") - def test_iot_connection_to_TP_LINK_C2_5G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="71c08c1c-415d-4da4-a151-feef43fb6ad8") - def test_iot_connection_to_ASUS_RT_AC66U_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="2322c155-07d1-47c9-bd21-2e358e3df6ee") - def test_iot_connection_to_ASUS_RT_AC66U_5G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) diff --git a/acts/tests/google/wifi/WifiIOTtpeTest.py b/acts/tests/google/wifi/WifiIOTtpeTest.py deleted file mode 100644 index fd141ffea6..0000000000 --- a/acts/tests/google/wifi/WifiIOTtpeTest.py +++ /dev/null @@ -1,216 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import itertools -import pprint -import time - -import acts.signals -import acts.test_utils.wifi.wifi_test_utils as wutils - -from acts import asserts -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest - -WifiEnums = wutils.WifiEnums - - -class WifiIOTtpeTest(WifiBaseTest): - """ Tests for wifi IOT - - Test Bed Requirement: - * One Android device - * Wi-Fi IOT networks visible to the device - """ - - def setup_class(self): - super().setup_class() - - self.dut = self.android_devices[0] - wutils.wifi_test_device_init(self.dut) - - req_params = [ "iot_networks", ] - opt_params = [ "open_network", "iperf_server_address" ] - self.unpack_userparams(req_param_names=req_params, - opt_param_names=opt_params) - - asserts.assert_true( - len(self.iot_networks) > 0, - "Need at least one iot network with psk.") - - if getattr(self, 'open_network', False): - self.iot_networks.append(self.open_network) - - wutils.wifi_toggle_state(self.dut, True) - if "iperf_server_address" in self.user_params: - self.iperf_server = self.iperf_servers[0] - self.iperf_server.start() - - # create hashmap for testcase name and SSIDs - self.iot_test_prefix = "test_iot_connection_to_" - self.ssid_map = {} - for network in self.iot_networks: - SSID = network['SSID'].replace('-','_') - self.ssid_map[SSID] = network - - def setup_test(self): - self.dut.droid.wakeLockAcquireBright() - self.dut.droid.wakeUpNow() - - def teardown_test(self): - self.dut.droid.wakeLockRelease() - self.dut.droid.goToSleepNow() - wutils.reset_wifi(self.dut) - - def teardown_class(self): - if "iperf_server_address" in self.user_params: - self.iperf_server.stop() - - def on_fail(self, test_name, begin_time): - self.dut.take_bug_report(test_name, begin_time) - self.dut.cat_adb_log(test_name, begin_time) - - """Helper Functions""" - - def connect_to_wifi_network(self, network): - """Connection logic for open and psk wifi networks. - - Args: - params: Dictionary with network info. - """ - SSID = network[WifiEnums.SSID_KEY] - self.dut.ed.clear_all_events() - wutils.start_wifi_connection_scan(self.dut) - scan_results = self.dut.droid.wifiGetScanResults() - wutils.assert_network_in_list({WifiEnums.SSID_KEY: SSID}, scan_results) - wutils.wifi_connect(self.dut, network, num_of_tries=3) - - def run_iperf_client(self, network): - """Run iperf traffic after connection. - - Args: - params: Dictionary with network info. - """ - if "iperf_server_address" in self.user_params: - wait_time = 5 - SSID = network[WifiEnums.SSID_KEY] - self.log.info("Starting iperf traffic through {}".format(SSID)) - time.sleep(wait_time) - port_arg = "-p {}".format(self.iperf_server.port) - success, data = self.dut.run_iperf_client(self.iperf_server_address, - port_arg) - self.log.debug(pprint.pformat(data)) - asserts.assert_true(success, "Error occurred in iPerf traffic.") - - def connect_to_wifi_network_and_run_iperf(self, network): - """Connection logic for open and psk wifi networks. - - Logic steps are - 1. Connect to the network. - 2. Run iperf traffic. - - Args: - params: A dictionary with network info. - """ - self.connect_to_wifi_network(network) - self.run_iperf_client(network) - - """Tests""" - - @test_tracker_info(uuid="0e4ad6ed-595c-4629-a4c9-c6be9c3c58e0") - def test_iot_connection_to_ASUS_RT_AC68U_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="a76d8acc-808e-4a5d-a52b-5ba07d07b810") - def test_iot_connection_to_ASUS_RT_AC68U_5G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="659a3e5e-07eb-4905-9cda-92e959c7b674") - def test_iot_connection_to_D_Link_DIR_868L_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="6bcfd736-30fc-48a8-b4fb-723d1d113f3c") - def test_iot_connection_to_D_Link_DIR_868L_5G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="c9da945a-2c4a-44e1-881d-adf307b39b21") - def test_iot_connection_to_TP_LINK_WR940N_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="db0d224d-df81-401f-bf35-08ad02e41a71") - def test_iot_connection_to_ASUS_RT_N66U_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="845ff1d6-618d-40f3-81c3-6ed3a0751fde") - def test_iot_connection_to_ASUS_RT_N66U_5G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="6908039b-ccc9-4777-a0f1-3494ce642014") - def test_iot_connection_to_ASUS_RT_AC54U_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="2647c15f-2aad-47d7-8dee-b2ee1ac4cef6") - def test_iot_connection_to_ASUS_RT_AC54U_5G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="99678f66-ddf1-454d-87e4-e55177ec380d") - def test_iot_connection_to_ASUS_RT_N56U_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="4dd75e81-9a8e-44fd-9449-09f5ab8a63c3") - def test_iot_connection_to_ASUS_RT_N56U_5G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="315397ce-50d5-4abf-a11c-1abcaef832d3") - def test_iot_connection_to_BELKIN_F9K1002v1_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="05ba464a-b1ef-4ac1-a32f-c919ec4aa1dd") - def test_iot_connection_to_CISCO_E1200_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="04912868-4a47-40ce-877e-4e4c89849557") - def test_iot_connection_to_TP_LINK_C2_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="53517a21-3802-4185-b8bb-6eaace063a42") - def test_iot_connection_to_TP_LINK_C2_5G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="71c08c1c-415d-4da4-a151-feef43fb6ad8") - def test_iot_connection_to_ASUS_RT_AC66U_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="2322c155-07d1-47c9-bd21-2e358e3df6ee") - def test_iot_connection_to_ASUS_RT_AC66U_5G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key]) diff --git a/acts/tests/google/wifi/WifiLinkProbeTest.py b/acts/tests/google/wifi/WifiLinkProbeTest.py deleted file mode 100644 index 7e6d58ffd7..0000000000 --- a/acts/tests/google/wifi/WifiLinkProbeTest.py +++ /dev/null @@ -1,155 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2019 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import time - -from acts import asserts -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest -import acts.test_utils.wifi.wifi_test_utils as wutils - -WifiEnums = wutils.WifiEnums -NUM_LINK_PROBES = 8 -PROBE_DELAY_SEC = 3 -ATTENUATION = 40 - - -class WifiLinkProbeTest(WifiBaseTest): - """ - Tests sending 802.11 Probe Request frames to the currently connected AP to - determine if the uplink to the AP is working. - - Test Bed Requirements: - * One Android Device - * One Wi-Fi network visible to the device, with an attenuator - """ - - def setup_class(self): - super().setup_class() - - self.dut = self.android_devices[0] - wutils.wifi_test_device_init(self.dut) - self.unpack_userparams(req_param_names=[], - opt_param_names=["reference_networks"]) - - if "AccessPoint" in self.user_params: - self.legacy_configure_ap_and_start() - - asserts.assert_true(len(self.reference_networks) > 0, - "Need at least one reference network with psk.") - self.attenuators = wutils.group_attenuators(self.attenuators) - - def setup_test(self): - self.dut.droid.wakeLockAcquireBright() - self.dut.droid.wakeUpNow() - wutils.wifi_toggle_state(self.dut, True) - self.attenuators[0].set_atten(0) - self.attenuators[1].set_atten(0) - - def teardown_test(self): - self.dut.droid.wakeLockRelease() - self.dut.droid.goToSleepNow() - wutils.reset_wifi(self.dut) - - def on_fail(self, test_name, begin_time): - self.dut.take_bug_report(test_name, begin_time) - self.dut.cat_adb_log(test_name, begin_time) - - def teardown_class(self): - if "AccessPoint" in self.user_params: - del self.user_params["reference_networks"] - - # HELPER METHODS - - def _test_link_probe_does_not_crash_device(self, network): - """ - Connect to a network, send link probes, and verify that the device did - not crash. Also verify that at least one link probe succeeded. - - Steps: - 1. Connect to a network. - 2. Send a few link probes. - 3. Verify that at least one link probe succeeded. - 4. Ensure that the device did not crash (by checking that it is - connected to the expected network). - """ - wutils.wifi_connect(self.dut, network, num_of_tries=3) - - results = wutils.send_link_probes( - self.dut, NUM_LINK_PROBES, PROBE_DELAY_SEC) - - asserts.assert_true(any(result.is_success for result in results), - "Expect at least 1 probe success: " + str(results)) - - wifi_info = self.dut.droid.wifiGetConnectionInfo() - expected = network[WifiEnums.SSID_KEY] - actual = wifi_info[WifiEnums.SSID_KEY] - asserts.assert_equal( - expected, actual, - "Device did not remain connected after sending link probes!") - - def _test_link_probe_ap_attenuated(self, network): - """ - Connect to a network, significantly attenuate the signal, and verify - that the device did not crash. - - Steps: - 1. Connect to a network. - 2. Attenuate the signal. - 3. Send a few link probes. - 4. Stop attenuating the signal. - 5. Ensure that the device did not crash (by checking that it is - connected to the expected network). - """ - wutils.wifi_connect(self.dut, network, num_of_tries=3) - self.attenuators[0].set_atten(ATTENUATION) - - wutils.send_link_probes(self.dut, NUM_LINK_PROBES, PROBE_DELAY_SEC) - - # we cannot assert for failed link probe when attenuated, this would - # depend too much on the attenuator setup => too flaky - - self.attenuators[0].set_atten(0) - time.sleep(PROBE_DELAY_SEC * 3) - wifi_info = self.dut.droid.wifiGetConnectionInfo() - expected = network[WifiEnums.SSID_KEY] - actual = wifi_info[WifiEnums.SSID_KEY] - asserts.assert_equal( - expected, actual, - "Device did not remain connected after sending link probes!") - - # TEST METHODS - - @test_tracker_info(uuid='2afd309b-6bf3-4de4-9d8a-e4d35354a2cb') - def test_link_probe_does_not_crash_device_2g(self): - network = self.reference_networks[0]["2g"] - self._test_link_probe_does_not_crash_device(network) - - @test_tracker_info(uuid='69417a6d-7090-4dd0-81ad-55fa3f12b7b1') - def test_link_probe_does_not_crash_device_5g(self): - network = self.reference_networks[0]["5g"] - self._test_link_probe_does_not_crash_device(network) - - @test_tracker_info(uuid='54b8ffaa-c305-4772-928d-03342c51122d') - def test_link_probe_ap_attenuated_2g(self): - network = self.reference_networks[0]["2g"] - self._test_link_probe_ap_attenuated(network) - - @test_tracker_info(uuid='54e29fa4-ff44-4aad-8999-676b361cacf4') - def test_link_probe_ap_attenuated_5g(self): - network = self.reference_networks[0]["5g"] - self._test_link_probe_ap_attenuated(network) - diff --git a/acts/tests/google/wifi/WifiMacRandomizationTest.py b/acts/tests/google/wifi/WifiMacRandomizationTest.py deleted file mode 100644 index 68cf85417c..0000000000 --- a/acts/tests/google/wifi/WifiMacRandomizationTest.py +++ /dev/null @@ -1,560 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2019 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import itertools -import pprint -import queue -import re -import time - -import acts.base_test -import acts.signals as signals -import acts.test_utils.wifi.wifi_test_utils as wutils -import acts.utils - -from acts import asserts -from acts.test_decorators import test_tracker_info -from acts.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_2G -from acts.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_5G -from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest -from scapy.all import * -from acts.controllers.ap_lib import hostapd_constants - -WifiEnums = wutils.WifiEnums - -# Default timeout used for reboot, toggle WiFi and Airplane mode, -# for the system to settle down after the operation. -DEFAULT_TIMEOUT = 10 -SHORT_TIMEOUT = 5 - -# Constants for WiFi state change operations. -FORGET = 1 -TOGGLE = 2 -REBOOT_DUT = 3 -REBOOT_AP = 4 - -# MAC Randomization setting constants. -RANDOMIZATION_NONE = 0 -RANDOMIZATION_PERSISTENT = 1 - - -class WifiMacRandomizationTest(WifiBaseTest): - """Tests for APIs in Android's WifiManager class. - - Test Bed Requirement: - * Atleast one Android device and atleast two Access Points. - * Several Wi-Fi networks visible to the device. - """ - - def setup_class(self): - super().setup_class() - - self.dut = self.android_devices[0] - self.dut_client = self.android_devices[1] - wutils.wifi_test_device_init(self.dut) - wutils.wifi_test_device_init(self.dut_client) - req_params = ["dbs_supported_models"] - opt_param = [ - "open_network", "reference_networks", "wep_networks" - ] - self.unpack_userparams( - req_param_names=req_params, opt_param_names=opt_param) - - if not hasattr(self, 'packet_capture'): - raise signals.TestFailure("Needs packet_capture attribute to " - "support sniffing.") - self.configure_packet_capture() - - if "AccessPoint" in self.user_params: - if "AccessPoint" in self.user_params: - self.legacy_configure_ap_and_start(wep_network=True, ap_count=2) - - asserts.assert_true( - len(self.reference_networks) > 0, - "Need at least one reference network with psk.") - - # Reboot device to reset factory MAC of wlan1 - self.dut.reboot() - self.dut_client.reboot() - time.sleep(DEFAULT_TIMEOUT) - wutils.wifi_toggle_state(self.dut, True) - wutils.wifi_toggle_state(self.dut_client, True) - self.soft_ap_factory_mac = self.get_soft_ap_mac_address() - self.sta_factory_mac = self.dut.droid.wifigetFactorymacAddresses()[0] - - self.wpapsk_2g = self.reference_networks[0]["2g"] - self.wpapsk_5g = self.reference_networks[0]["5g"] - self.wep_2g = self.wep_networks[0]["2g"] - self.wep_5g = self.wep_networks[0]["5g"] - self.open_2g = self.open_network[0]["2g"] - self.open_5g = self.open_network[0]["5g"] - - def setup_test(self): - for ad in self.android_devices: - ad.droid.wakeLockAcquireBright() - ad.droid.wakeUpNow() - wutils.wifi_toggle_state(ad, True) - - def teardown_test(self): - for ad in self.android_devices: - ad.droid.wakeLockRelease() - ad.droid.goToSleepNow() - wutils.reset_wifi(self.dut) - wutils.reset_wifi(self.dut_client) - - def on_fail(self, test_name, begin_time): - self.dut.cat_adb_log(test_name, begin_time) - self.dut.take_bug_report(test_name, begin_time) - self.dut_client.take_bug_report(test_name, begin_time) - - def teardown_class(self): - if "AccessPoint" in self.user_params: - del self.user_params["reference_networks"] - del self.user_params["open_network"] - del self.user_params["wep_networks"] - - - """Helper Functions""" - - - def get_randomized_mac(self, network): - """Get the randomized MAC address. - - Args: - network: dict, network information. - - Returns: - The randomized MAC address string for the network. - - """ - return self.dut.droid.wifigetRandomizedMacAddress(network) - - def connect_to_network_and_verify_mac_randomization(self, network, - status=RANDOMIZATION_PERSISTENT): - """Connect to the given network and verify MAC. - - Args: - network: dict, the network information. - status: int, MAC randomization level. - - Returns: - The randomized MAC addresss string. - - """ - wutils.connect_to_wifi_network(self.dut, network) - return self.verify_mac_randomization(network, status=status) - - def verify_mac_randomization_and_add_to_list(self, network, mac_list): - """Connect to a network and populate it's MAC in a reference list, - that will be used to verify any repeated MAC addresses. - - Args: - network: dict, the network information. - mac_list: list of MAC addresss strings. - - """ - rand_mac = self.connect_to_network_and_verify_mac_randomization( - network) - if rand_mac in mac_list: - raise signals.TestFailure('A new Randomized MAC was not generated ' - ' for this network %s.' % network) - mac_list.append(rand_mac) - - def verify_mac_randomization(self, network, status=RANDOMIZATION_PERSISTENT): - """Get the various types of MAC addresses for the device and verify. - - Args: - network: dict, the network information. - status: int, MAC randomization level. - - Returns: - The randomized MAC address string for the network. - - """ - randomized_mac = self.get_randomized_mac(network) - default_mac = self.get_sta_mac_address() - self.log.info("Factory MAC = %s\nRandomized MAC = %s\nDefault MAC = %s" % - (self.sta_factory_mac, randomized_mac, default_mac)) - message = ('Randomized MAC and Factory MAC are the same. ' - 'Randomized MAC = %s, Factory MAC = %s' % (randomized_mac, self.sta_factory_mac)) - asserts.assert_true(randomized_mac != self.sta_factory_mac, message) - if status == RANDOMIZATION_NONE: - asserts.assert_true(default_mac == self.sta_factory_mac, "Connection is not " - "using Factory MAC as the default MAC.") - else: - message = ('Connection is not using randomized MAC as the default MAC. ' - 'Randomized MAC = %s, Deafult MAC = %s' % (randomized_mac, default_mac)) - asserts.assert_true(default_mac == randomized_mac, message) - return randomized_mac - - def check_mac_persistence(self, network, condition): - """Check if the MAC is persistent after carrying out specific operations - like forget WiFi, toggle WiFi, reboot device and AP. - - Args: - network: dict, The network information. - condition: int, value to trigger certain operation on the device. - - Raises: - TestFaikure is the MAC is not persistent. - - """ - rand_mac1 = self.connect_to_network_and_verify_mac_randomization(network) - - if condition == FORGET: - wutils.wifi_forget_network(self.dut, network['SSID']) - - elif condition == TOGGLE: - wutils.wifi_toggle_state(self.dut, False) - wutils.wifi_toggle_state(self.dut, True) - - elif condition == REBOOT_DUT: - self.dut.reboot() - time.sleep(DEFAULT_TIMEOUT) - - elif condition == REBOOT_AP: - wutils.turn_ap_off(self, 1) - time.sleep(DEFAULT_TIMEOUT) - wutils.turn_ap_on(self, 1) - time.sleep(DEFAULT_TIMEOUT) - - rand_mac2 = self.connect_to_network_and_verify_mac_randomization(network) - - if rand_mac1 != rand_mac2: - raise signals.TestFailure('Randomized MAC is not persistent after ' - 'forgetting networ. Old MAC = %s New MAC' - ' = %s' % (rand_mac1, rand_mac2)) - - def verify_mac_not_found_in_pcap(self, mac, packets): - for pkt in packets: - self.log.debug("Packet Summary = %s" % pkt.summary()) - if mac in pkt.summary(): - raise signals.TestFailure("Caught Factory MAC in packet sniffer." - "Packet = %s" % pkt.show()) - - def verify_mac_is_found_in_pcap(self, mac, packets): - for pkt in packets: - self.log.debug("Packet Summary = %s" % pkt.summary()) - if mac in pkt.summary(): - return - raise signals.TestFailure("Did not find MAC = %s in packet sniffer." - % mac) - - def get_sta_mac_address(self): - """Gets the current MAC address being used for client mode.""" - out = self.dut.adb.shell("ifconfig wlan0") - res = re.match(".* HWaddr (\S+).*", out, re.S) - return res.group(1) - - def get_soft_ap_mac_address(self): - """Gets the current MAC address being used for SoftAp.""" - if self.dut.model in self.dbs_supported_models: - out = self.dut.adb.shell("ifconfig wlan1") - return re.match(".* HWaddr (\S+).*", out, re.S).group(1) - else: - return self.get_sta_mac_address() - """Tests""" - - - @test_tracker_info(uuid="2dd0a05e-a318-45a6-81cd-962e098fa242") - def test_set_mac_randomization_to_none(self): - self.pcap_procs = wutils.start_pcap( - self.packet_capture, 'dual', self.test_name) - network = self.wpapsk_2g - # Set macRandomizationSetting to RANDOMIZATION_NONE. - network["macRand"] = RANDOMIZATION_NONE - self.connect_to_network_and_verify_mac_randomization(network, - status=RANDOMIZATION_NONE) - pcap_fname = '%s_%s.pcap' % \ - (self.pcap_procs[hostapd_constants.BAND_2G][1], - hostapd_constants.BAND_2G.upper()) - time.sleep(SHORT_TIMEOUT) - wutils.stop_pcap(self.packet_capture, self.pcap_procs, False) - packets = rdpcap(pcap_fname) - self.verify_mac_is_found_in_pcap(self.sta_factory_mac, packets) - - @test_tracker_info(uuid="d9e64202-02d5-421a-967c-42e45f1f7f91") - def test_mac_randomization_wpapsk(self): - """Verify MAC randomization for a WPA network. - - Steps: - 1. Connect to WPA network. - 2. Get the Factory, Randomized and Default MACs. - 3. Verify randomized MAC is the default MAC for the device. - - """ - self.connect_to_network_and_verify_mac_randomization(self.wpapsk_2g) - - @test_tracker_info(uuid="b5be7c53-2edf-449e-ba70-a1fb7acf735e") - def test_mac_randomization_wep(self): - """Verify MAC randomization for a WEP network. - - Steps: - 1. Connect to WEP network. - 2. Get the Factory, Randomized and Default MACs. - 3. Verify randomized MAC is the default MAC for the device. - - """ - self.connect_to_network_and_verify_mac_randomization(self.wep_2g) - - @test_tracker_info(uuid="f5347ac0-68d5-4882-a58d-1bd0d575503c") - def test_mac_randomization_open(self): - """Verify MAC randomization for a open network. - - Steps: - 1. Connect to open network. - 2. Get the Factory, Randomized and Default MACs. - 3. Verify randomized MAC is the default MAC for the device. - - """ - self.connect_to_network_and_verify_mac_randomization(self.open_2g) - - @test_tracker_info(uuid="5d260421-2adf-4ace-b281-3d15aec39b2a") - def test_persistent_mac_after_forget(self): - """Check if MAC is persistent after forgetting/adding a network. - - Steps: - 1. Connect to WPA network and get the randomized MAC. - 2. Forget the network. - 3. Connect to the same network again. - 4. Verify randomized MAC has not changed. - - """ - self.check_mac_persistence(self.wpapsk_2g, FORGET) - - @test_tracker_info(uuid="09d40a93-ead2-45ca-9905-14b05fd79f34") - def test_persistent_mac_after_toggle(self): - """Check if MAC is persistent after toggling WiFi network. - - Steps: - 1. Connect to WPA network and get the randomized MAC. - 2. Turn WiFi ON/OFF. - 3. Connect to the same network again. - 4. Verify randomized MAC has not changed. - - """ - self.check_mac_persistence(self.wpapsk_2g, TOGGLE) - - @test_tracker_info(uuid="a514f-8562-44e8-bfe0-4ecab9af165b") - def test_persistent_mac_after_device_reboot(self): - """Check if MAC is persistent after a device reboot. - - Steps: - 1. Connect to WPA network and get the randomized MAC. - 2. Reboot DUT. - 3. Connect to the same network again. - 4. Verify randomized MAC has not changed. - - """ - self.check_mac_persistence(self.wpapsk_2g, REBOOT_DUT) - - # Disable reboot test for debugging purpose. - #@test_tracker_info(uuid="82d691a0-22e4-4a3d-9596-e150531fcd34") - def persistent_mac_after_ap_reboot(self): - """Check if MAC is persistent after AP reboots itself. - - Steps: - 1. Connect to WPA network and get the randomized MAC. - 2. Reboot AP(basically restart hostapd in our case). - 3. Connect to the same network again. - 4. Verify randomized MAC has not changed. - - """ - self.check_mac_persistence(self.wpapsk_2g, REBOOT_AP) - - @test_tracker_info(uuid="e1f33dbc-808c-4e61-8a4a-3a72c1f63c7e") - def test_mac_randomization_multiple_networks(self): - """Connect to multiple networks and verify same MAC. - - Steps: - 1. Connect to network A, get randomizd MAC. - 2. Conenct to network B, get randomized MAC. - 3. Connect back to network A and verify same MAC. - 4. Connect back to network B and verify same MAC. - - """ - mac_list = list() - - # Connect to two different networks and get randomized MAC addresses. - self.verify_mac_randomization_and_add_to_list(self.wpapsk_2g, mac_list) - self.verify_mac_randomization_and_add_to_list(self.open_2g, mac_list) - - # Connect to the previous network and check MAC is persistent. - mac_wpapsk = self.connect_to_network_and_verify_mac_randomization( - self.wpapsk_2g) - msg = ('Randomized MAC is not persistent for this network %s. Old MAC = ' - '%s \nNew MAC = %s') - if mac_wpapsk != mac_list[0]: - raise signals.TestFailure(msg % (self.wpapsk_5g, mac_list[0], mac_wpapsk)) - mac_open = self.connect_to_network_and_verify_mac_randomization( - self.open_2g) - if mac_open != mac_list[1]: - raise signals.TestFailure(msg %(self.open_5g, mac_list[1], mac_open)) - - @test_tracker_info(uuid="edb5a0e5-7f3b-4147-b1d3-48ad7ad9799e") - def test_mac_randomization_differnet_APs(self): - """Verify randomization using two different APs. - - Steps: - 1. Connect to network A on AP1, get the randomized MAC. - 2. Connect to network B on AP2, get the randomized MAC. - 3. Veirfy the two MACs are different. - - """ - ap1 = self.wpapsk_2g - ap2 = self.reference_networks[1]["5g"] - mac_ap1 = self.connect_to_network_and_verify_mac_randomization(ap1) - mac_ap2 = self.connect_to_network_and_verify_mac_randomization(ap2) - if mac_ap1 == mac_ap2: - raise signals.TestFailure("Same MAC address was generated for both " - "APs: %s" % mac_ap1) - - @test_tracker_info(uuid="b815e9ce-bccd-4fc3-9774-1e1bc123a2a8") - def test_mac_randomization_ap_sta(self): - """Bring up STA and softAP and verify MAC randomization. - - Steps: - 1. Connect to a network and get randomized MAC. - 2. Bring up softAP on the DUT. - 3. Connect to softAP network on the client and get MAC. - 4. Verify AP and STA use different randomized MACs. - 5. Find the channel of the SoftAp network. - 6. Configure sniffer on that channel. - 7. Verify the factory MAC is not leaked. - - """ - wutils.set_wifi_country_code(self.dut, wutils.WifiEnums.CountryCode.US) - wutils.set_wifi_country_code(self.dut_client, wutils.WifiEnums.CountryCode.US) - mac_sta = self.connect_to_network_and_verify_mac_randomization( - self.wpapsk_2g) - softap = wutils.start_softap_and_verify(self, WIFI_CONFIG_APBAND_2G) - wutils.connect_to_wifi_network(self.dut_client, softap) - softap_info = self.dut_client.droid.wifiGetConnectionInfo() - mac_ap = softap_info['mac_address'] - if mac_sta == mac_ap: - raise signals.TestFailure("Same MAC address was used for both " - "AP and STA: %s" % mac_sta) - - # Verify SoftAp MAC is randomized - softap_mac = self.get_soft_ap_mac_address() - message = ('Randomized SoftAp MAC and Factory SoftAp MAC are the same. ' - 'Randomized SoftAp MAC = %s, Factory SoftAp MAC = %s' - % (softap_mac, self.soft_ap_factory_mac)) - asserts.assert_true(softap_mac != self.soft_ap_factory_mac, message) - - softap_channel = hostapd_constants.CHANNEL_MAP[softap_info['frequency']] - self.log.info("softap_channel = %s\n" % (softap_channel)) - result = self.packet_capture.configure_monitor_mode( - hostapd_constants.BAND_2G, softap_channel) - if not result: - raise ValueError("Failed to configure channel for 2G band") - self.pcap_procs = wutils.start_pcap( - self.packet_capture, 'dual', self.test_name) - # re-connect to the softAp network after sniffer is started - wutils.connect_to_wifi_network(self.dut_client, self.wpapsk_2g) - wutils.connect_to_wifi_network(self.dut_client, softap) - time.sleep(SHORT_TIMEOUT) - wutils.stop_pcap(self.packet_capture, self.pcap_procs, False) - pcap_fname = '%s_%s.pcap' % \ - (self.pcap_procs[hostapd_constants.BAND_2G][1], - hostapd_constants.BAND_2G.upper()) - packets = rdpcap(pcap_fname) - self.verify_mac_not_found_in_pcap(self.soft_ap_factory_mac, packets) - self.verify_mac_not_found_in_pcap(self.sta_factory_mac, packets) - self.verify_mac_is_found_in_pcap(softap_mac, packets) - self.verify_mac_is_found_in_pcap(self.get_sta_mac_address(), packets) - - @test_tracker_info(uuid="3ca3f911-29f1-41fb-b836-4d25eac1669f") - def test_roaming_mac_randomization(self): - """test MAC randomization in the roaming scenario. - - Steps: - 1. Connect to network A on AP1, get randomized MAC. - 2. Set AP1 to MAX attenuation so that we roam to AP2. - 3. Wait for device to roam to AP2 and get randomized MAC. - 4. Veirfy that the device uses same AMC for both APs. - - """ - AP1_network = self.reference_networks[0]["5g"] - AP2_network = self.reference_networks[1]["5g"] - wutils.set_attns(self.attenuators, "AP1_on_AP2_off") - mac_before_roam = self.connect_to_network_and_verify_mac_randomization( - AP1_network) - wutils.trigger_roaming_and_validate(self.dut, self.attenuators, - "AP1_off_AP2_on", AP2_network) - mac_after_roam = self.get_randomized_mac(AP2_network) - if mac_after_roam != mac_before_roam: - raise signals.TestFailure("Randomized MAC address changed after " - "roaming from AP1 to AP2.\nMAC before roam = %s\nMAC after " - "roam = %s" %(mac_before_roam, mac_after_roam)) - wutils.trigger_roaming_and_validate(self.dut, self.attenuators, - "AP1_on_AP2_off", AP1_network) - mac_after_roam = self.get_randomized_mac(AP1_network) - if mac_after_roam != mac_before_roam: - raise signals.TestFailure("Randomized MAC address changed after " - "roaming from AP1 to AP2.\nMAC before roam = %s\nMAC after " - "roam = %s" %(mac_before_roam, mac_after_roam)) - - @test_tracker_info(uuid="17b12f1a-7c62-4188-b5a5-52d7a0bb7849") - def test_check_mac_sta_with_link_probe(self): - """Test to ensure Factory MAC is not exposed, using sniffer data. - - Steps: - 1. Configure and start the sniffer on 5GHz band. - 2. Connect to 5GHz network. - 3. Send link probes. - 4. Stop the sniffer. - 5. Invoke scapy to read the .pcap file. - 6. Read each packet summary and make sure Factory MAC is not used. - - """ - self.pcap_procs = wutils.start_pcap( - self.packet_capture, 'dual', self.test_name) - time.sleep(SHORT_TIMEOUT) - network = self.wpapsk_5g - rand_mac = self.connect_to_network_and_verify_mac_randomization(network) - wutils.send_link_probes(self.dut, 3, 3) - pcap_fname = '%s_%s.pcap' % \ - (self.pcap_procs[hostapd_constants.BAND_5G][1], - hostapd_constants.BAND_5G.upper()) - wutils.stop_pcap(self.packet_capture, self.pcap_procs, False) - time.sleep(SHORT_TIMEOUT) - packets = rdpcap(pcap_fname) - self.verify_mac_not_found_in_pcap(self.sta_factory_mac, packets) - self.verify_mac_is_found_in_pcap(self.get_sta_mac_address(), packets) - - @test_tracker_info(uuid="1c2cc0fd-a340-40c4-b679-6acc5f526451") - def test_check_mac_in_wifi_scan(self): - """Test to ensure Factory MAC is not exposed, in Wi-Fi scans - - Steps: - 1. Configure and start the sniffer on both bands. - 2. Perform a full scan. - 3. Stop the sniffer. - 4. Invoke scapy to read the .pcap file. - 5. Read each packet summary and make sure Factory MAC is not used. - - """ - self.pcap_procs = wutils.start_pcap( - self.packet_capture, 'dual', self.test_name) - wutils.start_wifi_connection_scan(self.dut) - time.sleep(SHORT_TIMEOUT) - wutils.stop_pcap(self.packet_capture, self.pcap_procs, False) - pcap_fname = '%s_%s.pcap' % \ - (self.pcap_procs[hostapd_constants.BAND_2G][1], - hostapd_constants.BAND_2G.upper()) - packets = rdpcap(pcap_fname) - self.verify_mac_not_found_in_pcap(self.sta_factory_mac, packets) diff --git a/acts/tests/google/wifi/WifiManagerTest.py b/acts/tests/google/wifi/WifiManagerTest.py deleted file mode 100644 index a4ef011f35..0000000000 --- a/acts/tests/google/wifi/WifiManagerTest.py +++ /dev/null @@ -1,978 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2016 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import itertools -import pprint -import queue -import time - -import acts.base_test -import acts.signals as signals -import acts.test_utils.wifi.wifi_test_utils as wutils -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 -# Default timeout used for reboot, toggle WiFi and Airplane mode, -# for the system to settle down after the operation. -DEFAULT_TIMEOUT = 10 -BAND_2GHZ = 0 -BAND_5GHZ = 1 - - -class WifiManagerTest(WifiBaseTest): - """Tests for APIs in Android's WifiManager class. - - Test Bed Requirement: - * Two Android device - * Several Wi-Fi networks visible to the device, including an open Wi-Fi - network. - """ - - def setup_class(self): - super().setup_class() - - self.dut = self.android_devices[0] - wutils.wifi_test_device_init(self.dut) - wutils.wifi_toggle_state(self.dut, True) - - self.dut_client = None - if len(self.android_devices) > 1: - self.dut_client = self.android_devices[1] - wutils.wifi_test_device_init(self.dut_client) - wutils.wifi_toggle_state(self.dut_client, True) - - req_params = [] - opt_param = [ - "open_network", "reference_networks", "iperf_server_address", - "wpa_networks", "wep_networks", "iperf_server_port" - ] - self.unpack_userparams( - req_param_names=req_params, opt_param_names=opt_param) - - if "AccessPoint" in self.user_params: - self.legacy_configure_ap_and_start(wpa_network=True, wep_network=True) - - asserts.assert_true( - len(self.reference_networks) > 0, - "Need at least one reference network with psk.") - self.wpapsk_2g = self.reference_networks[0]["2g"] - self.wpapsk_5g = self.reference_networks[0]["5g"] - self.open_network_2g = self.open_network[0]["2g"] - self.open_network_5g = self.open_network[0]["5g"] - - def setup_test(self): - for ad in self.android_devices: - ad.droid.wakeLockAcquireBright() - ad.droid.wakeUpNow() - wutils.wifi_toggle_state(self.dut, True) - - def teardown_test(self): - for ad in self.android_devices: - ad.droid.wakeLockRelease() - ad.droid.goToSleepNow() - self.turn_location_off_and_scan_toggle_off() - wutils.reset_wifi(self.dut) - if self.dut_client: - wutils.reset_wifi(self.dut_client) - - def on_fail(self, test_name, begin_time): - self.dut.take_bug_report(test_name, begin_time) - self.dut.cat_adb_log(test_name, begin_time) - - def teardown_class(self): - if "AccessPoint" in self.user_params: - del self.user_params["reference_networks"] - del self.user_params["open_network"] - - """Helper Functions""" - - def connect_to_wifi_network(self, params): - """Connection logic for open and psk wifi networks. - - Args: - params: A tuple of network info and AndroidDevice object. - """ - network, ad = params - droid = ad.droid - ed = ad.ed - SSID = network[WifiEnums.SSID_KEY] - wutils.start_wifi_connection_scan_and_ensure_network_found( - ad, SSID); - wutils.wifi_connect(ad, network, num_of_tries=3) - - def get_connection_data(self, dut, network): - """Get network id and ssid info from connection data. - - Args: - dut: The Android device object under test. - network: dict representing the network to connect to. - - Returns: - A convenience dict with the connected network's ID and SSID. - - """ - params = (network, dut) - self.connect_to_wifi_network(params) - connect_data = dut.droid.wifiGetConnectionInfo() - ssid_id_dict = dict() - ssid_id_dict[WifiEnums.NETID_KEY] = connect_data[WifiEnums.NETID_KEY] - ssid_id_dict[WifiEnums.SSID_KEY] = connect_data[WifiEnums.SSID_KEY] - return ssid_id_dict - - def connect_multiple_networks(self, dut): - """Connect to one 2.4GHz and one 5Ghz network. - - Args: - dut: The Android device object under test. - - Returns: - A list with the connection details for the 2GHz and 5GHz networks. - - """ - network_list = list() - connect_2g_data = self.get_connection_data(dut, self.wpapsk_2g) - network_list.append(connect_2g_data) - connect_5g_data = self.get_connection_data(dut, self.wpapsk_5g) - network_list.append(connect_5g_data) - return network_list - - def get_enabled_network(self, network1, network2): - """Check network status and return currently unconnected network. - - Args: - network1: dict representing a network. - network2: dict representing a network. - - Return: - Network dict of the unconnected network. - - """ - wifi_info = self.dut.droid.wifiGetConnectionInfo() - enabled = network1 - if wifi_info[WifiEnums.SSID_KEY] == network1[WifiEnums.SSID_KEY]: - enabled = network2 - return enabled - - def check_configstore_networks(self, networks): - """Verify that all previously configured networks are presistent after - reboot. - - Args: - networks: List of network dicts. - - Return: - None. Raises TestFailure. - - """ - network_info = self.dut.droid.wifiGetConfiguredNetworks() - if len(network_info) != len(networks): - msg = ( - "Length of configured networks before and after reboot don't" - " match. \nBefore reboot = %s \n After reboot = %s" % - (networks, network_info)) - raise signals.TestFailure(msg) - current_count = 0 - # For each network, check if it exists in configured list after reboot - for network in networks: - exists = wutils.match_networks({ - WifiEnums.SSID_KEY: network[WifiEnums.SSID_KEY] - }, network_info) - if not len(exists): - raise signals.TestFailure("%s network is not present in the" - " configured list after reboot" % - network[WifiEnums.SSID_KEY]) - # Get the new network id for each network after reboot. - network[WifiEnums.NETID_KEY] = exists[0]['networkId'] - if exists[0]['status'] == 'CURRENT': - current_count += 1 - # At any given point, there can only be one currently active - # network, defined with 'status':'CURRENT' - if current_count > 1: - raise signals.TestFailure("More than one network showing" - "as 'CURRENT' after reboot") - - def connect_to_wifi_network_with_id(self, network_id, network_ssid): - """Connect to the given network using network id and verify SSID. - - Args: - network_id: int Network Id of the network. - network_ssid: string SSID of the network. - - Returns: True if connect using network id was successful; - False otherwise. - - """ - wutils.start_wifi_connection_scan_and_ensure_network_found( - self.dut, network_ssid); - wutils.wifi_connect_by_id(self.dut, network_id) - connect_data = self.dut.droid.wifiGetConnectionInfo() - connect_ssid = connect_data[WifiEnums.SSID_KEY] - self.log.debug("Expected SSID = %s Connected SSID = %s" % - (network_ssid, connect_ssid)) - if connect_ssid != network_ssid: - return False - return True - - def run_iperf_client(self, params): - """Run iperf traffic after connection. - - Args: - params: A tuple of network info and AndroidDevice object. - """ - if "iperf_server_address" in self.user_params: - wait_time = 5 - network, ad = params - SSID = network[WifiEnums.SSID_KEY] - self.log.info("Starting iperf traffic through {}".format(SSID)) - time.sleep(wait_time) - port_arg = "-p {}".format(self.iperf_server_port) - success, data = ad.run_iperf_client(self.iperf_server_address, - port_arg) - self.log.debug(pprint.pformat(data)) - asserts.assert_true(success, "Error occurred in iPerf traffic.") - - def connect_to_wifi_network_toggle_wifi_and_run_iperf(self, params): - """ Connect to the provided network and then toggle wifi mode and wait - for reconnection to the provided network. - - Logic steps are - 1. Connect to the network. - 2. Turn wifi off. - 3. Turn wifi on. - 4. Wait for connection to the network. - 5. Run iperf traffic. - - Args: - params: A tuple of network info and AndroidDevice object. - """ - network, ad = params - self.connect_to_wifi_network(params) - wutils.toggle_wifi_and_wait_for_reconnection( - ad, network, num_of_tries=5) - self.run_iperf_client(params) - - def run_iperf(self, iperf_args): - if "iperf_server_address" not in self.user_params: - self.log.error(("Missing iperf_server_address. " - "Provide one in config.")) - else: - iperf_addr = self.user_params["iperf_server_address"] - self.log.info("Running iperf client.") - result, data = self.dut.run_iperf_client(iperf_addr, iperf_args) - self.log.debug(data) - - def run_iperf_rx_tx(self, time, omit=10): - args = "-p {} -t {} -O 10".format(self.iperf_server_port, time, omit) - self.log.info("Running iperf client {}".format(args)) - self.run_iperf(args) - args = "-p {} -t {} -O 10 -R".format(self.iperf_server_port, time, - omit) - self.log.info("Running iperf client {}".format(args)) - self.run_iperf(args) - - def get_energy_info(self): - """ Steps: - 1. Check that the WiFi energy info reporting support on this device - is as expected (support or not). - 2. If the device does not support energy info reporting as - expected, skip the test. - 3. Call API to get WiFi energy info. - 4. Verify the values of "ControllerEnergyUsed" and - "ControllerIdleTimeMillis" in energy info don't decrease. - 5. Repeat from Step 3 for 10 times. - """ - # Check if dut supports energy info reporting. - actual_support = self.dut.droid.wifiIsEnhancedPowerReportingSupported() - model = self.dut.model - if not actual_support: - asserts.skip( - ("Device %s does not support energy info reporting as " - "expected.") % model) - # Verify reported values don't decrease. - self.log.info(("Device %s supports energy info reporting, verify that " - "the reported values don't decrease.") % model) - energy = 0 - idle_time = 0 - for i in range(10): - info = self.dut.droid.wifiGetControllerActivityEnergyInfo() - self.log.debug("Iteration %d, got energy info: %s" % (i, info)) - new_energy = info["ControllerEnergyUsed"] - new_idle_time = info["ControllerIdleTimeMillis"] - asserts.assert_true(new_energy >= energy, - "Energy value decreased: previous %d, now %d" % - (energy, new_energy)) - energy = new_energy - asserts.assert_true(new_idle_time >= idle_time, - "Idle time decreased: previous %d, now %d" % ( - idle_time, new_idle_time)) - idle_time = new_idle_time - wutils.start_wifi_connection_scan(self.dut) - - def turn_location_on_and_scan_toggle_on(self): - """ Turns on wifi location scans. - """ - acts.utils.set_location_service(self.dut, True) - self.dut.droid.wifiScannerToggleAlwaysAvailable(True) - msg = "Failed to turn on location service's scan." - asserts.assert_true(self.dut.droid.wifiScannerIsAlwaysAvailable(), msg) - - def turn_location_off_and_scan_toggle_off(self): - """ Turns off wifi location scans. - """ - acts.utils.set_location_service(self.dut, False) - self.dut.droid.wifiScannerToggleAlwaysAvailable(False) - msg = "Failed to turn off location service's scan." - asserts.assert_true(not self.dut.droid.wifiScannerIsAlwaysAvailable(), msg) - - def turn_location_on_and_scan_toggle_off(self): - """ Turns off wifi location scans, but keeps location on. - """ - acts.utils.set_location_service(self.dut, True) - self.dut.droid.wifiScannerToggleAlwaysAvailable(False) - msg = "Failed to turn off location service's scan." - asserts.assert_true(not self.dut.droid.wifiScannerIsAlwaysAvailable(), msg) - - def helper_reconnect_toggle_wifi(self): - """Connect to multiple networks, turn off/on wifi, then reconnect to - a previously connected network. - - Steps: - 1. Connect to a 2GHz network. - 2. Connect to a 5GHz network. - 3. Turn WiFi OFF/ON. - 4. Reconnect to the non-current network. - - """ - connect_2g_data = self.get_connection_data(self.dut, self.wpapsk_2g) - connect_5g_data = self.get_connection_data(self.dut, self.wpapsk_5g) - wutils.toggle_wifi_off_and_on(self.dut) - reconnect_to = self.get_enabled_network(connect_2g_data, - connect_5g_data) - reconnect = self.connect_to_wifi_network_with_id( - reconnect_to[WifiEnums.NETID_KEY], - reconnect_to[WifiEnums.SSID_KEY]) - if not reconnect: - raise signals.TestFailure("Device did not connect to the correct" - " network after toggling WiFi.") - - def helper_reconnect_toggle_airplane(self): - """Connect to multiple networks, turn on/off Airplane moce, then - reconnect a previously connected network. - - Steps: - 1. Connect to a 2GHz network. - 2. Connect to a 5GHz network. - 3. Turn ON/OFF Airplane mode. - 4. Reconnect to the non-current network. - - """ - connect_2g_data = self.get_connection_data(self.dut, self.wpapsk_2g) - connect_5g_data = self.get_connection_data(self.dut, self.wpapsk_5g) - wutils.toggle_airplane_mode_on_and_off(self.dut) - reconnect_to = self.get_enabled_network(connect_2g_data, - connect_5g_data) - reconnect = self.connect_to_wifi_network_with_id( - reconnect_to[WifiEnums.NETID_KEY], - reconnect_to[WifiEnums.SSID_KEY]) - if not reconnect: - raise signals.TestFailure("Device did not connect to the correct" - " network after toggling Airplane mode.") - - def helper_reboot_configstore_reconnect(self): - """Connect to multiple networks, reboot then reconnect to previously - connected network. - - Steps: - 1. Connect to a 2GHz network. - 2. Connect to a 5GHz network. - 3. Reboot device. - 4. Verify all networks are persistent after reboot. - 5. Reconnect to the non-current network. - - """ - network_list = self.connect_multiple_networks(self.dut) - self.dut.reboot() - time.sleep(DEFAULT_TIMEOUT) - self.check_configstore_networks(network_list) - - reconnect_to = self.get_enabled_network(network_list[BAND_2GHZ], - network_list[BAND_5GHZ]) - - reconnect = self.connect_to_wifi_network_with_id( - reconnect_to[WifiEnums.NETID_KEY], - reconnect_to[WifiEnums.SSID_KEY]) - if not reconnect: - raise signals.TestFailure( - "Device failed to reconnect to the correct" - " network after reboot.") - - def helper_toggle_wifi_reboot_configstore_reconnect(self): - """Connect to multiple networks, disable WiFi, reboot, then - reconnect to previously connected network. - - Steps: - 1. Connect to a 2GHz network. - 2. Connect to a 5GHz network. - 3. Turn WiFi OFF. - 4. Reboot device. - 5. Turn WiFi ON. - 4. Verify all networks are persistent after reboot. - 5. Reconnect to the non-current network. - - """ - network_list = self.connect_multiple_networks(self.dut) - self.log.debug("Toggling wifi OFF") - wutils.wifi_toggle_state(self.dut, False) - time.sleep(DEFAULT_TIMEOUT) - self.dut.reboot() - time.sleep(DEFAULT_TIMEOUT) - self.log.debug("Toggling wifi ON") - wutils.wifi_toggle_state(self.dut, True) - time.sleep(DEFAULT_TIMEOUT) - self.check_configstore_networks(network_list) - reconnect_to = self.get_enabled_network(network_list[BAND_2GHZ], - network_list[BAND_5GHZ]) - reconnect = self.connect_to_wifi_network_with_id( - reconnect_to[WifiEnums.NETID_KEY], - reconnect_to[WifiEnums.SSID_KEY]) - if not reconnect: - msg = ("Device failed to reconnect to the correct network after" - " toggling WiFi and rebooting.") - raise signals.TestFailure(msg) - - def helper_toggle_airplane_reboot_configstore_reconnect(self): - """Connect to multiple networks, enable Airplane mode, reboot, then - reconnect to previously connected network. - - Steps: - 1. Connect to a 2GHz network. - 2. Connect to a 5GHz network. - 3. Toggle Airplane mode ON. - 4. Reboot device. - 5. Toggle Airplane mode OFF. - 4. Verify all networks are persistent after reboot. - 5. Reconnect to the non-current network. - - """ - network_list = self.connect_multiple_networks(self.dut) - self.log.debug("Toggling Airplane mode ON") - asserts.assert_true( - acts.utils.force_airplane_mode(self.dut, True), - "Can not turn on airplane mode on: %s" % self.dut.serial) - time.sleep(DEFAULT_TIMEOUT) - self.dut.reboot() - time.sleep(DEFAULT_TIMEOUT) - self.log.debug("Toggling Airplane mode OFF") - asserts.assert_true( - acts.utils.force_airplane_mode(self.dut, False), - "Can not turn on airplane mode on: %s" % self.dut.serial) - time.sleep(DEFAULT_TIMEOUT) - self.check_configstore_networks(network_list) - reconnect_to = self.get_enabled_network(network_list[BAND_2GHZ], - network_list[BAND_5GHZ]) - reconnect = self.connect_to_wifi_network_with_id( - reconnect_to[WifiEnums.NETID_KEY], - reconnect_to[WifiEnums.SSID_KEY]) - if not reconnect: - msg = ("Device failed to reconnect to the correct network after" - " toggling Airplane mode and rebooting.") - raise signals.TestFailure(msg) - - def verify_traffic_between_devices(self,dest_device,src_device,num_of_tries=2): - """Test the clients and DUT can ping each other. - - Args: - num_of_tries: the retry times of ping test. - dest_device:Test device. - src_device:Second DUT access same AP - """ - dest_device = dest_device.droid.connectivityGetIPv4Addresses('wlan0')[0] - for _ in range(num_of_tries): - if acts.utils.adb_shell_ping(src_device, count=10, dest_ip=dest_device, timeout=20): - break - else: - asserts.fail("Ping to %s from %s failed" % (src_device.serial, dest_device)) - - """Tests""" - - @test_tracker_info(uuid="525fc5e3-afba-4bfd-9a02-5834119e3c66") - def test_toggle_wifi_state_and_get_startupTime(self): - """Test toggling wifi""" - self.log.debug("Going from on to off.") - wutils.wifi_toggle_state(self.dut, False) - self.log.debug("Going from off to on.") - startTime = time.time() - wutils.wifi_toggle_state(self.dut, True) - startup_time = time.time() - startTime - self.log.debug("WiFi was enabled on the device in %s s." % startup_time) - - @test_tracker_info(uuid="e9d11563-2bbe-4c96-87eb-ec919b51435b") - def test_toggle_with_screen(self): - """Test toggling wifi with screen on/off""" - wait_time = 5 - self.log.debug("Screen from off to on.") - self.dut.droid.wakeLockAcquireBright() - self.dut.droid.wakeUpNow() - time.sleep(wait_time) - self.log.debug("Going from on to off.") - try: - wutils.wifi_toggle_state(self.dut, False) - time.sleep(wait_time) - self.log.debug("Going from off to on.") - wutils.wifi_toggle_state(self.dut, True) - finally: - self.dut.droid.wakeLockRelease() - time.sleep(wait_time) - self.dut.droid.goToSleepNow() - - @test_tracker_info(uuid="71556e06-7fb1-4e2b-9338-b01f1f8e286e") - def test_scan(self): - """Test wifi connection scan can start and find expected networks.""" - ssid = self.open_network_2g[WifiEnums.SSID_KEY] - wutils.start_wifi_connection_scan_and_ensure_network_found( - self.dut, ssid) - ssid = self.open_network_5g[WifiEnums.SSID_KEY] - wutils.start_wifi_connection_scan_and_ensure_network_found( - self.dut, ssid) - - @test_tracker_info(uuid="3ea09efb-6921-429e-afb1-705ef5a09afa") - def test_scan_with_wifi_off_and_location_scan_on(self): - """Put wifi in scan only mode""" - self.turn_location_on_and_scan_toggle_on() - wutils.wifi_toggle_state(self.dut, False) - - """Test wifi connection scan can start and find expected networks.""" - ssid = self.open_network_2g[WifiEnums.SSID_KEY] - wutils.start_wifi_connection_scan_and_ensure_network_found( - self.dut, ssid) - ssid = self.open_network_5g[WifiEnums.SSID_KEY] - wutils.start_wifi_connection_scan_and_ensure_network_found( - self.dut, ssid) - - @test_tracker_info(uuid="770caebe-bcb1-43ac-95b6-5dd52dd90e80") - def test_scan_with_wifi_off_and_location_scan_off(self): - """Turn off wifi and location scan""" - self.turn_location_on_and_scan_toggle_off() - wutils.wifi_toggle_state(self.dut, False) - - """Test wifi connection scan should fail.""" - self.dut.droid.wifiStartScan() - try: - self.dut.ed.pop_event("WifiManagerScanResultsAvailable", 60) - except queue.Empty: - self.log.debug("Wifi scan results not received.") - else: - asserts.fail("Wi-Fi scan results received") - - @test_tracker_info(uuid="a4ad9930-a8fa-4868-81ed-a79c7483e502") - def test_add_network(self): - """Test wifi connection scan.""" - ssid = self.open_network_2g[WifiEnums.SSID_KEY] - nId = self.dut.droid.wifiAddNetwork(self.open_network_2g) - asserts.assert_true(nId > -1, "Failed to add network.") - configured_networks = self.dut.droid.wifiGetConfiguredNetworks() - self.log.debug( - ("Configured networks after adding: %s" % configured_networks)) - wutils.assert_network_in_list({ - WifiEnums.SSID_KEY: ssid - }, configured_networks) - - @test_tracker_info(uuid="aca85551-10ba-4007-90d9-08bcdeb16a60") - def test_forget_network(self): - ssid = self.open_network_2g[WifiEnums.SSID_KEY] - nId = self.dut.droid.wifiAddNetwork(self.open_network_2g) - asserts.assert_true(nId > -1, "Failed to add network.") - configured_networks = self.dut.droid.wifiGetConfiguredNetworks() - self.log.debug( - ("Configured networks after adding: %s" % configured_networks)) - wutils.assert_network_in_list({ - WifiEnums.SSID_KEY: ssid - }, configured_networks) - wutils.wifi_forget_network(self.dut, ssid) - configured_networks = self.dut.droid.wifiGetConfiguredNetworks() - for nw in configured_networks: - asserts.assert_true( - nw[WifiEnums.BSSID_KEY] != ssid, - "Found forgotten network %s in configured networks." % ssid) - - @test_tracker_info(uuid="b306d65c-6df3-4eb5-a178-6278bdc76c3e") - def test_reconnect_to_connected_network(self): - """Connect to a network and immediately issue reconnect. - - Steps: - 1. Connect to a 2GHz network. - 2. Reconnect to the network using its network id. - 3. Connect to a 5GHz network. - 4. Reconnect to the network using its network id. - - """ - connect_2g_data = self.get_connection_data(self.dut, self.wpapsk_2g) - reconnect_2g = self.connect_to_wifi_network_with_id( - connect_2g_data[WifiEnums.NETID_KEY], - connect_2g_data[WifiEnums.SSID_KEY]) - if not reconnect_2g: - raise signals.TestFailure("Device did not connect to the correct" - " 2GHz network.") - connect_5g_data = self.get_connection_data(self.dut, self.wpapsk_5g) - reconnect_5g = self.connect_to_wifi_network_with_id( - connect_5g_data[WifiEnums.NETID_KEY], - connect_5g_data[WifiEnums.SSID_KEY]) - if not reconnect_5g: - raise signals.TestFailure("Device did not connect to the correct" - " 5GHz network.") - - @test_tracker_info(uuid="3cff17f6-b684-4a95-a438-8272c2ad441d") - def test_reconnect_to_previously_connected(self): - """Connect to multiple networks and reconnect to the previous network. - - Steps: - 1. Connect to a 2GHz network. - 2. Connect to a 5GHz network. - 3. Reconnect to the 2GHz network using its network id. - 4. Reconnect to the 5GHz network using its network id. - - """ - connect_2g_data = self.get_connection_data(self.dut, self.wpapsk_2g) - connect_5g_data = self.get_connection_data(self.dut, self.wpapsk_5g) - reconnect_2g = self.connect_to_wifi_network_with_id( - connect_2g_data[WifiEnums.NETID_KEY], - connect_2g_data[WifiEnums.SSID_KEY]) - if not reconnect_2g: - raise signals.TestFailure("Device did not connect to the correct" - " 2GHz network.") - reconnect_5g = self.connect_to_wifi_network_with_id( - connect_5g_data[WifiEnums.NETID_KEY], - connect_5g_data[WifiEnums.SSID_KEY]) - if not reconnect_5g: - raise signals.TestFailure("Device did not connect to the correct" - " 5GHz network.") - - @test_tracker_info(uuid="334175c3-d26a-4c87-a8ab-8eb220b2d80f") - def test_reconnect_toggle_wifi(self): - """Connect to multiple networks, turn off/on wifi, then reconnect to - a previously connected network. - - Steps: - 1. Connect to a 2GHz network. - 2. Connect to a 5GHz network. - 3. Turn WiFi OFF/ON. - 4. Reconnect to the non-current network. - - """ - self.helper_reconnect_toggle_wifi() - - @test_tracker_info(uuid="bd2cec9e-7f17-44ef-8a0c-4da92a9b55ae") - def test_reconnect_toggle_wifi_with_location_scan_on(self): - """Connect to multiple networks, turn off/on wifi, then reconnect to - a previously connected network. - - Steps: - 1. Turn on location scans. - 2. Connect to a 2GHz network. - 3. Connect to a 5GHz network. - 4. Turn WiFi OFF/ON. - 5. Reconnect to the non-current network. - - """ - self.turn_location_on_and_scan_toggle_on() - self.helper_reconnect_toggle_wifi() - - @test_tracker_info(uuid="8e6e6c21-fefb-4fe8-9fb1-f09b1182b76d") - def test_reconnect_toggle_airplane(self): - """Connect to multiple networks, turn on/off Airplane moce, then - reconnect a previously connected network. - - Steps: - 1. Connect to a 2GHz network. - 2. Connect to a 5GHz network. - 3. Turn ON/OFF Airplane mode. - 4. Reconnect to the non-current network. - - """ - self.helper_reconnect_toggle_airplane() - - @test_tracker_info(uuid="28562f13-8a0a-492e-932c-e587560db5f2") - def test_reconnect_toggle_airplane_with_location_scan_on(self): - """Connect to multiple networks, turn on/off Airplane moce, then - reconnect a previously connected network. - - Steps: - 1. Turn on location scans. - 2. Connect to a 2GHz network. - 3. Connect to a 5GHz network. - 4. Turn ON/OFF Airplane mode. - 5. Reconnect to the non-current network. - - """ - self.turn_location_on_and_scan_toggle_on() - self.helper_reconnect_toggle_airplane() - - @test_tracker_info(uuid="3d041c12-05e2-46a7-ab9b-e3f60cc735db") - def test_reboot_configstore_reconnect(self): - """Connect to multiple networks, reboot then reconnect to previously - connected network. - - Steps: - 1. Connect to a 2GHz network. - 2. Connect to a 5GHz network. - 3. Reboot device. - 4. Verify all networks are persistent after reboot. - 5. Reconnect to the non-current network. - - """ - self.helper_reboot_configstore_reconnect() - - @test_tracker_info(uuid="a70d5853-67b5-4d48-bdf7-08ee51fafd21") - def test_reboot_configstore_reconnect_with_location_scan_on(self): - """Connect to multiple networks, reboot then reconnect to previously - connected network. - - Steps: - 1. Turn on location scans. - 2. Connect to a 2GHz network. - 3. Connect to a 5GHz network. - 4. Reboot device. - 5. Verify all networks are persistent after reboot. - 6. Reconnect to the non-current network. - - """ - self.turn_location_on_and_scan_toggle_on() - self.helper_reboot_configstore_reconnect() - - @test_tracker_info(uuid="26d94dfa-1349-4c8b-aea0-475eb73bb521") - def test_toggle_wifi_reboot_configstore_reconnect(self): - """Connect to multiple networks, disable WiFi, reboot, then - reconnect to previously connected network. - - Steps: - 1. Connect to a 2GHz network. - 2. Connect to a 5GHz network. - 3. Turn WiFi OFF. - 4. Reboot device. - 5. Turn WiFi ON. - 4. Verify all networks are persistent after reboot. - 5. Reconnect to the non-current network. - - """ - self.helper_toggle_wifi_reboot_configstore_reconnect() - - @test_tracker_info(uuid="7c004a3b-c1c6-4371-9124-0f34650be915") - def test_toggle_wifi_reboot_configstore_reconnect_with_location_scan_on(self): - """Connect to multiple networks, disable WiFi, reboot, then - reconnect to previously connected network. - - Steps: - 1. Turn on location scans. - 2. Connect to a 2GHz network. - 3. Connect to a 5GHz network. - 4. Turn WiFi OFF. - 5. Reboot device. - 6. Turn WiFi ON. - 7. Verify all networks are persistent after reboot. - 8. Reconnect to the non-current network. - - """ - self.turn_location_on_and_scan_toggle_on() - self.helper_toggle_wifi_reboot_configstore_reconnect() - - @test_tracker_info(uuid="4fce017b-b443-40dc-a598-51d59d3bb38f") - def test_toggle_airplane_reboot_configstore_reconnect(self): - """Connect to multiple networks, enable Airplane mode, reboot, then - reconnect to previously connected network. - - Steps: - 1. Connect to a 2GHz network. - 2. Connect to a 5GHz network. - 3. Toggle Airplane mode ON. - 4. Reboot device. - 5. Toggle Airplane mode OFF. - 4. Verify all networks are persistent after reboot. - 5. Reconnect to the non-current network. - - """ - self.helper_toggle_airplane_reboot_configstore_reconnect() - - @test_tracker_info(uuid="7f0810f9-2338-4158-95f5-057f5a1905b6") - def test_toggle_airplane_reboot_configstore_reconnect_with_location_scan_on(self): - """Connect to multiple networks, enable Airplane mode, reboot, then - reconnect to previously connected network. - - Steps: - 1. Turn on location scans. - 2. Connect to a 2GHz network. - 3. Connect to a 5GHz network. - 4. Toggle Airplane mode ON. - 5. Reboot device. - 6. Toggle Airplane mode OFF. - 7. Verify all networks are persistent after reboot. - 8. Reconnect to the non-current network. - - """ - self.turn_location_on_and_scan_toggle_on() - self.helper_toggle_airplane_reboot_configstore_reconnect() - - @test_tracker_info(uuid="81eb7527-4c92-4422-897a-6b5f6445e84a") - def test_config_store_with_wpapsk_2g(self): - self.connect_to_wifi_network_toggle_wifi_and_run_iperf( - (self.wpapsk_2g, self.dut)) - - @test_tracker_info(uuid="8457903d-cb7e-4c89-bcea-7f59585ea6e0") - def test_config_store_with_wpapsk_5g(self): - self.connect_to_wifi_network_toggle_wifi_and_run_iperf( - (self.wpapsk_5g, self.dut)) - - @test_tracker_info(uuid="b9fbc13a-47b4-4f64-bd2c-e5a3cb24ab2f") - def test_tdls_supported(self): - model = self.dut.model - self.log.debug("Model is %s" % model) - if not model.startswith("volantis"): - asserts.assert_true(self.dut.droid.wifiIsTdlsSupported(), ( - "TDLS should be supported on %s, but device is " - "reporting not supported.") % model) - else: - asserts.assert_false(self.dut.droid.wifiIsTdlsSupported(), ( - "TDLS should not be supported on %s, but device " - "is reporting supported.") % model) - - @test_tracker_info(uuid="50637d40-ea59-4f4b-9fc1-e6641d64074c") - def test_energy_info(self): - """Verify the WiFi energy info reporting feature """ - self.get_energy_info() - - @test_tracker_info(uuid="1f1cf549-53eb-4f36-9f33-ce06c9158efc") - def test_energy_info_connected(self): - """Verify the WiFi energy info reporting feature when connected. - - Connect to a wifi network, then the same as test_energy_info. - """ - wutils.wifi_connect(self.dut, self.open_network_2g) - self.get_energy_info() - - @test_tracker_info(uuid="2622c253-defc-4a35-93a6-ca9d29a8238c") - def test_connect_to_wep_2g(self): - """Verify DUT can connect to 2GHz WEP network - - Steps: - 1. Ensure the 2GHz WEP network is visible in scan result. - 2. Connect to the network and validate internet connection. - """ - wutils.connect_to_wifi_network(self.dut, self.wep_networks[0]["2g"]) - - @test_tracker_info(uuid="1f2d17a2-e92d-43af-966b-3421c0db8620") - def test_connect_to_wep_5g(self): - """Verify DUT can connect to 5GHz WEP network - - Steps: - 1. Ensure the 5GHz WEP network is visible in scan result. - 2. Connect to the network and validate internet connection. - """ - wutils.connect_to_wifi_network(self.dut, self.wep_networks[0]["5g"]) - - @test_tracker_info(uuid="4a957952-289d-4657-9882-e1475274a7ff") - def test_connect_to_wpa_2g(self): - """Verify DUT can connect to 2GHz WPA-PSK network - - Steps: - 1. Ensure the 2GHz WPA-PSK network is visible in scan result. - 2. Connect to the network and validate internet connection. - """ - wutils.connect_to_wifi_network(self.dut, self.wpa_networks[0]["2g"]) - - @test_tracker_info(uuid="612c3c31-a4c5-4014-9a2d-3f4bcc20c0d7") - def test_connect_to_wpa_5g(self): - """Verify DUT can connect to 5GHz WPA-PSK network - - Steps: - 1. Ensure the 5GHz WPA-PSK network is visible in scan result. - 2. Connect to the network and validate internet connection. - """ - wutils.connect_to_wifi_network(self.dut, self.wpa_networks[0]["5g"]) - - @test_tracker_info(uuid="2a617fb4-1d8e-44e9-a500-a5456e1df83f") - def test_connect_to_2g_can_be_pinged(self): - """Verify DUT can be pinged by another device when it connects to 2GHz AP - - Steps: - 1. Ensure the 2GHz WPA-PSK network is visible in scan result. - 2. Connect to the network and validate internet connection. - 3. Check DUT can be pinged by another device - """ - wutils.connect_to_wifi_network(self.dut, self.wpa_networks[0]["2g"]) - wutils.connect_to_wifi_network(self.dut_client, self.wpa_networks[0]["2g"]) - self.verify_traffic_between_devices(self.dut,self.dut_client) - - @test_tracker_info(uuid="94bdd657-649b-4a2c-89c3-3ec6ba18e08e") - def test_connect_to_5g_can_be_pinged(self): - """Verify DUT can be pinged by another device when it connects to 5GHz AP - - Steps: - 1. Ensure the 5GHz WPA-PSK network is visible in scan result. - 2. Connect to the network and validate internet connection. - 3. Check DUT can be pinged by another device - """ - wutils.connect_to_wifi_network(self.dut, self.wpa_networks[0]["5g"]) - wutils.connect_to_wifi_network(self.dut_client, self.wpa_networks[0]["5g"]) - self.verify_traffic_between_devices(self.dut,self.dut_client) - - @test_tracker_info(uuid="d87359aa-c4da-4554-b5de-8e3fa852a6b0") - def test_sta_turn_off_screen_can_be_pinged(self): - """Verify DUT can be pinged by another device after idle for a while - - Steps: - 1. Ensure the 2GHz WPA-PSK network is visible in scan result. - 2. DUT and DUT_Client connect to the network and validate internet connection. - 3. Let DUT sleep for 5 minutes - 4. Check DUT can be pinged by DUT_Client - """ - # DUT connect to AP - wutils.connect_to_wifi_network(self.dut, self.wpa_networks[0]["2g"]) - wutils.connect_to_wifi_network(self.dut_client, self.wpa_networks[0]["2g"]) - # Check DUT and DUT_Client can ping each other successfully - self.verify_traffic_between_devices(self.dut,self.dut_client) - self.verify_traffic_between_devices(self.dut_client,self.dut) - # DUT turn off screen and go sleep for 5 mins - self.dut.droid.wakeLockRelease() - self.dut.droid.goToSleepNow() - # TODO(hsiuchangchen): find a way to check system already suspended - # instead of waiting 5 mins - self.log.info("Sleep for 5 minutes") - time.sleep(300) - # Verify DUT_Client can ping DUT when DUT sleeps - self.verify_traffic_between_devices(self.dut,self.dut_client) - 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/WifiNativeTest.py b/acts/tests/google/wifi/WifiNativeTest.py deleted file mode 100644 index 56e21955a7..0000000000 --- a/acts/tests/google/wifi/WifiNativeTest.py +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (C) 2016 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may not -# use this file except in compliance with the License. You may obtain a copy of -# the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations under -# the License. - -from acts import base_test -from acts.controllers import native_android_device - -class WifiNativeTest(base_test.BaseTestClass): - - def setup_class(self): - self.native_devices = self.register_controller(native_android_device) - self.dut = self.native_devices[0] - - def setup_test(self): -# TODO: uncomment once wifi_toggle_state (or alternative) -# work with sl4n -# assert wutils.wifi_toggle_state(self.device, True) - return self.dut.droid.WifiInit() - -# TODO: uncomment once wifi_toggle_state (or alternative) -# work with sl4n -# def teardown_test(self): -# assert wutils.wifi_toggle_state(self.device, False) - - def test_hal_get_features(self): - result = self.dut.droid.WifiGetSupportedFeatureSet() - self.log.info("Wi-Fi feature set: %d", result) diff --git a/acts/tests/google/wifi/WifiNetworkRequestTest.py b/acts/tests/google/wifi/WifiNetworkRequestTest.py deleted file mode 100644 index 7fed0ad1c7..0000000000 --- a/acts/tests/google/wifi/WifiNetworkRequestTest.py +++ /dev/null @@ -1,481 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2018 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import itertools -import pprint -import queue -import time - -import acts.base_test -import acts.signals as signals -import acts.test_utils.wifi.wifi_test_utils as wutils -import acts.utils - -from acts import asserts -from acts.controllers.android_device import SL4A_APK_NAME -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest -from acts.test_utils.wifi import wifi_constants - -WifiEnums = wutils.WifiEnums - -# Network request timeout to use. -NETWORK_REQUEST_TIMEOUT_MS = 60 * 1000 -# Timeout to wait for instant failure. -NETWORK_REQUEST_INSTANT_FAILURE_TIMEOUT_SEC = 5 - -class WifiNetworkRequestTest(WifiBaseTest): - """Tests for NetworkRequest with WifiNetworkSpecifier API surface. - - Test Bed Requirement: - * one Android device - * Several Wi-Fi networks visible to the device, including an open Wi-Fi - network. - """ - - def setup_class(self): - super().setup_class() - - self.dut = self.android_devices[0] - wutils.wifi_test_device_init(self.dut) - req_params = [] - opt_param = [ - "open_network", "reference_networks" - ] - self.unpack_userparams( - req_param_names=req_params, opt_param_names=opt_param) - - if "AccessPoint" in self.user_params: - self.legacy_configure_ap_and_start(wpa_network=True, - wep_network=True) - - asserts.assert_true( - len(self.reference_networks) > 0, - "Need at least one reference network with psk.") - self.wpa_psk_2g = self.reference_networks[0]["2g"] - self.wpa_psk_5g = self.reference_networks[0]["5g"] - self.open_2g = self.open_network[0]["2g"] - self.open_5g = self.open_network[0]["5g"] - - def setup_test(self): - self.dut.droid.wakeLockAcquireBright() - self.dut.droid.wakeUpNow() - self.remove_approvals() - self.clear_deleted_ephemeral_networks() - wutils.wifi_toggle_state(self.dut, True) - self.dut.ed.clear_all_events() - - def teardown_test(self): - self.dut.droid.wakeLockRelease() - self.dut.droid.goToSleepNow() - self.dut.droid.wifiReleaseNetworkAll() - self.dut.droid.wifiDisconnect() - wutils.reset_wifi(self.dut) - self.dut.ed.clear_all_events() - - def on_fail(self, test_name, begin_time): - self.dut.take_bug_report(test_name, begin_time) - self.dut.cat_adb_log(test_name, begin_time) - - def teardown_class(self): - if "AccessPoint" in self.user_params: - del self.user_params["reference_networks"] - del self.user_params["open_network"] - - """Helper Functions""" - def wait_for_network_lost(self): - """ - Wait for network lost callback from connectivity service (wifi - disconnect). - - Args: - ad: Android device object. - """ - try: - self.dut.droid.wifiStartTrackingStateChange() - event = self.dut.ed.pop_event( - wifi_constants.WIFI_NETWORK_CB_ON_LOST, 10) - self.dut.droid.wifiStopTrackingStateChange() - except queue.Empty: - raise signals.TestFailure( - "Device did not disconnect from the network") - - def remove_approvals(self): - self.dut.log.debug("Removing all approvals from sl4a app") - self.dut.adb.shell( - "cmd wifi network-requests-remove-user-approved-access-points" - + " " + SL4A_APK_NAME) - - def clear_deleted_ephemeral_networks(self): - self.dut.log.debug("Clearing deleted ephemeral networks") - self.dut.adb.shell( - "cmd wifi clear-deleted-ephemeral-networks") - - @test_tracker_info(uuid="d70c8380-61ba-48a3-b76c-a0b55ce4eabf") - def test_connect_to_wpa_psk_2g_with_ssid(self): - """ - Initiates a connection to network via network request with specific SSID - - Steps: - 1. Send a network specifier with the specific SSID/credentials of - WPA-PSK 2G network. - 2. Wait for platform to scan and find matching networks. - 3. Simulate user selecting the network. - 4. Ensure that the device connects to the network. - """ - wutils.wifi_connect_using_network_request(self.dut, self.wpa_psk_2g, - self.wpa_psk_2g) - - @test_tracker_info(uuid="44f2bf40-a282-4413-b8f2-3abb3caa49ee") - def test_connect_to_open_5g_with_ssid(self): - """ - Initiates a connection to network via network request with specific SSID - - Steps: - 1. Send a network specifier with the specific SSID of Open 5G network. - 2. Wait for platform to scan and find matching networks. - 3. Simulate user selecting the network. - 4. Ensure that the device connects to the network. - """ - wutils.wifi_connect_using_network_request(self.dut, self.open_5g, - self.open_5g) - - @test_tracker_info(uuid="09d1823e-4f85-42f8-8c20-de7637f6d4be") - def test_connect_to_wpa_psk_5g_with_ssid_pattern(self): - """ - Initiates a connection to network via network request with SSID pattern - - Steps: - 1. Send a network specifier with the SSID pattern/credentials of - WPA-PSK 5G network. - 2. Wait for platform to scan and find matching networks. - 3. Simulate user selecting the network. - 4. Ensure that the device connects to the network. - """ - network_specifier = self.wpa_psk_5g.copy(); - # Remove ssid & replace with ssid pattern. - network_ssid = network_specifier.pop(WifiEnums.SSID_KEY) - # Remove the last element of ssid & replace with .* to create a matching - # pattern. - network_specifier[WifiEnums.SSID_PATTERN_KEY] = network_ssid[:-1] + ".*" - wutils.wifi_connect_using_network_request(self.dut, self.wpa_psk_5g, - network_specifier) - - @test_tracker_info(uuid="52216329-06f1-45ef-8d5f-de8b02d9f975") - def test_connect_to_open_5g_after_connecting_to_wpa_psk_2g(self): - """ - Initiates a connection to network via network request with SSID pattern - - Steps: - 1. Send a network specifier with the specific SSID of Open 5G network. - 2. Wait for platform to scan and find matching networks. - 3. Simulate user selecting the network. - 4. Ensure that the device connects to the network. - 5. Release the network request. - 6. Send another network specifier with the specific SSID & credentials - of WPA-PSK 2G network. - 7. Ensure we disconnect from the previous network. - 8. Wait for platform to scan and find matching networks. - 9. Simulate user selecting the new network. - 10. Ensure that the device connects to the new network. - """ - # Complete flow for the first request. - wutils.wifi_connect_using_network_request(self.dut, self.wpa_psk_2g, - self.wpa_psk_2g) - # Release the request. - self.dut.droid.wifiReleaseNetwork(self.wpa_psk_2g) - # Ensure we disconnected from the previous network. - wutils.wait_for_disconnect(self.dut) - self.dut.log.info("Disconnected from network %s", self.wpa_psk_2g) - # Complete flow for the second request. - wutils.wifi_connect_using_network_request(self.dut, self.open_5g, - self.open_5g) - - @test_tracker_info(uuid="f28b5dc9-771f-42ef-8178-e55e9a16f5c7") - def test_connect_to_wpa_psk_5g_while_connecting_to_open_2g(self): - """ - Initiates a connection to network via network request with specific SSID - - Steps: - 1. Send a network specifier with the specific SSID & credentials of - WPA-PSK 5G network. - 2. Send another network specifier with the specific SSID of Open 2G - network. - 3. Ensure we disconnect from the previous network. - 4. Wait for platform to scan and find matching networks. - 5. Simulate user selecting the new network. - 6. Ensure that the device connects to the new network. - """ - # Make the first request. - self.dut.droid.wifiRequestNetworkWithSpecifier(self.open_2g) - self.dut.log.info("Sent network request with %s", self.open_2g) - # Complete flow for the second request. - wutils.wifi_connect_using_network_request(self.dut, self.wpa_psk_5g, - self.wpa_psk_5g) - - @test_tracker_info(uuid="2ab82a98-37da-4b27-abb6-578bedebccdc") - def test_connect_to_open_5g_while_connected_to_wpa_psk_2g(self): - """ - Initiates a connection to network via network request with specific SSID - - Steps: - 1. Send a network specifier with the specific SSID of Open 5G network. - 2. Wait for platform to scan and find matching networks. - 3. Simulate user selecting the network. - 4. Ensure that the device connects to the network. - 5. Send another network specifier with the specific SSID & credentials - of WPA-PSK 2G network. - 6. Ensure we disconnect from the previous network. - 7. Wait for platform to scan and find matching networks. - 8. Simulate user selecting the new network. - 9. Ensure that the device connects to the new network. - """ - # Complete flow for the first request. - wutils.wifi_connect_using_network_request(self.dut, self.wpa_psk_2g, - self.wpa_psk_2g) - # Send the second request. - self.dut.droid.wifiRequestNetworkWithSpecifier(self.open_5g) - self.dut.log.info("Sent network request with %s", self.open_5g) - # Ensure we do not disconnect from the previous network until the user - # approves the new request. - self.dut.ed.clear_all_events() - wutils.ensure_no_disconnect(self.dut) - - # Now complete the flow and ensure we connected to second request. - wutils.wait_for_wifi_connect_after_network_request(self.dut, - self.open_5g) - - @test_tracker_info(uuid="f0bb2213-b3d1-4fb8-bbdc-ad55c4fb05ed") - def test_connect_to_wpa_psk_2g_which_is_already_approved(self): - """ - Initiates a connection to network via network request with specific SSID - bypassing user approval. - - Steps: - 1. Send a network specifier with the specific SSID/credentials of - WPA-PSK 2G network. - 2. Wait for platform to scan and find matching networks. - 3. Simulate user selecting the network. - 4. Ensure that the device connects to the network. - 5. Ensure we disconnect from the previous network. - 6. Send another network specifier with the specific - SSID/BSSID/credentials of WPA-PSK 2G network. - 7. Ensure that the device bypasses user approval & connects to the - same network. - """ - # Complete flow for the first request. - wutils.wifi_connect_using_network_request(self.dut, self.wpa_psk_2g, - self.wpa_psk_2g) - # Release the request. - self.dut.droid.wifiReleaseNetwork(self.wpa_psk_2g) - # Ensure we disconnected from the network. - wutils.wait_for_disconnect(self.dut) - self.dut.log.info("Disconnected from network %s", self.wpa_psk_2g) - self.dut.ed.clear_all_events() - - # Find bssid for the WPA-PSK 2G network. - scan_results = self.dut.droid.wifiGetScanResults() - match_results = wutils.match_networks( - {WifiEnums.SSID_KEY: self.wpa_psk_2g[WifiEnums.SSID_KEY]}, - scan_results) - asserts.assert_equal(len(match_results), 1, - "Cannot find bssid for WPA-PSK 2G network") - bssid = match_results[0][WifiEnums.BSSID_KEY] - # Send the second request with bssid. - network_specifier_with_bssid = self.wpa_psk_2g.copy(); - network_specifier_with_bssid[WifiEnums.BSSID_KEY] = bssid - self.dut.droid.wifiRequestNetworkWithSpecifier( - network_specifier_with_bssid) - self.dut.log.info("Sent network request with %r", - network_specifier_with_bssid) - - # Ensure we connected to second request without user approval. - wutils.wait_for_connect(self.dut, self.wpa_psk_2g[WifiEnums.SSID_KEY]) - - @test_tracker_info(uuid="fcf84d94-5f6e-4bd6-9f76-40a0228d4ebe") - def test_connect_to_wpa_psk_2g_which_is_already_approved_but_then_forgot(self): - """ - Initiates a connection to network via network request with specific SSID - with user approval. - - Steps: - 1. Send a network specifier with the specific SSID/credentials of - WPA-PSK 2G network. - 2. Wait for platform to scan and find matching networks. - 3. Simulate user selecting the network. - 4. Ensure that the device connects to the network. - 4. Simulate user fogetting the network from the UI. - 6. Ensure we disconnect from the previous network. - 7. Send another network specifier with the specific - SSID/BSSID/credentials of WPA-PSK 2G network. - 8. Ensure that the device does not bypass user approval & connects to the - same network with user approval. (This should also clear the blacklist) - 9. Send the same network specifier with the specific - SSID/BSSID/credentials of WPA-PSK 2G network. - 10.Ensure that the device bypasses user approval now & connects to the - same network. - """ - # Complete flow for the first request. - wutils.wifi_connect_using_network_request(self.dut, self.wpa_psk_2g, - self.wpa_psk_2g) - - # Simulate user forgeting the ephemeral network. - self.dut.droid.wifiDisableEphemeralNetwork( - self.wpa_psk_2g[WifiEnums.SSID_KEY]) - # Ensure we disconnected from the network. - wutils.wait_for_disconnect(self.dut) - self.dut.log.info("Disconnected from network %s", self.wpa_psk_2g) - self.dut.ed.clear_all_events() - # Release the first request. - self.dut.droid.wifiReleaseNetwork(self.wpa_psk_2g) - - # Find bssid for the WPA-PSK 2G network. - scan_results = self.dut.droid.wifiGetScanResults() - match_results = wutils.match_networks( - {WifiEnums.SSID_KEY: self.wpa_psk_2g[WifiEnums.SSID_KEY]}, - scan_results) - asserts.assert_equal(len(match_results), 1, - "Cannot find bssid for WPA-PSK 2G network") - bssid = match_results[0][WifiEnums.BSSID_KEY] - # Send the second request with bssid. - network_specifier_with_bssid = self.wpa_psk_2g.copy(); - network_specifier_with_bssid[WifiEnums.BSSID_KEY] = bssid - self.dut.droid.wifiRequestNetworkWithSpecifier( - network_specifier_with_bssid) - self.dut.log.info("Sent network request with %r", - network_specifier_with_bssid) - - # Ensure that we did not connect bypassing user approval. - assert_msg = "Device should not connect without user approval" - asserts.assert_false( - wutils.wait_for_connect(self.dut, - self.wpa_psk_2g[WifiEnums.SSID_KEY], - assert_on_fail=False), - assert_msg) - - # Now complete the flow and ensure we connected to second request. - wutils.wait_for_wifi_connect_after_network_request(self.dut, - self.wpa_psk_2g) - - # Now make the same request again & ensure that we connect without user - # approval. - self.dut.droid.wifiRequestNetworkWithSpecifier( - network_specifier_with_bssid) - self.dut.log.info("Sent network request with %r", - network_specifier_with_bssid) - wutils.wait_for_connect(self.dut, self.wpa_psk_2g[WifiEnums.SSID_KEY]) - - @test_tracker_info(uuid="2f90a266-f04d-4932-bb5b-d075bedfd56d") - def test_match_failure_with_invalid_ssid_pattern(self): - """ - Initiates a connection to network via network request with SSID pattern - that does not match any networks. - - Steps: - 1. Send a network specifier with the non-matching SSID pattern. - 2. Ensure that the platform does not retrun any matching networks. - 3. Wait for the request to timeout. - """ - network = self.wpa_psk_5g - network_specifier = self.wpa_psk_5g.copy(); - # Remove ssid & replace with invalid ssid pattern. - network_ssid = network_specifier.pop(WifiEnums.SSID_KEY) - network_specifier[WifiEnums.SSID_PATTERN_KEY] = \ - network_ssid + "blah" + ".*" - - self.dut.droid.wifiStartTrackingStateChange() - expected_ssid = network[WifiEnums.SSID_KEY] - - self.dut.droid.wifiRequestNetworkWithSpecifierWithTimeout( - network_specifier, NETWORK_REQUEST_TIMEOUT_MS) - self.dut.log.info("Sent network request with invalid specifier %s", - network_specifier) - time.sleep(wifi_constants.NETWORK_REQUEST_CB_REGISTER_DELAY_SEC) - self.dut.droid.wifiRegisterNetworkRequestMatchCallback() - # Wait for the request to timeout. - timeout_secs = \ - NETWORK_REQUEST_TIMEOUT_MS / 1000 + NETWORK_REQUEST_INSTANT_FAILURE_TIMEOUT_SEC - try: - on_unavailable_event = self.dut.ed.pop_event( - wifi_constants.WIFI_NETWORK_CB_ON_UNAVAILABLE, timeout_secs) - asserts.assert_true(on_unavailable_event, "Network request did not timeout") - - except queue.Empty: - asserts.fail("No events returned") - finally: - self.dut.droid.wifiStopTrackingStateChange() - - @test_tracker_info(uuid="760c3768-697d-442b-8d61-cfe02f10ceff") - def test_connect_failure_user_rejected(self): - """ - Initiates a connection to network via network request with specific SSID - which the user rejected. - - Steps: - 1. Send a network specifier with the specific SSID/credentials of - WPA-PSK 5G network. - 2. Wait for platform to scan and find matching networks. - 3. Simulate user rejecting the network. - 4. Ensure that we get an instant onUnavailable callback. - 5. Simulate user fogetting the network from the UI. - """ - network = self.wpa_psk_5g - expected_ssid = network[WifiEnums.SSID_KEY] - - self.dut.droid.wifiStartTrackingStateChange() - - self.dut.droid.wifiRequestNetworkWithSpecifierWithTimeout( - network, NETWORK_REQUEST_TIMEOUT_MS) - self.dut.log.info("Sent network request with specifier %s", network) - time.sleep(wifi_constants.NETWORK_REQUEST_CB_REGISTER_DELAY_SEC) - self.dut.droid.wifiRegisterNetworkRequestMatchCallback() - - # Wait for the platform to scan and return a list of networks - # matching the request - try: - matched_network = None - for _ in [0, 3]: - on_match_event = self.dut.ed.pop_event( - wifi_constants.WIFI_NETWORK_REQUEST_MATCH_CB_ON_MATCH, 30) - asserts.assert_true(on_match_event, - "Network request on match not received.") - matched_scan_results = on_match_event["data"] - self.dut.log.debug("Network request on match results %s", - matched_scan_results) - matched_network = wutils.match_networks( - {WifiEnums.SSID_KEY: network[WifiEnums.SSID_KEY]}, - matched_scan_results) - if matched_network: - break; - asserts.assert_true( - matched_network, "Target network %s not found" % network) - - # Send user rejection. - self.dut.droid.wifiSendUserRejectionForNetworkRequestMatch() - self.dut.log.info("Sent user rejection for network request %s", - expected_ssid) - - # Wait for the platform to raise unavailable callback - # instantaneously. - on_unavailable_event = self.dut.ed.pop_event( - wifi_constants.WIFI_NETWORK_CB_ON_UNAVAILABLE, - NETWORK_REQUEST_INSTANT_FAILURE_TIMEOUT_SEC) - asserts.assert_true(on_unavailable_event, - "Network request on available not received.") - except queue.Empty: - asserts.fail("Expected events not returned") - finally: - self.dut.droid.wifiStopTrackingStateChange() diff --git a/acts/tests/google/wifi/WifiNetworkSelectorTest.py b/acts/tests/google/wifi/WifiNetworkSelectorTest.py deleted file mode 100644 index 5af4ad9584..0000000000 --- a/acts/tests/google/wifi/WifiNetworkSelectorTest.py +++ /dev/null @@ -1,423 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2016 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import logging -import time - -import acts.signals as signals - -from acts import asserts -from acts import base_test -from acts.controllers import android_device -from acts.controllers import attenuator -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi import wifi_test_utils as wutils -from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest - -WifiEnums = wutils.WifiEnums - -AP_1 = 0 -AP_2 = 1 -AP_1_2G_ATTENUATOR = 0 -AP_1_5G_ATTENUATOR = 1 -AP_2_2G_ATTENUATOR = 2 -AP_2_5G_ATTENUATOR = 3 -ATTENUATOR_INITIAL_SETTING = 60 -# WifiNetworkSelector imposes a 10 seconds gap between two selections -NETWORK_SELECTION_TIME_GAP = 12 - - -class WifiNetworkSelectorTest(WifiBaseTest): - """These tests verify the behavior of the Android Wi-Fi Network Selector - feature. - """ - - def setup_class(self): - super().setup_class() - - self.dut = self.android_devices[0] - wutils.wifi_test_device_init(self.dut) - req_params = [] - opt_param = ["open_network", "reference_networks"] - self.unpack_userparams( - req_param_names=req_params, opt_param_names=opt_param) - - if hasattr(self, 'access_points'): - self.legacy_configure_ap_and_start(ap_count=2) - - if hasattr(self, 'packet_capture'): - self.configure_packet_capture() - - def setup_test(self): - #reset and clear all saved networks on the DUT - wutils.reset_wifi(self.dut) - #move the APs out of range - for attenuator in self.attenuators: - attenuator.set_atten(ATTENUATOR_INITIAL_SETTING) - #turn on the screen - self.dut.droid.wakeLockAcquireBright() - self.dut.droid.wakeUpNow() - self.dut.ed.clear_all_events() - - if hasattr(self, 'packet_capture'): - self.pcap_procs = wutils.start_pcap( - self.packet_capture, 'dual', self.test_name) - - def teardown_test(self): - #turn off the screen - self.dut.droid.wakeLockRelease() - self.dut.droid.goToSleepNow() - - def on_pass(self, test_name, begin_time): - if hasattr(self, 'packet_capture'): - wutils.stop_pcap(self.packet_capture, self.pcap_procs, True) - - def on_fail(self, test_name, begin_time): - if hasattr(self, 'packet_capture'): - wutils.stop_pcap(self.packet_capture, self.pcap_procs, False) - self.dut.take_bug_report(test_name, begin_time) - self.dut.cat_adb_log(test_name, begin_time) - - def teardown_class(self): - if "AccessPoint" in self.user_params: - del self.user_params["reference_networks"] - del self.user_params["open_network"] - - """ Helper Functions """ - - def add_networks(self, ad, networks): - """Add Wi-Fi networks to an Android device and verify the networks were - added correctly. - - Args: - ad: the AndroidDevice object to add networks to. - networks: a list of dicts, each dict represents a Wi-Fi network. - """ - for network in networks: - ret = ad.droid.wifiAddNetwork(network) - asserts.assert_true(ret != -1, "Failed to add network %s" % - network) - ad.droid.wifiEnableNetwork(ret, 0) - configured_networks = ad.droid.wifiGetConfiguredNetworks() - logging.debug("Configured networks: %s", configured_networks) - - def connect_and_verify_connected_bssid(self, expected_bssid): - """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. - """ - #wait for the attenuator to stablize - time.sleep(10) - #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() - logging.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) - - """ Tests Begin """ - - @test_tracker_info(uuid="ffa5e278-db3f-4e17-af11-6c7a3e7c5cc2") - def test_network_selector_automatic_connection(self): - """ - 1. Add one saved network to DUT. - 2. Move the DUT in range. - 3. Verify the DUT is connected to the network. - """ - #add a saved network to DUT - networks = [self.reference_networks[AP_1]['5g']] - self.add_networks(self.dut, networks) - #move the DUT in range - self.attenuators[AP_1_5G_ATTENUATOR].set_atten(0) - #verify - self.connect_and_verify_connected_bssid(self.reference_networks[AP_1][ - '5g']['bssid']) - - @test_tracker_info(uuid="3ea818f2-10d7-4aad-bfab-7d8fb25aae78") - def test_network_selector_basic_connection_prefer_5g(self): - """ - 1. Add one saved SSID with 2G and 5G BSSIDs of similar RSSI. - 2. Move the DUT in range. - 3. Verify the DUT is connected to the 5G BSSID. - """ - #add a saved network with both 2G and 5G BSSIDs to DUT - # TODO: bmahadev Change this to a single SSID once we migrate tests to - # use dynamic AP. - networks = [self.reference_networks[AP_1]['2g'], - self.reference_networks[AP_1]['5g']] - self.add_networks(self.dut, networks) - #move the DUT in range - self.attenuators[AP_1_2G_ATTENUATOR].set_atten(0) - self.attenuators[AP_1_5G_ATTENUATOR].set_atten(0) - #verify - self.connect_and_verify_connected_bssid(self.reference_networks[AP_1][ - '5g']['bssid']) - - @test_tracker_info(uuid="bebb29ca-4486-4cde-b390-c5f8f2e1580c") - def test_network_selector_prefer_stronger_rssi(self): - """ - 1. Add two saved SSIDs to DUT, same band, one has stronger RSSI - than the other. - 2. Move the DUT in range. - 3. Verify the DUT is connected to the SSID with stronger RSSI. - """ - #add a 2G and a 5G saved network to DUT - networks = [ - self.reference_networks[AP_1]['2g'], self.reference_networks[AP_2][ - '2g'] - ] - self.add_networks(self.dut, networks) - #move the DUT in range - self.attenuators[AP_1_2G_ATTENUATOR].set_atten(20) - self.attenuators[AP_2_2G_ATTENUATOR].set_atten(40) - #verify - self.connect_and_verify_connected_bssid(self.reference_networks[AP_1][ - '2g']['bssid']) - - @test_tracker_info(uuid="f9f72dc5-034f-4fe2-a27d-df1b6cae76cd") - def test_network_selector_prefer_secure_over_open_network(self): - """ - 1. Add two saved networks to DUT, same band, similar RSSI, one uses - WPA2 security, the other is open. - 2. Move the DUT in range. - 3. Verify the DUT is connected to the secure network that uses WPA2. - """ - #add a open network and a secure saved network to DUT - networks = [ - self.open_network[AP_1]['5g'], self.reference_networks[AP_1]['5g'] - ] - self.add_networks(self.dut, networks) - #move the DUT in range - #TODO: control open network attenuator - self.attenuators[AP_1_5G_ATTENUATOR].set_atten(0) - #verify - self.connect_and_verify_connected_bssid(self.reference_networks[AP_1][ - '5g']['bssid']) - - @test_tracker_info(uuid="ab2c527c-0f9c-4f09-a13f-e3f461b7da52") - def test_network_selector_blacklist_by_connection_failure(self): - """ - 1. Add two saved secured networks X and Y to DUT. X has stronger - RSSI than Y. X has wrong password configured. - 2. Move the DUT in range. - 3. Verify the DUT is connected to network Y. - """ - #add two saved networks to DUT, and one of them is configured with incorrect password - wrong_passwd_network = self.reference_networks[AP_1]['5g'].copy() - wrong_passwd_network['password'] += 'haha' - networks = [wrong_passwd_network, self.reference_networks[AP_2]['5g']] - self.add_networks(self.dut, networks) - #make both AP_1 5G and AP_2 5G in range, and AP_1 5G has stronger RSSI than AP_2 5G - self.attenuators[AP_1_5G_ATTENUATOR].set_atten(0) - self.attenuators[AP_2_5G_ATTENUATOR].set_atten(10) - #start 3 scans to get AP_1 5G blacklisted because of the incorrect password - count = 0 - while count < 3: - wutils.start_wifi_connection_scan(self.dut) - time.sleep(NETWORK_SELECTION_TIME_GAP) - count += 1 - #verify - self.connect_and_verify_connected_bssid(self.reference_networks[AP_2][ - '5g']['bssid']) - - @test_tracker_info(uuid="71d88fcf-c7b8-4fd2-a7cb-84ac4a130ecf") - def test_network_selector_2g_to_5g_prefer_same_SSID(self): - """ - 1. Add SSID_A and SSID_B to DUT. Both SSIDs have both 2G and 5G - BSSIDs. - 2. Attenuate the networks so that the DUT is connected to SSID_A's - 2G in the beginning. - 3. Increase the RSSI of both SSID_A's 5G and SSID_B's 5G. - 4. Verify the DUT switches to SSID_A's 5G. - """ - #add two saved networks to DUT - networks = [ - self.reference_networks[AP_1]['2g'], self.reference_networks[AP_2][ - '2g'] - ] - self.add_networks(self.dut, networks) - #make AP_1 2G in range - self.attenuators[AP_1_2G_ATTENUATOR].set_atten(0) - #verify - self.connect_and_verify_connected_bssid(self.reference_networks[AP_1][ - '2g']['bssid']) - #make both AP_1 and AP_2 5G in range with similar RSSI - self.attenuators[AP_1_5G_ATTENUATOR].set_atten(0) - self.attenuators[AP_2_5G_ATTENUATOR].set_atten(0) - #ensure the time gap between two network selections - time.sleep(NETWORK_SELECTION_TIME_GAP) - #verify - self.connect_and_verify_connected_bssid(self.reference_networks[AP_1][ - '5g']['bssid']) - - @test_tracker_info(uuid="c1243cf4-d96e-427e-869e-3d640bee3f28") - def test_network_selector_2g_to_5g_different_ssid(self): - """ - 1. Add SSID_A and SSID_B to DUT. Both SSIDs have both 2G and 5G - BSSIDs. - 2. Attenuate the networks so that the DUT is connected to SSID_A's - 2G in the beginning. - 3. Increase the RSSI of SSID_B's 5G while attenuate down SSID_A's - 2G RSSI. - 4. Verify the DUT switches to SSID_B's 5G. - """ - #add two saved networks to DUT - networks = [ - self.reference_networks[AP_1]['2g'], self.reference_networks[AP_2][ - '2g'] - ] - self.add_networks(self.dut, networks) - #make both AP_1 2G and AP_2 5G in range, and AP_1 2G - #has much stronger RSSI than AP_2 5G - self.attenuators[AP_1_2G_ATTENUATOR].set_atten(0) - self.attenuators[AP_2_5G_ATTENUATOR].set_atten(20) - #verify - self.connect_and_verify_connected_bssid(self.reference_networks[AP_1][ - '2g']['bssid']) - #bump up AP_2 5G RSSI and reduce AP_1 2G RSSI - self.attenuators[AP_1_2G_ATTENUATOR].set_atten(40) - self.attenuators[AP_2_5G_ATTENUATOR].set_atten(0) - #ensure the time gap between two network selections - time.sleep(NETWORK_SELECTION_TIME_GAP) - #verify - self.connect_and_verify_connected_bssid(self.reference_networks[AP_2][ - '5g']['bssid']) - - @test_tracker_info(uuid="10da95df-83ed-4447-89f8-735b08dbe2eb") - def test_network_selector_5g_to_2g_same_ssid(self): - """ - 1. Add one SSID that has both 2G and 5G to the DUT. - 2. Attenuate down the 2G RSSI. - 3. Connect the DUT to the 5G BSSID. - 4. Bring up the 2G RSSI and attenuate down the 5G RSSI. - 5. Verify the DUT switches to the 2G BSSID. - """ - #add a saved network to DUT - networks = [self.reference_networks[AP_1]['2g']] - self.add_networks(self.dut, networks) - #make both AP_1 2G and AP_2 5G in range, and AP_1 5G - #has much stronger RSSI than AP_2 2G - self.attenuators[AP_1_5G_ATTENUATOR].set_atten(0) - self.attenuators[AP_1_2G_ATTENUATOR].set_atten(50) - #verify - self.connect_and_verify_connected_bssid(self.reference_networks[AP_1][ - '5g']['bssid']) - #bump up AP_1 2G RSSI and reduce AP_1 5G RSSI - self.attenuators[AP_1_2G_ATTENUATOR].set_atten(0) - self.attenuators[AP_1_5G_ATTENUATOR].set_atten(30) - #ensure the time gap between two network selections - time.sleep(NETWORK_SELECTION_TIME_GAP) - #verify - self.connect_and_verify_connected_bssid(self.reference_networks[AP_1][ - '2g']['bssid']) - - @test_tracker_info(uuid="ead78ae0-27ab-4bb8-ae77-0b9fe588436a") - def test_network_selector_stay_on_sufficient_network(self): - """ - 1. Add two 5G WPA2 BSSIDs X and Y to the DUT. X has higher RSSI - than Y. - 2. Connect the DUT to X. - 3. Change attenuation so that Y's RSSI goes above X's. - 4. Verify the DUT stays on X. - """ - #add two saved networks to DUT - networks = [ - self.reference_networks[AP_1]['5g'], self.reference_networks[AP_2][ - '5g'] - ] - self.add_networks(self.dut, networks) - #make both AP_1 5G and AP_2 5G in range, and AP_1 5G - #has stronger RSSI than AP_2 5G - self.attenuators[AP_1_5G_ATTENUATOR].set_atten(10) - self.attenuators[AP_2_5G_ATTENUATOR].set_atten(20) - #verify - self.connect_and_verify_connected_bssid(self.reference_networks[AP_1][ - '5g']['bssid']) - #bump up AP_2 5G RSSI over AP_1 5G RSSI - self.attenuators[AP_2_5G_ATTENUATOR].set_atten(0) - #ensure the time gap between two network selections - time.sleep(NETWORK_SELECTION_TIME_GAP) - #verify - self.connect_and_verify_connected_bssid(self.reference_networks[AP_1][ - '5g']['bssid']) - - @test_tracker_info(uuid="5470010f-8b62-4b1c-8b83-1f91422eced0") - def test_network_selector_stay_on_user_selected_network(self): - """ - 1. Connect the DUT to SSID_A with a very low RSSI via the user select code path. - 2. Add SSID_B to the DUT as saved network. SSID_B has higher RSSI than SSID_A. - 3. Start a scan and network selection. - 4. Verify DUT stays on SSID_A. - """ - #make AP_1 5G in range with a low RSSI - self.attenuators[AP_1_5G_ATTENUATOR].set_atten(10) - #connect to AP_1 via user selection - wutils.wifi_connect(self.dut, self.reference_networks[AP_1]['5g']) - #verify - self.connect_and_verify_connected_bssid(self.reference_networks[AP_1][ - '5g']['bssid']) - #make AP_2 5G in range with a strong RSSI - self.attenuators[AP_2_5G_ATTENUATOR].set_atten(0) - #add AP_2 as a saved network to DUT - networks = [self.reference_networks[AP_2]['5g']] - self.add_networks(self.dut, networks) - #ensure the time gap between two network selections - time.sleep(NETWORK_SELECTION_TIME_GAP) - #verify we are still connected to AP_1 5G - self.connect_and_verify_connected_bssid(self.reference_networks[AP_1][ - '5g']['bssid']) - - @test_tracker_info(uuid="f08d8f73-8c94-42af-bba9-4c49bbf16420") - def test_network_selector_reselect_after_forget_network(self): - """ - 1. Add two 5G BSSIDs X and Y to the DUT. X has higher RSSI - than Y. - 2. Connect the DUT to X. - 3. Forget X. - 5. Verify the DUT reselect and connect to Y. - """ - #add two saved networks to DUT - networks = [ - self.reference_networks[AP_1]['5g'], self.reference_networks[AP_2][ - '5g'] - ] - self.add_networks(self.dut, networks) - #make both AP_1 5G and AP_2 5G in range. AP_1 5G has stronger - #RSSI than AP_2 5G - self.attenuators[AP_1_5G_ATTENUATOR].set_atten(0) - self.attenuators[AP_2_5G_ATTENUATOR].set_atten(10) - #verify - self.connect_and_verify_connected_bssid(self.reference_networks[AP_1][ - '5g']['bssid']) - #forget AP_1 - wutils.wifi_forget_network(self.dut, - self.reference_networks[AP_1]['5g']['SSID']) - #verify - self.connect_and_verify_connected_bssid(self.reference_networks[AP_2][ - '5g']['bssid']) diff --git a/acts/tests/google/wifi/WifiNetworkSuggestionTest.py b/acts/tests/google/wifi/WifiNetworkSuggestionTest.py deleted file mode 100644 index 6d6da35b42..0000000000 --- a/acts/tests/google/wifi/WifiNetworkSuggestionTest.py +++ /dev/null @@ -1,458 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2018 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import itertools -import pprint -import queue -import time - -import acts.base_test -import acts.signals as signals -import acts.test_utils.wifi.wifi_test_utils as wutils -import acts.utils - -from acts import asserts -from acts.controllers.android_device import SL4A_APK_NAME -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest -from acts.test_utils.wifi import wifi_constants - -WifiEnums = wutils.WifiEnums -# EAP Macros -EAP = WifiEnums.Eap -EapPhase2 = WifiEnums.EapPhase2 -# Enterprise Config Macros -Ent = WifiEnums.Enterprise - -# Default timeout used for reboot, toggle WiFi and Airplane mode, -# for the system to settle down after the operation. -DEFAULT_TIMEOUT = 10 - - -class WifiNetworkSuggestionTest(WifiBaseTest): - """Tests for WifiNetworkSuggestion API surface. - - Test Bed Requirement: - * one Android device - * Several Wi-Fi networks visible to the device, including an open Wi-Fi - network. - """ - - def setup_class(self): - super().setup_class() - - self.dut = self.android_devices[0] - wutils.wifi_test_device_init(self.dut) - req_params = [] - opt_param = [ - "open_network", "reference_networks", "radius_conf_2g", "radius_conf_5g", "ca_cert", - "eap_identity", "eap_password", "hidden_networks" - ] - self.unpack_userparams( - req_param_names=req_params, opt_param_names=opt_param) - - if "AccessPoint" in self.user_params: - self.legacy_configure_ap_and_start( - wpa_network=True, ent_network=True, - radius_conf_2g=self.radius_conf_2g, - radius_conf_5g=self.radius_conf_5g,) - - asserts.assert_true( - len(self.reference_networks) > 0, - "Need at least one reference network with psk.") - if hasattr(self, "reference_networks"): - self.wpa_psk_2g = self.reference_networks[0]["2g"] - self.wpa_psk_5g = self.reference_networks[0]["5g"] - if hasattr(self, "open_network"): - self.open_2g = self.open_network[0]["2g"] - self.open_5g = self.open_network[0]["5g"] - if hasattr(self, "ent_networks"): - self.ent_network_2g = self.ent_networks[0]["2g"] - self.ent_network_5g = self.ent_networks[0]["5g"] - self.config_aka = { - Ent.EAP: int(EAP.AKA), - WifiEnums.SSID_KEY: self.ent_network_2g[WifiEnums.SSID_KEY], - } - self.config_ttls = { - Ent.EAP: int(EAP.TTLS), - Ent.CA_CERT: self.ca_cert, - Ent.IDENTITY: self.eap_identity, - Ent.PASSWORD: self.eap_password, - Ent.PHASE2: int(EapPhase2.MSCHAPV2), - WifiEnums.SSID_KEY: self.ent_network_2g[WifiEnums.SSID_KEY], - } - if hasattr(self, "hidden_networks"): - self.hidden_network = self.hidden_networks[0] - self.dut.droid.wifiRemoveNetworkSuggestions([]) - - def setup_test(self): - self.dut.droid.wakeLockAcquireBright() - self.dut.droid.wakeUpNow() - self.clear_deleted_ephemeral_networks() - wutils.wifi_toggle_state(self.dut, True) - self.dut.ed.clear_all_events() - - def teardown_test(self): - self.dut.droid.wakeLockRelease() - self.dut.droid.goToSleepNow() - self.dut.droid.wifiRemoveNetworkSuggestions([]) - self.dut.droid.wifiDisconnect() - wutils.reset_wifi(self.dut) - wutils.wifi_toggle_state(self.dut, False) - self.dut.ed.clear_all_events() - - def on_fail(self, test_name, begin_time): - self.dut.take_bug_report(test_name, begin_time) - self.dut.cat_adb_log(test_name, begin_time) - - def teardown_class(self): - if "AccessPoint" in self.user_params: - del self.user_params["reference_networks"] - del self.user_params["open_network"] - - """Helper Functions""" - def set_approved(self, approved): - self.dut.log.debug("Setting suggestions from sl4a app " - + "approved" if approved else "not approved") - self.dut.adb.shell("cmd wifi network-suggestions-set-user-approved" - + " " + SL4A_APK_NAME - + " " + ("yes" if approved else "no")) - - def is_approved(self): - is_approved_str = self.dut.adb.shell( - "cmd wifi network-suggestions-has-user-approved" - + " " + SL4A_APK_NAME) - return True if (is_approved_str == "yes") else False - - def clear_deleted_ephemeral_networks(self): - self.dut.log.debug("Clearing deleted ephemeral networks") - self.dut.adb.shell( - "cmd wifi clear-deleted-ephemeral-networks") - - def add_suggestions_and_ensure_connection(self, network_suggestions, - expected_ssid, - expect_post_connection_broadcast): - if expect_post_connection_broadcast is not None: - self.dut.droid.wifiStartTrackingNetworkSuggestionStateChange() - - self.dut.log.info("Adding network suggestions"); - asserts.assert_true( - self.dut.droid.wifiAddNetworkSuggestions(network_suggestions), - "Failed to add suggestions") - # Enable suggestions by the app. - self.dut.log.debug("Enabling suggestions from test"); - self.set_approved(True) - wutils.start_wifi_connection_scan_and_return_status(self.dut) - wutils.wait_for_connect(self.dut, expected_ssid) - - if expect_post_connection_broadcast is None: - return; - - # Check if we expected to get the broadcast. - try: - event = self.dut.ed.pop_event( - wifi_constants.WIFI_NETWORK_SUGGESTION_POST_CONNECTION, 60) - except queue.Empty: - if expect_post_connection_broadcast: - raise signals.TestFailure( - "Did not receive post connection broadcast") - else: - if not expect_post_connection_broadcast: - raise signals.TestFailure( - "Received post connection broadcast") - finally: - self.dut.droid.wifiStopTrackingNetworkSuggestionStateChange() - self.dut.ed.clear_all_events() - - def remove_suggestions_disconnect_and_ensure_no_connection_back(self, - network_suggestions, - expected_ssid): - self.dut.log.info("Removing network suggestions") - asserts.assert_true( - self.dut.droid.wifiRemoveNetworkSuggestions(network_suggestions), - "Failed to remove suggestions") - # Ensure we did not disconnect - wutils.ensure_no_disconnect(self.dut) - - # Trigger a disconnect and wait for the disconnect. - self.dut.droid.wifiDisconnect() - wutils.wait_for_disconnect(self.dut) - self.dut.ed.clear_all_events() - - # Now ensure that we didn't connect back. - asserts.assert_false( - wutils.wait_for_connect(self.dut, expected_ssid, assert_on_fail=False), - "Device should not connect back") - - def _test_connect_to_wifi_network_reboot_config_store(self, - network_suggestions, - wifi_network): - """ Test network suggestion with reboot config store - - Args: - 1. network_suggestions: network suggestions in list to add to the device. - 2. wifi_network: expected wifi network to connect to - """ - - self.add_suggestions_and_ensure_connection( - network_suggestions, wifi_network[WifiEnums.SSID_KEY], None) - - # Reboot and wait for connection back to the same suggestion. - self.dut.reboot() - time.sleep(DEFAULT_TIMEOUT) - - wutils.wait_for_connect(self.dut, wifi_network[WifiEnums.SSID_KEY]) - - self.remove_suggestions_disconnect_and_ensure_no_connection_back( - network_suggestions, wifi_network[WifiEnums.SSID_KEY]) - - @test_tracker_info(uuid="bda8ed20-4382-4380-831a-64cf77eca108") - def test_connect_to_wpa_psk_2g(self): - """ Adds a network suggestion and ensure that the device connected. - - Steps: - 1. Send a network suggestion to the device. - 2. Wait for the device to connect to it. - 3. Ensure that we did not receive the post connection broadcast - (isAppInteractionRequired = False). - 4. Remove the suggestions and ensure the device does not connect back. - """ - self.add_suggestions_and_ensure_connection( - [self.wpa_psk_2g], self.wpa_psk_2g[WifiEnums.SSID_KEY], - False) - - self.remove_suggestions_disconnect_and_ensure_no_connection_back( - [self.wpa_psk_2g], self.wpa_psk_2g[WifiEnums.SSID_KEY]) - - @test_tracker_info(uuid="f54bc250-d9e9-4f00-8b5b-b866e8550b43") - def test_connect_to_highest_priority(self): - """ - Adds network suggestions and ensures that device connects to - the suggestion with the highest priority. - - Steps: - 1. Send 2 network suggestions to the device (with different priorities). - 2. Wait for the device to connect to the network with the highest - priority. - 3. Re-add the suggestions with the priorities reversed. - 4. Again wait for the device to connect to the network with the highest - priority. - """ - network_suggestion_2g = self.wpa_psk_2g - network_suggestion_5g = self.wpa_psk_5g - - # Add suggestions & wait for the connection event. - network_suggestion_2g[WifiEnums.PRIORITY] = 5 - network_suggestion_5g[WifiEnums.PRIORITY] = 2 - self.add_suggestions_and_ensure_connection( - [network_suggestion_2g, network_suggestion_5g], - self.wpa_psk_2g[WifiEnums.SSID_KEY], - None) - - self.remove_suggestions_disconnect_and_ensure_no_connection_back( - [], self.wpa_psk_2g[WifiEnums.SSID_KEY]) - - # Reverse the priority. - # Add suggestions & wait for the connection event. - network_suggestion_2g[WifiEnums.PRIORITY] = 2 - network_suggestion_5g[WifiEnums.PRIORITY] = 5 - self.add_suggestions_and_ensure_connection( - [network_suggestion_2g, network_suggestion_5g], - self.wpa_psk_5g[WifiEnums.SSID_KEY], - None) - - @test_tracker_info(uuid="b1d27eea-23c8-4c4f-b944-ef118e4cc35f") - def test_connect_to_wpa_psk_2g_with_post_connection_broadcast(self): - """ Adds a network suggestion and ensure that the device connected. - - Steps: - 1. Send a network suggestion to the device with - isAppInteractionRequired set. - 2. Wait for the device to connect to it. - 3. Ensure that we did receive the post connection broadcast - (isAppInteractionRequired = True). - 4. Remove the suggestions and ensure the device does not connect back. - """ - network_suggestion = self.wpa_psk_2g - network_suggestion[WifiEnums.IS_APP_INTERACTION_REQUIRED] = True - self.add_suggestions_and_ensure_connection( - [network_suggestion], self.wpa_psk_2g[WifiEnums.SSID_KEY], - True) - self.remove_suggestions_disconnect_and_ensure_no_connection_back( - [self.wpa_psk_2g], self.wpa_psk_2g[WifiEnums.SSID_KEY]) - - @test_tracker_info(uuid="a036a24d-29c0-456d-ae6a-afdde34da710") - def test_connect_to_wpa_psk_5g_reboot_config_store(self): - """ - Adds a network suggestion and ensure that the device connects to it - after reboot. - - Steps: - 1. Send a network suggestion to the device. - 2. Wait for the device to connect to it. - 3. Ensure that we did not receive the post connection broadcast - (isAppInteractionRequired = False). - 4. Reboot the device. - 5. Wait for the device to connect to back to it. - 6. Remove the suggestions and ensure the device does not connect back. - """ - self._test_connect_to_wifi_network_reboot_config_store( - [self.wpa_psk_5g], self.wpa_psk_5g) - - @test_tracker_info(uuid="61649a2b-0f00-4272-9b9b-40ad5944da31") - def test_connect_to_wpa_ent_config_aka_reboot_config_store(self): - """ - Adds a network suggestion and ensure that the device connects to it - after reboot. - - Steps: - 1. Send a Enterprise AKA network suggestion to the device. - 2. Wait for the device to connect to it. - 3. Ensure that we did not receive the post connection broadcast. - 4. Reboot the device. - 5. Wait for the device to connect to the wifi network. - 6. Remove suggestions and ensure device doesn't connect back to it. - """ - self._test_connect_to_wifi_network_reboot_config_store( - [self.config_aka], self.ent_network_2g) - - @test_tracker_info(uuid="98b2d40a-acb4-4a2f-aba1-b069e2a1d09d") - def test_connect_to_wpa_ent_config_ttls_pap_reboot_config_store(self): - """ - Adds a network suggestion and ensure that the device connects to it - after reboot. - - Steps: - 1. Send a Enterprise TTLS PAP network suggestion to the device. - 2. Wait for the device to connect to it. - 3. Ensure that we did not receive the post connection broadcast. - 4. Reboot the device. - 5. Wait for the device to connect to the wifi network. - 6. Remove suggestions and ensure device doesn't connect back to it. - """ - config = dict(self.config_ttls) - config[WifiEnums.Enterprise.PHASE2] = WifiEnums.EapPhase2.PAP.value - - self._test_connect_to_wifi_network_reboot_config_store( - [config], self.ent_network_2g) - - @test_tracker_info(uuid="554b5861-22d0-4922-a5f4-712b4cf564eb") - def test_fail_to_connect_to_wpa_psk_5g_when_not_approved(self): - """ - Adds a network suggestion and ensure that the device does not - connect to it until we approve the app. - - Steps: - 1. Send a network suggestion to the device with the app not approved. - 2. Ensure the network is present in scan results, but we don't connect - to it. - 3. Now approve the app. - 4. Wait for the device to connect to it. - """ - self.dut.log.info("Adding network suggestions"); - asserts.assert_true( - self.dut.droid.wifiAddNetworkSuggestions([self.wpa_psk_5g]), - "Failed to add suggestions") - - # Disable suggestions by the app. - self.set_approved(False) - - # Ensure the app is not approved. - asserts.assert_false( - self.is_approved(), - "Suggestions should be disabled") - - # Start a new scan to trigger auto-join. - wutils.start_wifi_connection_scan_and_ensure_network_found( - self.dut, self.wpa_psk_5g[WifiEnums.SSID_KEY]) - - # Ensure we don't connect to the network. - asserts.assert_false( - wutils.wait_for_connect( - self.dut, self.wpa_psk_5g[WifiEnums.SSID_KEY], assert_on_fail=False), - "Should not connect to network suggestions from unapproved app") - - self.dut.log.info("Enabling suggestions from test"); - # Now Enable suggestions by the app & ensure we connect to the network. - self.set_approved(True) - - # Ensure the app is approved. - asserts.assert_true( - self.is_approved(), - "Suggestions should be enabled") - - # Start a new scan to trigger auto-join. - wutils.start_wifi_connection_scan_and_ensure_network_found( - self.dut, self.wpa_psk_5g[WifiEnums.SSID_KEY]) - - wutils.wait_for_connect(self.dut, self.wpa_psk_5g[WifiEnums.SSID_KEY]) - - @test_tracker_info(uuid="98400dea-776e-4a0a-9024-18845b27331c") - def test_fail_to_connect_to_wpa_psk_2g_after_user_forgot_network(self): - """ - Adds a network suggestion and ensures that the device does not - connect to it after the user forgot the network previously. - - Steps: - 1. Send a network suggestion to the device with - isAppInteractionRequired set. - 2. Wait for the device to connect to it. - 3. Ensure that we did receive the post connection broadcast - (isAppInteractionRequired = True). - 4. Simulate user forgetting the network and the device does not - connecting back even though the suggestion is active from the app. - """ - network_suggestion = self.wpa_psk_2g - network_suggestion[WifiEnums.IS_APP_INTERACTION_REQUIRED] = True - self.add_suggestions_and_ensure_connection( - [network_suggestion], self.wpa_psk_2g[WifiEnums.SSID_KEY], - True) - - # Simulate user forgetting the ephemeral network. - self.dut.droid.wifiDisableEphemeralNetwork( - self.wpa_psk_2g[WifiEnums.SSID_KEY]) - wutils.wait_for_disconnect(self.dut) - self.dut.log.info("Disconnected from network %s", self.wpa_psk_2g) - self.dut.ed.clear_all_events() - - # Now ensure that we don't connect back even though the suggestion - # is still active. - asserts.assert_false( - wutils.wait_for_connect(self.dut, - self.wpa_psk_2g[WifiEnums.SSID_KEY], - assert_on_fail=False), - "Device should not connect back") - - @test_tracker_info(uuid="93c86b05-fa56-4d79-ad27-009a16f691b1") - def test_connect_to_hidden_network(self): - """ - Adds a network suggestion with hidden SSID config, ensure device can scan - and connect to this network. - - Steps: - 1. Send a hidden network suggestion to the device. - 2. Wait for the device to connect to it. - 3. Ensure that we did not receive the post connection broadcast - (isAppInteractionRequired = False). - 4. Remove the suggestions and ensure the device does not connect back. - """ - asserts.skip_if(not hasattr(self, "hidden_networks"), "No hidden networks, skip this test") - - network_suggestion = self.hidden_network - self.add_suggestions_and_ensure_connection( - [network_suggestion], network_suggestion[WifiEnums.SSID_KEY], False) - self.remove_suggestions_disconnect_and_ensure_no_connection_back( - [network_suggestion], network_suggestion[WifiEnums.SSID_KEY]) diff --git a/acts/tests/google/wifi/WifiNewSetupAutoJoinTest.py b/acts/tests/google/wifi/WifiNewSetupAutoJoinTest.py deleted file mode 100644 index b5ba8997d7..0000000000 --- a/acts/tests/google/wifi/WifiNewSetupAutoJoinTest.py +++ /dev/null @@ -1,516 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2016 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import time - -from acts import asserts -from acts import base_test -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi import wifi_constants -from acts.test_utils.wifi import wifi_test_utils as wutils -from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest - -WifiEnums = wutils.WifiEnums -NETWORK_ID_ERROR = "Network don't have ID" -NETWORK_ERROR = "Device is not connected to reference network" - - -class WifiNewSetupAutoJoinTest(WifiBaseTest): - def add_network_and_enable(self, network): - """Add a network and enable it. - - Args: - network : Network details for the network to be added. - - """ - ret = self.dut.droid.wifiAddNetwork(network) - asserts.assert_true(ret != -1, "Add network %r failed" % network) - self.dut.droid.wifiEnableNetwork(ret, 0) - - def setup_class(self): - """It will setup the required dependencies from config file and configure - the required networks for auto-join testing. Configured networks will - not be removed. If networks are already configured it will skip - configuring the networks - - Returns: - True if successfully configured the requirements for testing. - """ - super().setup_class() - - self.dut = self.android_devices[0] - wutils.wifi_test_device_init(self.dut) - req_params = ("atten_val", "ping_addr", "max_bugreports") - opt_param = ["reference_networks"] - self.unpack_userparams( - req_param_names=req_params, opt_param_names=opt_param) - - if "AccessPoint" in self.user_params: - self.legacy_configure_ap_and_start(ap_count=2) - - configured_networks = self.dut.droid.wifiGetConfiguredNetworks() - self.log.debug("Configured networks :: {}".format(configured_networks)) - count_confnet = 0 - result = False - if self.reference_networks[0]['2g']['SSID'] == self.reference_networks[ - 0]['5g']['SSID']: - self.ref_ssid_count = 1 - else: - self.ref_ssid_count = 2 # Different SSID for 2g and 5g - for confnet in configured_networks: - if confnet[WifiEnums.SSID_KEY] == self.reference_networks[0]['2g'][ - 'SSID']: - count_confnet += 1 - elif confnet[WifiEnums.SSID_KEY] == self.reference_networks[0][ - '5g']['SSID']: - count_confnet += 1 - self.log.info("count_confnet {}".format(count_confnet)) - if count_confnet == self.ref_ssid_count: - return - else: - self.log.info("Configured networks for testing") - self.attenuators[0].set_atten(0) - self.attenuators[1].set_atten(0) - self.attenuators[2].set_atten(90) - self.attenuators[3].set_atten(90) - wait_time = 15 - self.dut.droid.wakeLockAcquireBright() - self.dut.droid.wakeUpNow() - # Add and enable all networks. - for network in self.reference_networks: - self.add_network_and_enable(network['2g']) - self.add_network_and_enable(network['5g']) - self.dut.droid.wifiLockRelease() - self.dut.droid.goToSleepNow() - - def check_connection(self, network_bssid): - """Check current wifi connection networks. - Args: - network_bssid: Network bssid to which connection. - Returns: - True if connection to given network happen, else return False. - """ - time.sleep(40) #time for connection state to be updated - self.log.info("Check network for {}".format(network_bssid)) - current_network = self.dut.droid.wifiGetConnectionInfo() - self.log.debug("Current network: {}".format(current_network)) - if WifiEnums.BSSID_KEY in current_network: - return current_network[WifiEnums.BSSID_KEY] == network_bssid - return False - - def set_attn_and_validate_connection(self, attn_value, bssid): - """Validate wifi connection status on different attenuation setting. - - Args: - attn_value: Attenuation value for different APs signal. - bssid: Bssid of excepted network. - - Returns: - True if bssid of current network match, else false. - """ - self.attenuators[0].set_atten(attn_value[0]) - self.attenuators[1].set_atten(attn_value[1]) - self.attenuators[2].set_atten(attn_value[2]) - self.attenuators[3].set_atten(attn_value[3]) - self.dut.droid.wakeLockAcquireBright() - self.dut.droid.wakeUpNow() - try: - asserts.assert_true( - self.check_connection(bssid), - "Device is not connected to required bssid {}".format(bssid)) - time.sleep(10) #wait for connection to be active - asserts.assert_true( - wutils.validate_connection(self.dut, self.ping_addr), - "Error, No Internet connection for current bssid {}".format( - bssid)) - finally: - self.dut.droid.wifiLockRelease() - self.dut.droid.goToSleepNow() - - def on_fail(self, test_name, begin_time): - if self.max_bugreports > 0: - self.dut.take_bug_report(test_name, begin_time) - self.max_bugreports -= 1 - self.dut.cat_adb_log(test_name, begin_time) - - def teardown_class(self): - for ad in self.android_devices: - wutils.reset_wifi(ad) - if "AccessPoint" in self.user_params: - del self.user_params["reference_networks"] - del self.user_params["open_network"] - - """ Tests Begin """ - - """ Test wifi auto join functionality move in range of AP1. - - 1. Attenuate the signal to low range of AP1 and Ap2 not visible at all. - 2. Wake up the device. - 3. Check that device is connected to right BSSID and maintain stable - connection to BSSID in range. - """ - @test_tracker_info(uuid="9ea2c78d-d305-497f-87a5-f621f0a4b34e") - def test_autojoin_Ap1_2g_AP1_20_AP2_95_AP3_95(self): - att0, att1, att2, att3 = self.atten_val["Ap1_2g"] - variance = 5 - attn_value = [att0 + variance * 2, att1, att2, att3] - self.set_attn_and_validate_connection( - attn_value, self.reference_networks[0]["2g"]['bssid']) - - @test_tracker_info(uuid="7c34a508-2ffa-4bca-82b3-9637b7c8250a") - def test_autojoin_Ap1_2g_AP1_15_AP2_95_AP3_95(self): - att0, att1, att2, att3 = self.atten_val["Ap1_2g"] - variance = 5 - attn_value = [att0 + variance, att1, att2, att3] - self.set_attn_and_validate_connection( - attn_value, self.reference_networks[0]["2g"]['bssid']) - - @test_tracker_info(uuid="ea614fcc-7fca-4172-ba3a-5978427eb40f") - def test_autojoin_Ap1_2g_AP1_10_AP2_95_AP3_95(self): - att0, att1, att2, att3 = self.atten_val["Ap1_2g"] - variance = 5 - attn_value = [att0, att1, att2, att3] - self.set_attn_and_validate_connection( - attn_value, self.reference_networks[0]["2g"]['bssid']) - - @test_tracker_info(uuid="a1ad25cf-11e7-4240-b3c0-9f14325d5b2d") - def test_autojoin_Ap1_2g_AP1_5_AP2_95_AP3_95(self): - att0, att1, att2, att3 = self.atten_val["Ap1_2g"] - variance = 5 - attn_value = [att0 - variance, att1, att2, att3] - self.set_attn_and_validate_connection( - attn_value, self.reference_networks[0]["2g"]['bssid']) - - """ Test wifi auto join functionality move to high range. - - 1. Attenuate the signal to high range of AP1. - 2. Wake up the device. - 3. Check that device is connected to right BSSID and maintain stable - connection to BSSID in range. - """ - @test_tracker_info(uuid="b5eba5ec-96e5-4bd8-b483-f5b2a9504558") - def test_autojoin_Ap1_2gto5g_AP1_55_AP2_10_AP3_95(self): - att0, att1, att2, attn3 = self.atten_val["Ap1_2gto5g"] - variance = 5 - attn_value = [att0 + variance * 2, att1, att2, attn3] - self.set_attn_and_validate_connection( - attn_value, self.reference_networks[0]["5g"]['bssid']) - - @test_tracker_info(uuid="e63543f7-5f43-4ba2-a5bd-2af3c159a622") - def test_autojoin_Ap1_2gto5g_AP1_50_AP2_10_AP3_95(self): - att0, att1, att2, attn3 = self.atten_val["Ap1_2gto5g"] - variance = 5 - attn_value = [att0 + variance, att1, att2, attn3] - self.set_attn_and_validate_connection( - attn_value, self.reference_networks[0]["5g"]['bssid']) - - @test_tracker_info(uuid="0c2cef5d-695d-4d4e-832d-f5e8b393a09c") - def test_autojoin_Ap1_2gto5g_AP1_45_AP2_10_AP3_95(self): - att0, att1, att2, attn3 = self.atten_val["Ap1_2gto5g"] - variance = 5 - attn_value = [att0, att1, att2, attn3] - self.set_attn_and_validate_connection( - attn_value, self.reference_networks[0]["5g"]['bssid']) - - """ Test wifi auto join functionality move to low range toward AP2. - - 1. Attenuate the signal to medium range of AP1 and low range of AP2. - 2. Wake up the device. - 3. Check that device is connected to right BSSID and maintain stable - connection to BSSID in range. - """ - @test_tracker_info(uuid="37822578-d35c-462c-87c0-7a2d9252938c") - def test_autojoin_in_AP1_5gto2g_AP1_5_AP2_80_AP3_95(self): - att0, att1, att2, attn3 = self.atten_val["In_AP1_5gto2g"] - variance = 5 - attn_value = [att0 - variance, att1 + variance, att2, attn3] - self.set_attn_and_validate_connection( - attn_value, self.reference_networks[0]["2g"]['bssid']) - - @test_tracker_info(uuid="194ffe44-9718-4beb-b69e-cccb569f9b81") - def test_autojoin_in_AP1_5gto2g_AP1_10_AP2_75_AP3_95(self): - att0, att1, att2, attn3 = self.atten_val["In_AP1_5gto2g"] - variance = 5 - attn_value = [att0, att1, att2, attn3] - self.set_attn_and_validate_connection( - attn_value, self.reference_networks[0]["2g"]['bssid']) - - @test_tracker_info(uuid="09bdcb0f-7833-4604-a839-f7d981bf4aca") - def test_autojoin_in_AP1_5gto2g_AP1_15_AP2_70_AP3_95(self): - att0, att1, att2, attn3 = self.atten_val["In_AP1_5gto2g"] - variance = 5 - attn_value = [att0 + variance, att1 - variance, att2, attn3] - self.set_attn_and_validate_connection( - attn_value, self.reference_networks[0]["2g"]['bssid']) - - """ Test wifi auto join functionality move from low range of AP1 to better - range of AP2. - - 1. Attenuate the signal to low range of AP1 and medium range of AP2. - 2. Wake up the device. - 3. Check that device is connected to right BSSID and maintain stable - connection to BSSID in range. - """ - @test_tracker_info(uuid="8ffdcab1-2bfb-4acd-b1e8-089ba8a4ec41") - def test_autojoin_swtich_AP1toAp2_AP1_65_AP2_75_AP3_2(self): - att0, att1, att2, attn3 = self.atten_val["Swtich_AP1toAp2"] - variance = 5 - attn_value = [att0 - variance, att1 + variance, att2, attn3] - self.set_attn_and_validate_connection( - attn_value, self.reference_networks[1]["2g"]['bssid']) - - @test_tracker_info(uuid="23e05821-3c53-4033-830e-a446b6105831") - def test_autojoin_swtich_AP1toAp2_AP1_70_AP2_70_AP3_2(self): - att0, att1, att2, attn3 = self.atten_val["Swtich_AP1toAp2"] - variance = 5 - attn_value = [att0, att1, att2, attn3] - self.set_attn_and_validate_connection( - attn_value, self.reference_networks[1]["2g"]['bssid']) - - @test_tracker_info(uuid="a56ad87d-d37f-4606-9ae8-af6f55cbb6cf") - def test_autojoin_swtich_AP1toAp2_AP1_75_AP2_65_AP3_2(self): - att0, att1, att2, attn3 = self.atten_val["Swtich_AP1toAp2"] - variance = 5 - attn_value = [att0 + variance, att1 - variance, att2, attn3] - self.set_attn_and_validate_connection( - attn_value, self.reference_networks[1]["2g"]['bssid']) - - """ Test wifi auto join functionality move to high range of AP2. - - 1. Attenuate the signal to out range of AP1 and high range of AP2. - 2. Wake up the device. - 3. Check that device is connected to right BSSID and maintain stable - connection to BSSID in range. - """ - @test_tracker_info(uuid="7a8b9242-f93c-449a-90a6-4562274a213a") - def test_autojoin_Ap2_2gto5g_AP1_70_AP2_85_AP3_75(self): - att0, att1, att2, attn3 = self.atten_val["Ap2_2gto5g"] - variance = 5 - attn_value = [att0 - variance, att1 + variance * 2, att2, attn3] - self.set_attn_and_validate_connection( - attn_value, self.reference_networks[1]["5g"]['bssid']) - - @test_tracker_info(uuid="5e0c5485-a3ae-438a-92e5-9a6b5a22cb82") - def test_autojoin_Ap2_2gto5g_AP1_75_AP2_80_AP3_75(self): - att0, att1, att2, attn3 = self.atten_val["Ap2_2gto5g"] - variance = 5 - attn_value = [att0, att1 + variance, att2, attn3] - self.set_attn_and_validate_connection( - attn_value, self.reference_networks[1]["5g"]['bssid']) - - @test_tracker_info(uuid="3b289144-a12a-424f-822e-8d173d75c3c3") - def test_autojoin_Ap2_2gto5g_AP1_75_AP2_75_AP3_75(self): - att0, att1, att2, attn3 = self.atten_val["Ap2_2gto5g"] - variance = 5 - attn_value = [att0, att1, att2, attn3] - self.set_attn_and_validate_connection( - attn_value, self.reference_networks[1]["5g"]['bssid']) - - """ Test wifi auto join functionality move to low range of AP2. - - 1. Attenuate the signal to low range of AP2. - 2. Wake up the device. - 3. Check that device is connected to right BSSID and maintain stable. - """ - @test_tracker_info(uuid="009457df-f430-402c-96ab-c456b043b6f5") - def test_autojoin_Ap2_5gto2g_AP1_75_AP2_70_AP3_10(self): - att0, att1, att2, attn3 = self.atten_val["Ap2_5gto2g"] - variance = 5 - attn_value = [att0, att1 - variance, att2, attn3] - self.set_attn_and_validate_connection( - attn_value, self.reference_networks[1]["2g"]['bssid']) - - @test_tracker_info(uuid="15ef731c-ddfb-4118-aedb-c177f50bdea0") - def test_autojoin_Ap2_5gto2g_AP1_75_AP2_75_AP3_10(self): - att0, att1, att2, attn3 = self.atten_val["Ap2_5gto2g"] - variance = 5 - attn_value = [att0, att1, att2, attn3] - self.set_attn_and_validate_connection( - attn_value, self.reference_networks[1]["2g"]['bssid']) - - @test_tracker_info(uuid="f79b0570-56a0-43d2-962d-9e114d48bacf") - def test_autojoin_Ap2_5gto2g_AP1_75_AP2_80_AP3_10(self): - att0, att1, att2, attn3 = self.atten_val["Ap2_5gto2g"] - variance = 5 - attn_value = [att0, att1 + variance, att2, attn3] - self.set_attn_and_validate_connection( - attn_value, self.reference_networks[1]["2g"]['bssid']) - - @test_tracker_info(uuid="c6d070af-b601-42f1-adec-5ac564154b29") - def test_autojoin_out_of_range(self): - """Test wifi auto join functionality move to low range. - - 1. Attenuate the signal to out of range. - 2. Wake up the device. - 3. Start the scan. - 4. Check that device is not connected to any network. - """ - self.attenuators[0].set_atten(90) - self.attenuators[1].set_atten(90) - self.attenuators[2].set_atten(90) - self.attenuators[3].set_atten(90) - self.dut.droid.wakeLockAcquireBright() - self.dut.droid.wakeUpNow() - try: - wutils.start_wifi_connection_scan(self.dut) - wifi_results = self.dut.droid.wifiGetScanResults() - self.log.debug("Scan result {}".format(wifi_results)) - time.sleep(20) - current_network = self.dut.droid.wifiGetConnectionInfo() - self.log.info("Current network: {}".format(current_network)) - asserts.assert_true( - ('network_id' in current_network and - current_network['network_id'] == -1), - "Device is connected to network {}".format(current_network)) - finally: - self.dut.droid.wifiLockRelease() - self.dut.droid.goToSleepNow() - - """ Test wifi auto join functionality move in low range of AP2. - - 1. Attenuate the signal to move in range of AP2 and Ap1 not visible at all. - 2. Wake up the device. - 3. Check that device is connected to right BSSID and maintain stable - connection to BSSID in range. - """ - @test_tracker_info(uuid="15c27654-bae0-4d2d-bdc8-54fb04b901d1") - def test_autojoin_Ap2_2g_AP1_75_AP2_85_AP3_10(self): - att0, att1, att2, attn3 = self.atten_val["Ap2_2g"] - variance = 5 - attn_value = [att0, att1 + variance * 2, att2, attn3] - self.set_attn_and_validate_connection( - attn_value, self.reference_networks[1]["2g"]['bssid']) - - @test_tracker_info(uuid="af40824a-4d65-4789-980f-d534abeca36b") - def test_autojoin_Ap2_2g_AP1_75_AP2_80_AP3_10(self): - att0, att1, att2, attn3 = self.atten_val["Ap2_2g"] - variance = 5 - attn_value = [att0, att1 + variance, att2, attn3] - self.set_attn_and_validate_connection( - attn_value, self.reference_networks[1]["2g"]['bssid']) - - @test_tracker_info(uuid="2d482060-9865-472b-810b-c74c6a099e6c") - def test_autojoin_Ap2_2g_AP1_75_AP2_75_AP3_10(self): - att0, att1, att2, attn3 = self.atten_val["Ap2_2g"] - variance = 5 - attn_value = [att0, att1, att2, attn3] - self.set_attn_and_validate_connection( - attn_value, self.reference_networks[1]["2g"]['bssid']) - - @test_tracker_info(uuid="b5cad09e-6e31-40f4-a568-2a1d5271e20c") - def test_autojoin_Ap2_2g_AP1_75_AP2_70_AP3_10(self): - att0, att1, att2, attn3 = self.atten_val["Ap2_2g"] - variance = 5 - attn_value = [att0, att1 - variance, att2, attn3] - self.set_attn_and_validate_connection( - attn_value, self.reference_networks[1]["2g"]['bssid']) - - """ Test wifi auto join functionality move to medium range of Ap2 and - low range of AP1. - - 1. Attenuate the signal to move in medium range of AP2 and low range of AP1. - 2. Wake up the device. - 3. Check that device is connected to right BSSID and maintain stable - connection to BSSID in range. - """ - @test_tracker_info(uuid="80e74c78-59e2-46db-809d-cb03bd1b6824") - def test_autojoin_in_Ap2_5gto2g_AP1_75_AP2_70_AP3_10(self): - att0, att1, att2, attn3 = self.atten_val["In_Ap2_5gto2g"] - variance = 5 - attn_value = [att0, att1 - variance, att2, attn3] - self.set_attn_and_validate_connection( - attn_value, self.reference_networks[1]["2g"]['bssid']) - - @test_tracker_info(uuid="d2a188bd-91cf-4412-a098-739c0c236fe1") - def test_autojoin_in_Ap2_5gto2g_AP1_75_AP2_75_AP3_10(self): - att0, att1, att2, attn3 = self.atten_val["In_Ap2_5gto2g"] - variance = 5 - attn_value = [att0, att1, att2, attn3] - self.set_attn_and_validate_connection( - attn_value, self.reference_networks[1]["2g"]['bssid']) - - @test_tracker_info(uuid="032e81e9-bc8a-4fa2-a96b-d733c241869e") - def test_autojoin_in_Ap2_5gto2g_AP1_75_AP2_80_AP3_10(self): - att0, att1, att2, attn3 = self.atten_val["In_Ap2_5gto2g"] - variance = 5 - attn_value = [att0, att1 + variance, att2, attn3] - self.set_attn_and_validate_connection( - attn_value, self.reference_networks[1]["2g"]['bssid']) - - """ Test wifi auto join functionality move from low range of AP2 to better - range of AP1. - - 1. Attenuate the signal to low range of AP2 and medium range of AP1. - 2. Wake up the device. - 3. Check that device is connected to right BSSID and maintain stable - connection to BSSID in range. - """ - @test_tracker_info(uuid="01faeba0-bd66-4d30-a3d9-b81e959025b2") - def test_autojoin_swtich_AP2toAp1_AP1_15_AP2_65_AP3_75(self): - att0, att1, att2, attn3 = self.atten_val["Swtich_AP2toAp1"] - variance = 5 - attn_value = [att0 + variance, att1 - variance, att2, attn3] - self.set_attn_and_validate_connection( - attn_value, self.reference_networks[0]["2g"]['bssid']) - - @test_tracker_info(uuid="68b15c50-03ab-4385-9231-280002315fe5") - def test_autojoin_swtich_AP2toAp1_AP1_10_AP2_70_AP3_75(self): - att0, att1, att2, attn3 = self.atten_val["Swtich_AP2toAp1"] - variance = 5 - attn_value = [att0, att1, att2, attn3] - self.set_attn_and_validate_connection( - attn_value, self.reference_networks[0]["2g"]['bssid']) - - @test_tracker_info(uuid="1986d79b-097e-44c9-9aff-7bcd56490c3b") - def test_autojoin_swtich_AP2toAp1_AP1_5_AP2_75_AP3_75(self): - att0, att1, att2, attn3 = self.atten_val["Swtich_AP2toAp1"] - variance = 5 - attn_value = [att0 - variance, att1 + variance, att2, attn3] - self.set_attn_and_validate_connection( - attn_value, self.reference_networks[0]["2g"]['bssid']) - - """ Test wifi auto join functionality move to medium range of AP1. - - 1. Attenuate the signal to medium range of AP1. - 2. Wake up the device. - 3. Check that device is connected to right BSSID and maintain stable - connection to BSSID in range. - """ - @test_tracker_info(uuid="ec509d40-e339-47c2-995e-cc77f5a28687") - def test_autojoin_Ap1_5gto2g_AP1_10_AP2_80_AP3_95(self): - att0, att1, att2, attn3 = self.atten_val["Ap1_5gto2g"] - variance = 5 - attn_value = [att0, att1, att2, attn3] - self.set_attn_and_validate_connection( - attn_value, self.reference_networks[0]["2g"]['bssid']) - - @test_tracker_info(uuid="ddc66d1e-3241-4040-996a-85bc2a2a4d67") - def test_autojoin_Ap1_5gto2g_AP1_15_AP2_80_AP3_95(self): - att0, att1, att2, attn3 = self.atten_val["Ap1_5gto2g"] - variance = 5 - attn_value = [att0 + variance, att1, att2, attn3] - self.set_attn_and_validate_connection( - attn_value, self.reference_networks[0]["2g"]['bssid']) - - @test_tracker_info(uuid="dfc84504-230f-428e-b701-edc496d0e7b3") - def test_autojoin_Ap1_5gto2g_AP1_20_AP2_80_AP3_95(self): - att0, att1, att2, attn3 = self.atten_val["Ap1_5gto2g"] - variance = 5 - attn_value = [att0 + variance * 2, att1, att2, attn3] - self.set_attn_and_validate_connection( - attn_value, self.reference_networks[0]["2g"]['bssid']) - - """ Tests End """ diff --git a/acts/tests/google/wifi/WifiPasspointTest.py b/acts/tests/google/wifi/WifiPasspointTest.py deleted file mode 100755 index b867faad98..0000000000 --- a/acts/tests/google/wifi/WifiPasspointTest.py +++ /dev/null @@ -1,397 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import itertools -import pprint -import queue -import time - -import acts.base_test -import acts.test_utils.wifi.wifi_test_utils as wutils - - -import WifiManagerTest -from acts import asserts -from acts import signals -from acts.libs.uicd.uicd_cli import UicdCli -from acts.libs.uicd.uicd_cli import UicdError -from acts.test_decorators import test_tracker_info -from acts.test_utils.tel.tel_test_utils import get_operator_name -from acts.utils import force_airplane_mode - -WifiEnums = wutils.WifiEnums - -DEFAULT_TIMEOUT = 10 -OSU_TEST_TIMEOUT = 300 - -# Constants for providers. -GLOBAL_RE = 0 -OSU_BOINGO = 0 -BOINGO = 1 -ATT = 2 - -# Constants used for various device operations. -RESET = 1 -TOGGLE = 2 - -UNKNOWN_FQDN = "@#@@!00fffffx" - -class WifiPasspointTest(acts.base_test.BaseTestClass): - """Tests for APIs in Android's WifiManager class. - - Test Bed Requirement: - * One Android device - * Several Wi-Fi networks visible to the device, including an open Wi-Fi - network. - """ - - def setup_class(self): - self.dut = self.android_devices[0] - wutils.wifi_test_device_init(self.dut) - req_params = ["passpoint_networks", "uicd_workflows", "uicd_zip"] - opt_param = [] - self.unpack_userparams( - req_param_names=req_params, opt_param_names=opt_param) - self.unpack_userparams(req_params) - asserts.assert_true( - len(self.passpoint_networks) > 0, - "Need at least one Passpoint network.") - wutils.wifi_toggle_state(self.dut, True) - self.unknown_fqdn = UNKNOWN_FQDN - # Setup Uicd cli object for UI interation. - self.ui = UicdCli(self.uicd_zip[0], self.uicd_workflows) - self.passpoint_workflow = "passpoint-login_%s" % self.dut.model - - - def setup_test(self): - self.dut.droid.wakeLockAcquireBright() - self.dut.droid.wakeUpNow() - self.dut.unlock_screen() - - - def teardown_test(self): - self.dut.droid.wakeLockRelease() - self.dut.droid.goToSleepNow() - wutils.reset_wifi(self.dut) - - - def on_fail(self, test_name, begin_time): - self.dut.take_bug_report(test_name, begin_time) - - - """Helper Functions""" - - - def install_passpoint_profile(self, passpoint_config): - """Install the Passpoint network Profile. - - Args: - passpoint_config: A JSON dict of the Passpoint configuration. - - """ - asserts.assert_true(WifiEnums.SSID_KEY in passpoint_config, - "Key '%s' must be present in network definition." % - WifiEnums.SSID_KEY) - # Install the Passpoint profile. - self.dut.droid.addUpdatePasspointConfig(passpoint_config) - - - def check_passpoint_connection(self, passpoint_network): - """Verify the device is automatically able to connect to the Passpoint - network. - - Args: - passpoint_network: SSID of the Passpoint network. - - """ - ad = self.dut - ad.ed.clear_all_events() - wutils.start_wifi_connection_scan(ad) - scan_results = ad.droid.wifiGetScanResults() - # Wait for scan to complete. - time.sleep(5) - ssid = passpoint_network - wutils.assert_network_in_list({WifiEnums.SSID_KEY: ssid}, scan_results) - # Passpoint network takes longer time to connect than normal networks. - # Every try comes with a timeout of 30s. Setting total timeout to 120s. - wutils.wifi_passpoint_connect(self.dut, passpoint_network, num_of_tries=4) - # Re-verify we are connected to the correct network. - network_info = self.dut.droid.wifiGetConnectionInfo() - if network_info[WifiEnums.SSID_KEY] != passpoint_network: - raise signals.TestFailure("Device did not connect to the passpoint" - " network.") - - - def get_configured_passpoint_and_delete(self): - """Get configured Passpoint network and delete using its FQDN.""" - passpoint_config = self.dut.droid.getPasspointConfigs() - if not len(passpoint_config): - raise signals.TestFailure("Failed to fetch the list of configured" - "passpoint networks.") - if not wutils.delete_passpoint(self.dut, passpoint_config[0]): - raise signals.TestFailure("Failed to delete Passpoint configuration" - " with FQDN = %s" % passpoint_config[0]) - - def start_subscription_provisioning(self, state): - """Start subscription provisioning with a default provider.""" - - self.unpack_userparams(('osu_configs',)) - asserts.assert_true( - len(self.osu_configs) > 0, - "Need at least one osu config.") - osu_config = self.osu_configs[OSU_BOINGO] - # Clear all previous events. - self.dut.ed.clear_all_events() - self.dut.droid.startSubscriptionProvisioning(osu_config) - start_time = time.time() - while time.time() < start_time + OSU_TEST_TIMEOUT: - dut_event = self.dut.ed.pop_event("onProvisioningCallback", - DEFAULT_TIMEOUT * 18) - if dut_event['data']['tag'] == 'success': - self.log.info("Passpoint Provisioning Success") - # Reset WiFi after provisioning success. - if state == RESET: - wutils.reset_wifi(self.dut) - time.sleep(DEFAULT_TIMEOUT) - # Toggle WiFi after provisioning success. - elif state == TOGGLE: - wutils.toggle_wifi_off_and_on(self.dut) - time.sleep(DEFAULT_TIMEOUT) - break - if dut_event['data']['tag'] == 'failure': - raise signals.TestFailure( - "Passpoint Provisioning is failed with %s" % - dut_event['data'][ - 'reason']) - break - if dut_event['data']['tag'] == 'status': - self.log.info( - "Passpoint Provisioning status %s" % dut_event['data'][ - 'status']) - if int(dut_event['data']['status']) == 7: - self.ui.run(self.dut.serial, self.passpoint_workflow) - # Clear all previous events. - self.dut.ed.clear_all_events() - - # Verify device connects to the Passpoint network. - time.sleep(DEFAULT_TIMEOUT) - current_passpoint = self.dut.droid.wifiGetConnectionInfo() - if current_passpoint[WifiEnums.SSID_KEY] not in osu_config[ - "expected_ssids"]: - raise signals.TestFailure("Device did not connect to the %s" - " passpoint network" % osu_config[ - "expected_ssids"]) - # Delete the Passpoint profile. - self.get_configured_passpoint_and_delete() - wutils.wait_for_disconnect(self.dut) - - - """Tests""" - - @test_tracker_info(uuid="b0bc0153-77bb-4594-8f19-cea2c6bd2f43") - def test_add_passpoint_network(self): - """Add a Passpoint network and verify device connects to it. - - Steps: - 1. Install a Passpoint Profile. - 2. Verify the device connects to the required Passpoint SSID. - 3. Get the Passpoint configuration added above. - 4. Delete Passpoint configuration using its FQDN. - 5. Verify that we are disconnected from the Passpoint network. - - """ - passpoint_config = self.passpoint_networks[BOINGO] - self.install_passpoint_profile(passpoint_config) - ssid = passpoint_config[WifiEnums.SSID_KEY] - self.check_passpoint_connection(ssid) - self.get_configured_passpoint_and_delete() - wutils.wait_for_disconnect(self.dut) - - - @test_tracker_info(uuid="eb29d6e2-a755-4c9c-9e4e-63ea2277a64a") - def test_update_passpoint_network(self): - """Update a previous Passpoint network and verify device still connects - to it. - - 1. Install a Passpoint Profile. - 2. Verify the device connects to the required Passpoint SSID. - 3. Update the Passpoint Profile. - 4. Verify device is still connected to the Passpoint SSID. - 5. Get the Passpoint configuration added above. - 6. Delete Passpoint configuration using its FQDN. - - """ - passpoint_config = self.passpoint_networks[BOINGO] - self.install_passpoint_profile(passpoint_config) - ssid = passpoint_config[WifiEnums.SSID_KEY] - self.check_passpoint_connection(ssid) - - # Update passpoint configuration using the original profile because we - # do not have real profile with updated credentials to use. - self.install_passpoint_profile(passpoint_config) - - # Wait for a Disconnect event from the supplicant. - wutils.wait_for_disconnect(self.dut) - - # Now check if we are again connected with the updated profile. - self.check_passpoint_connection(ssid) - - self.get_configured_passpoint_and_delete() - wutils.wait_for_disconnect(self.dut) - - - @test_tracker_info(uuid="b6e8068d-faa1-49f2-b421-c60defaed5f0") - def test_add_delete_list_of_passpoint_network(self): - """Add multiple passpoint networks, list them and delete one by one. - - 1. Install Passpoint Profile A. - 2. Install Passpoint Profile B. - 3. Get all the Passpoint configurations added above and verify. - 6. Ensure all Passpoint configurations can be deleted. - - """ - for passpoint_config in self.passpoint_networks[:2]: - self.install_passpoint_profile(passpoint_config) - time.sleep(DEFAULT_TIMEOUT) - configs = self.dut.droid.getPasspointConfigs() - # It is length -1 because ATT profile will be handled separately - if not len(configs) or len(configs) != len(self.passpoint_networks[:2]): - raise signals.TestFailure("Failed to fetch some or all of the" - " configured passpoint networks.") - for config in configs: - if not wutils.delete_passpoint(self.dut, config): - raise signals.TestFailure("Failed to delete Passpoint" - " configuration with FQDN = %s" % - config) - - - @test_tracker_info(uuid="a53251be-7aaf-41fc-a5f3-63984269d224") - def test_delete_unknown_fqdn(self): - """Negative test to delete Passpoint profile using an unknown FQDN. - - 1. Pass an unknown FQDN for removal. - 2. Verify that it was not successful. - - """ - if wutils.delete_passpoint(self.dut, self.unknown_fqdn): - raise signals.TestFailure("Failed because an unknown FQDN" - " was successfully deleted.") - - - @test_tracker_info(uuid="bf03c03a-e649-4e2b-a557-1f791bd98951") - def test_passpoint_failover(self): - """Add a pair of passpoint networks and test failover when one of the" - profiles is removed. - - 1. Install a Passpoint Profile A and B. - 2. Verify device connects to a Passpoint network and get SSID. - 3. Delete the current Passpoint profile using its FQDN. - 4. Verify device fails over and connects to the other Passpoint SSID. - 5. Delete Passpoint configuration using its FQDN. - - """ - # Install both Passpoint profiles on the device. - passpoint_ssid = list() - for passpoint_config in self.passpoint_networks[:2]: - passpoint_ssid.append(passpoint_config[WifiEnums.SSID_KEY]) - self.install_passpoint_profile(passpoint_config) - time.sleep(DEFAULT_TIMEOUT) - - # Get the current network and the failover network. - wutils.wait_for_connect(self.dut) - current_passpoint = self.dut.droid.wifiGetConnectionInfo() - current_ssid = current_passpoint[WifiEnums.SSID_KEY] - if current_ssid not in passpoint_ssid: - raise signals.TestFailure("Device did not connect to any of the " - "configured Passpoint networks.") - - expected_ssid = self.passpoint_networks[0][WifiEnums.SSID_KEY] - if current_ssid == expected_ssid: - expected_ssid = self.passpoint_networks[1][WifiEnums.SSID_KEY] - - # Remove the current Passpoint profile. - for network in self.passpoint_networks[:2]: - if network[WifiEnums.SSID_KEY] == current_ssid: - if not wutils.delete_passpoint(self.dut, network["fqdn"]): - raise signals.TestFailure("Failed to delete Passpoint" - " configuration with FQDN = %s" % - network["fqdn"]) - # Verify device fails over and connects to the other passpoint network. - time.sleep(DEFAULT_TIMEOUT) - - current_passpoint = self.dut.droid.wifiGetConnectionInfo() - if current_passpoint[WifiEnums.SSID_KEY] != expected_ssid: - raise signals.TestFailure("Device did not failover to the %s" - " passpoint network" % expected_ssid) - - # Delete the remaining Passpoint profile. - self.get_configured_passpoint_and_delete() - wutils.wait_for_disconnect(self.dut) - - - def test_install_att_passpoint_profile(self): - """Add an AT&T Passpoint profile. - - It is used for only installing the profile for other tests. - """ - isFound = False - for passpoint_config in self.passpoint_networks: - if 'att' in passpoint_config['fqdn']: - isFound = True - self.install_passpoint_profile(passpoint_config) - break - if not isFound: - raise signals.TestFailure("cannot find ATT profile.") - - - @test_tracker_info(uuid="e3e826d2-7c39-4c37-ab3f-81992d5aa0e8") - def test_att_passpoint_network(self): - """Add a AT&T Passpoint network and verify device connects to it. - - Steps: - 1. Install a AT&T Passpoint Profile. - 2. Verify the device connects to the required Passpoint SSID. - 3. Get the Passpoint configuration added above. - 4. Delete Passpoint configuration using its FQDN. - 5. Verify that we are disconnected from the Passpoint network. - - """ - carriers = ["att"] - operator = get_operator_name(self.log, self.dut) - asserts.skip_if(operator not in carriers, - "Device %s does not have a ATT sim" % self.dut.model) - - passpoint_config = self.passpoint_networks[ATT] - self.install_passpoint_profile(passpoint_config) - ssid = passpoint_config[WifiEnums.SSID_KEY] - self.check_passpoint_connection(ssid) - self.get_configured_passpoint_and_delete() - wutils.wait_for_disconnect(self.dut) - - - @test_tracker_info(uuid="c85c81b2-7133-4635-8328-9498169ae802") - def test_start_subscription_provisioning(self): - self.start_subscription_provisioning(0) - - - @test_tracker_info(uuid="fd09a643-0d4b-45a9-881a-a771f9707ab1") - def test_start_subscription_provisioning_and_reset_wifi(self): - self.start_subscription_provisioning(RESET) - - - @test_tracker_info(uuid="f43ea759-673f-4567-aa11-da3bc2cabf08") - def test_start_subscription_provisioning_and_toggle_wifi(self): - self.start_subscription_provisioning(TOGGLE) diff --git a/acts/tests/google/wifi/WifiPerformancePreflightTest.py b/acts/tests/google/wifi/WifiPerformancePreflightTest.py deleted file mode 100644 index 35f29666da..0000000000 --- a/acts/tests/google/wifi/WifiPerformancePreflightTest.py +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2020 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the 'License'); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an 'AS IS' BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from acts import base_test -from acts.metrics.loggers.blackbox import BlackboxMappedMetricLogger -from acts.test_utils.wifi import wifi_performance_test_utils as wputils -from acts.test_utils.wifi import wifi_retail_ap as retail_ap - - -class WifiPerformancePreflightTest(base_test.BaseTestClass): - """Class for Wifi performance preflight tests. - - This class implements WiFi performance tests to perform before any other - test suite. Currently, the preflight checklist checks the wifi firmware and - config files, i.e., bdf files for any changes by retrieving their version - number and checksum. - """ - def __init__(self, controllers): - base_test.BaseTestClass.__init__(self, controllers) - self.testcase_metric_logger = ( - BlackboxMappedMetricLogger.for_test_case()) - - def setup_class(self): - self.dut = self.android_devices[-1] - # Initialize AP to ensure that tests can be run in later suites - req_params = ['RetailAccessPoints'] - opt_params = ['bdf', 'firmware'] - self.unpack_userparams(req_params, opt_params) - self.access_point = retail_ap.create(self.RetailAccessPoints)[0] - # Load BDF and firmware if needed - if hasattr(self, 'bdf'): - self.log.info('Pushing WiFi BDF to DUT.') - wputils.push_bdf(self.dut, self.bdf[0]) - if hasattr(self, 'firmware'): - self.log.info('Pushing WiFi firmware to DUT.') - wlanmdsp = [ - file for file in self.firmware if "wlanmdsp.mbn" in file - ][0] - data_msc = [file for file in self.firmware - if "Data.msc" in file][0] - wputils.push_firmware(self.dut, wlanmdsp, data_msc) - - for ad in self.android_devices: - ad.droid.wifiEnableVerboseLogging(1) - ad.adb.shell("wpa_cli -i wlan0 -p -g@android:wpa_wlan0 IFNAME=" - "wlan0 log_level EXCESSIVE") - - def test_wifi_sw_signature(self): - sw_signature = wputils.get_sw_signature(self.dut) - self.testcase_metric_logger.add_metric('bdf_signature', - sw_signature['bdf_signature']) - self.testcase_metric_logger.add_metric('fw_signature', - sw_signature['fw_signature']) - self.testcase_metric_logger.add_metric('serial_hash', - sw_signature['serial_hash']) - - def teardown_class(self): - # Teardown AP and release its lockfile - self.access_point.teardown()
\ No newline at end of file diff --git a/acts/tests/google/wifi/WifiPingTest.py b/acts/tests/google/wifi/WifiPingTest.py deleted file mode 100644 index cd9c52c39d..0000000000 --- a/acts/tests/google/wifi/WifiPingTest.py +++ /dev/null @@ -1,804 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the 'License'); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an 'AS IS' BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import collections -import itertools -import json -import logging -import os -import statistics -from acts import asserts -from acts import context -from acts import base_test -from acts import utils -from acts.controllers.utils_lib import ssh -from acts.metrics.loggers.blackbox import BlackboxMappedMetricLogger -from acts.test_utils.wifi import ota_chamber -from acts.test_utils.wifi import ota_sniffer -from acts.test_utils.wifi import wifi_performance_test_utils as wputils -from acts.test_utils.wifi import wifi_retail_ap as retail_ap -from acts.test_utils.wifi import wifi_test_utils as wutils -from functools import partial - - -class WifiPingTest(base_test.BaseTestClass): - """Class for ping-based Wifi performance tests. - - This class implements WiFi ping performance tests such as range and RTT. - The class setups up the AP in the desired configurations, configures - and connects the phone to the AP, and runs For an example config file to - run this test class see example_connectivity_performance_ap_sta.json. - """ - - TEST_TIMEOUT = 10 - RSSI_POLL_INTERVAL = 0.2 - SHORT_SLEEP = 1 - MED_SLEEP = 5 - MAX_CONSECUTIVE_ZEROS = 5 - DISCONNECTED_PING_RESULT = { - 'connected': 0, - 'rtt': [], - 'time_stamp': [], - 'ping_interarrivals': [], - 'packet_loss_percentage': 100 - } - - def __init__(self, controllers): - base_test.BaseTestClass.__init__(self, controllers) - self.testcase_metric_logger = ( - BlackboxMappedMetricLogger.for_test_case()) - self.testclass_metric_logger = ( - BlackboxMappedMetricLogger.for_test_class()) - self.publish_testcase_metrics = True - - def setup_class(self): - self.dut = self.android_devices[-1] - req_params = [ - 'ping_test_params', 'testbed_params', 'main_network', - 'RetailAccessPoints', 'RemoteServer' - ] - opt_params = ['OTASniffer'] - self.unpack_userparams(req_params, opt_params) - self.testclass_params = self.ping_test_params - self.num_atten = self.attenuators[0].instrument.num_atten - self.ping_server = ssh.connection.SshConnection( - ssh.settings.from_config(self.RemoteServer[0]['ssh_config'])) - self.access_point = retail_ap.create(self.RetailAccessPoints)[0] - if hasattr(self, - 'OTASniffer') and self.testbed_params['sniffer_enable']: - self.sniffer = ota_sniffer.create(self.OTASniffer)[0] - self.log.info('Access Point Configuration: {}'.format( - self.access_point.ap_settings)) - self.log_path = os.path.join(logging.log_path, 'results') - os.makedirs(self.log_path, exist_ok=True) - self.atten_dut_chain_map = {} - self.testclass_results = [] - - # Turn WiFi ON - if self.testclass_params.get('airplane_mode', 1): - self.log.info('Turning on airplane mode.') - asserts.assert_true(utils.force_airplane_mode(self.dut, True), - "Can not turn on airplane mode.") - wutils.wifi_toggle_state(self.dut, True) - - # Configure test retries - self.user_params['retry_tests'] = [self.__class__.__name__] - - def teardown_class(self): - # Turn WiFi OFF and reset AP - for dev in self.android_devices: - wutils.wifi_toggle_state(dev, False) - self.process_testclass_results() - - def setup_test(self): - self.retry_flag = False - - def teardown_test(self): - self.retry_flag = False - - def on_retry(self): - """Function to control test logic on retried tests. - - This function is automatically executed on tests that are being - retried. In this case the function resets wifi, toggles it off and on - and sets a retry_flag to enable further tweaking the test logic on - second attempts. - """ - self.retry_flag = True - for dev in self.android_devices: - wutils.reset_wifi(dev) - wutils.toggle_wifi_off_and_on(dev) - - def process_testclass_results(self): - """Saves all test results to enable comparison.""" - testclass_summary = {} - for test in self.testclass_results: - if 'range' in test['test_name']: - testclass_summary[test['test_name']] = test['range'] - # Save results - results_file_path = os.path.join(self.log_path, - 'testclass_summary.json') - with open(results_file_path, 'w') as results_file: - json.dump(testclass_summary, results_file, indent=4) - - def pass_fail_check_ping_rtt(self, result): - """Check the test result and decide if it passed or failed. - - The function computes RTT statistics and fails any tests in which the - tail of the ping latency results exceeds the threshold defined in the - configuration file. - - Args: - result: dict containing ping results and other meta data - """ - ignored_fraction = (self.testclass_params['rtt_ignored_interval'] / - self.testclass_params['rtt_ping_duration']) - sorted_rtt = [ - sorted(x['rtt'][round(ignored_fraction * len(x['rtt'])):]) - for x in result['ping_results'] - ] - disconnected = any([len(x) == 0 for x in sorted_rtt]) - if disconnected: - asserts.fail('Test failed. DUT disconnected at least once.') - - rtt_at_test_percentile = [ - x[int((1 - self.testclass_params['rtt_test_percentile'] / 100) * - len(x))] for x in sorted_rtt - ] - # Set blackbox metric - if self.publish_testcase_metrics: - self.testcase_metric_logger.add_metric('ping_rtt', - max(rtt_at_test_percentile)) - # Evaluate test pass/fail - rtt_failed = any([ - rtt > self.testclass_params['rtt_threshold'] * 1000 - for rtt in rtt_at_test_percentile - ]) - if rtt_failed: - #TODO: figure out how to cleanly exclude RTT tests from retry - asserts.explicit_pass( - 'Test failed. RTTs at test percentile = {}'.format( - rtt_at_test_percentile)) - else: - asserts.explicit_pass( - 'Test Passed. RTTs at test percentile = {}'.format( - rtt_at_test_percentile)) - - def pass_fail_check_ping_range(self, result): - """Check the test result and decide if it passed or failed. - - Checks whether the attenuation at which ping packet losses begin to - exceed the threshold matches the range derived from golden - rate-vs-range result files. The test fails is ping range is - range_gap_threshold worse than RvR range. - - Args: - result: dict containing ping results and meta data - """ - # Get target range - #rvr_range = self.get_range_from_rvr() - # Set Blackbox metric - if self.publish_testcase_metrics: - self.testcase_metric_logger.add_metric('ping_range', - result['range']) - # Evaluate test pass/fail - test_message = ('Attenuation at range is {}dB. ' - 'LLStats at Range: {}'.format( - result['range'], result['llstats_at_range'])) - if result['peak_throughput_pct'] < 95: - asserts.fail("(RESULT NOT RELIABLE) {}".format(test_message)) - else: - asserts.explicit_pass(test_message) - - def pass_fail_check(self, result): - if 'range' in result['testcase_params']['test_type']: - self.pass_fail_check_ping_range(result) - else: - self.pass_fail_check_ping_rtt(result) - - def process_ping_results(self, testcase_params, ping_range_result): - """Saves and plots ping results. - - Args: - ping_range_result: dict containing ping results and metadata - """ - # Compute range - ping_loss_over_att = [ - x['packet_loss_percentage'] - for x in ping_range_result['ping_results'] - ] - ping_loss_above_threshold = [ - x > self.testclass_params['range_ping_loss_threshold'] - for x in ping_loss_over_att - ] - for idx in range(len(ping_loss_above_threshold)): - if all(ping_loss_above_threshold[idx:]): - range_index = max(idx, 1) - 1 - break - else: - range_index = -1 - ping_range_result['atten_at_range'] = testcase_params['atten_range'][ - range_index] - ping_range_result['peak_throughput_pct'] = 100 - min( - ping_loss_over_att) - ping_range_result['range'] = (ping_range_result['atten_at_range'] + - ping_range_result['fixed_attenuation']) - ping_range_result['llstats_at_range'] = ( - 'TX MCS = {0} ({1:.1f}%). ' - 'RX MCS = {2} ({3:.1f}%)'.format( - ping_range_result['llstats'][range_index]['summary'] - ['common_tx_mcs'], ping_range_result['llstats'][range_index] - ['summary']['common_tx_mcs_freq'] * 100, - ping_range_result['llstats'][range_index]['summary'] - ['common_rx_mcs'], ping_range_result['llstats'][range_index] - ['summary']['common_rx_mcs_freq'] * 100)) - - # Save results - results_file_path = os.path.join( - self.log_path, '{}.json'.format(self.current_test_name)) - with open(results_file_path, 'w') as results_file: - json.dump(ping_range_result, results_file, indent=4) - - # Plot results - if 'range' not in self.current_test_name: - figure = wputils.BokehFigure( - self.current_test_name, - x_label='Timestamp (s)', - primary_y_label='Round Trip Time (ms)') - for idx, result in enumerate(ping_range_result['ping_results']): - if len(result['rtt']) > 1: - x_data = [ - t - result['time_stamp'][0] - for t in result['time_stamp'] - ] - figure.add_line( - x_data, result['rtt'], 'RTT @ {}dB'.format( - ping_range_result['attenuation'][idx])) - - output_file_path = os.path.join( - self.log_path, '{}.html'.format(self.current_test_name)) - figure.generate_figure(output_file_path) - - def run_ping_test(self, testcase_params): - """Main function to test ping. - - The function sets up the AP in the correct channel and mode - configuration and calls get_ping_stats while sweeping attenuation - - Args: - testcase_params: dict containing all test parameters - Returns: - test_result: dict containing ping results and other meta data - """ - # Prepare results dict - llstats_obj = wputils.LinkLayerStats( - self.dut, self.testclass_params.get('llstats_enabled', True)) - test_result = collections.OrderedDict() - test_result['testcase_params'] = testcase_params.copy() - test_result['test_name'] = self.current_test_name - test_result['ap_config'] = self.access_point.ap_settings.copy() - test_result['attenuation'] = testcase_params['atten_range'] - test_result['fixed_attenuation'] = self.testbed_params[ - 'fixed_attenuation'][str(testcase_params['channel'])] - test_result['rssi_results'] = [] - test_result['ping_results'] = [] - test_result['llstats'] = [] - # Setup sniffer - if self.testbed_params['sniffer_enable']: - self.sniffer.start_capture( - testcase_params['test_network'], - chan=int(testcase_params['channel']), - bw=int(testcase_params['mode'][3:]), - duration=testcase_params['ping_duration'] * - len(testcase_params['atten_range']) + self.TEST_TIMEOUT) - # Run ping and sweep attenuation as needed - zero_counter = 0 - for atten in testcase_params['atten_range']: - for attenuator in self.attenuators: - attenuator.set_atten(atten, strict=False) - rssi_future = wputils.get_connected_rssi_nb( - self.dut, - int(testcase_params['ping_duration'] / 2 / - self.RSSI_POLL_INTERVAL), self.RSSI_POLL_INTERVAL, - testcase_params['ping_duration'] / 2) - # Refresh link layer stats - llstats_obj.update_stats() - current_ping_stats = wputils.get_ping_stats( - self.ping_server, self.dut_ip, - testcase_params['ping_duration'], - testcase_params['ping_interval'], testcase_params['ping_size']) - current_rssi = rssi_future.result() - test_result['rssi_results'].append(current_rssi) - llstats_obj.update_stats() - curr_llstats = llstats_obj.llstats_incremental.copy() - test_result['llstats'].append(curr_llstats) - if current_ping_stats['connected']: - self.log.info( - 'Attenuation = {0}dB\tPacket Loss = {1}%\t' - 'Avg RTT = {2:.2f}ms\tRSSI = {3} [{4},{5}]\t'.format( - atten, current_ping_stats['packet_loss_percentage'], - statistics.mean(current_ping_stats['rtt']), - current_rssi['signal_poll_rssi']['mean'], - current_rssi['chain_0_rssi']['mean'], - current_rssi['chain_1_rssi']['mean'])) - if current_ping_stats['packet_loss_percentage'] == 100: - zero_counter = zero_counter + 1 - else: - zero_counter = 0 - else: - self.log.info( - 'Attenuation = {}dB. Disconnected.'.format(atten)) - zero_counter = zero_counter + 1 - test_result['ping_results'].append(current_ping_stats.as_dict()) - if zero_counter == self.MAX_CONSECUTIVE_ZEROS: - self.log.info('Ping loss stable at 100%. Stopping test now.') - for idx in range( - len(testcase_params['atten_range']) - - len(test_result['ping_results'])): - test_result['ping_results'].append( - self.DISCONNECTED_PING_RESULT) - break - if self.testbed_params['sniffer_enable']: - self.sniffer.stop_capture() - return test_result - - def setup_ap(self, testcase_params): - """Sets up the access point in the configuration required by the test. - - Args: - testcase_params: dict containing AP and other test params - """ - band = self.access_point.band_lookup_by_channel( - testcase_params['channel']) - if '2G' in band: - frequency = wutils.WifiEnums.channel_2G_to_freq[ - testcase_params['channel']] - else: - frequency = wutils.WifiEnums.channel_5G_to_freq[ - testcase_params['channel']] - if frequency in wutils.WifiEnums.DFS_5G_FREQUENCIES: - self.access_point.set_region(self.testbed_params['DFS_region']) - else: - self.access_point.set_region(self.testbed_params['default_region']) - self.access_point.set_channel(band, testcase_params['channel']) - self.access_point.set_bandwidth(band, testcase_params['mode']) - if 'low' in testcase_params['ap_power']: - self.log.info('Setting low AP power.') - self.access_point.set_power( - band, self.testclass_params['low_ap_tx_power']) - self.log.info('Access Point Configuration: {}'.format( - self.access_point.ap_settings)) - - def setup_dut(self, testcase_params): - """Sets up the DUT in the configuration required by the test. - - Args: - testcase_params: dict containing AP and other test params - """ - # Check battery level before test - if not wputils.health_check(self.dut, 10): - asserts.skip('Battery level too low. Skipping test.') - # Turn screen off to preserve battery - self.dut.go_to_sleep() - if wputils.validate_network(self.dut, - testcase_params['test_network']['SSID']): - self.log.info('Already connected to desired network') - else: - wutils.reset_wifi(self.dut) - wutils.set_wifi_country_code(self.dut, - self.testclass_params['country_code']) - testcase_params['test_network']['channel'] = testcase_params[ - 'channel'] - wutils.wifi_connect(self.dut, - testcase_params['test_network'], - num_of_tries=5, - check_connectivity=True) - self.dut_ip = self.dut.droid.connectivityGetIPv4Addresses('wlan0')[0] - if testcase_params['channel'] not in self.atten_dut_chain_map.keys(): - self.atten_dut_chain_map[testcase_params[ - 'channel']] = wputils.get_current_atten_dut_chain_map( - self.attenuators, self.dut, self.ping_server) - self.log.info("Current Attenuator-DUT Chain Map: {}".format( - self.atten_dut_chain_map[testcase_params['channel']])) - for idx, atten in enumerate(self.attenuators): - if self.atten_dut_chain_map[testcase_params['channel']][ - idx] == testcase_params['attenuated_chain']: - atten.offset = atten.instrument.max_atten - else: - atten.offset = 0 - - def setup_ping_test(self, testcase_params): - """Function that gets devices ready for the test. - - Args: - testcase_params: dict containing test-specific parameters - """ - # Configure AP - self.setup_ap(testcase_params) - # Set attenuator to 0 dB - for attenuator in self.attenuators: - attenuator.set_atten(0, strict=False) - # Reset, configure, and connect DUT - self.setup_dut(testcase_params) - - def get_range_start_atten(self, testcase_params): - """Gets the starting attenuation for this ping test. - - This function is used to get the starting attenuation for ping range - tests. This implementation returns the default starting attenuation, - however, defining this function enables a more involved configuration - for over-the-air test classes. - - Args: - testcase_params: dict containing all test params - """ - return self.testclass_params['range_atten_start'] - - def compile_test_params(self, testcase_params): - band = self.access_point.band_lookup_by_channel( - testcase_params['channel']) - testcase_params['test_network'] = self.main_network[band] - if testcase_params['chain_mask'] in ['0', '1']: - testcase_params['attenuated_chain'] = 'DUT-Chain-{}'.format( - 1 if testcase_params['chain_mask'] == '0' else 0) - else: - # Set attenuated chain to -1. Do not set to None as this will be - # compared to RF chain map which may include None - testcase_params['attenuated_chain'] = -1 - if testcase_params['test_type'] == 'test_ping_range': - testcase_params.update( - ping_interval=self.testclass_params['range_ping_interval'], - ping_duration=self.testclass_params['range_ping_duration'], - ping_size=self.testclass_params['ping_size'], - ) - elif testcase_params['test_type'] == 'test_fast_ping_rtt': - testcase_params.update( - ping_interval=self.testclass_params['rtt_ping_interval'] - ['fast'], - ping_duration=self.testclass_params['rtt_ping_duration'], - ping_size=self.testclass_params['ping_size'], - ) - elif testcase_params['test_type'] == 'test_slow_ping_rtt': - testcase_params.update( - ping_interval=self.testclass_params['rtt_ping_interval'] - ['slow'], - ping_duration=self.testclass_params['rtt_ping_duration'], - ping_size=self.testclass_params['ping_size']) - - if testcase_params['test_type'] == 'test_ping_range': - start_atten = self.get_range_start_atten(testcase_params) - num_atten_steps = int( - (self.testclass_params['range_atten_stop'] - start_atten) / - self.testclass_params['range_atten_step']) - testcase_params['atten_range'] = [ - start_atten + x * self.testclass_params['range_atten_step'] - for x in range(0, num_atten_steps) - ] - else: - testcase_params['atten_range'] = self.testclass_params[ - 'rtt_test_attenuation'] - return testcase_params - - def _test_ping(self, testcase_params): - """ Function that gets called for each range test case - - The function gets called in each range test case. It customizes the - range test based on the test name of the test that called it - - Args: - testcase_params: dict containing preliminary set of parameters - """ - # Compile test parameters from config and test name - testcase_params = self.compile_test_params(testcase_params) - # Run ping test - self.setup_ping_test(testcase_params) - ping_result = self.run_ping_test(testcase_params) - # Postprocess results - self.process_ping_results(testcase_params, ping_result) - self.testclass_results.append(ping_result) - self.pass_fail_check(ping_result) - - def generate_test_cases(self, ap_power, channels, modes, chain_mask, - test_types): - test_cases = [] - allowed_configs = { - 'VHT20': [ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 149, 153, - 157, 161 - ], - 'VHT40': [36, 44, 149, 157], - 'VHT80': [36, 149] - } - for channel, mode, chain, test_type in itertools.product( - channels, modes, chain_mask, test_types): - if channel not in allowed_configs[mode]: - continue - testcase_name = '{}_ch{}_{}_ch{}'.format(test_type, channel, mode, - chain) - testcase_params = collections.OrderedDict(test_type=test_type, - ap_power=ap_power, - channel=channel, - mode=mode, - chain_mask=chain) - setattr(self, testcase_name, - partial(self._test_ping, testcase_params)) - test_cases.append(testcase_name) - return test_cases - - -class WifiPing_TwoChain_Test(WifiPingTest): - def __init__(self, controllers): - super().__init__(controllers) - self.tests = self.generate_test_cases( - ap_power='standard', - channels=[1, 6, 11, 36, 40, 44, 48, 149, 153, 157, 161], - modes=['VHT20', 'VHT40', 'VHT80'], - test_types=[ - 'test_ping_range', 'test_fast_ping_rtt', 'test_slow_ping_rtt' - ], - chain_mask=['2x2']) - - -class WifiPing_PerChainRange_Test(WifiPingTest): - def __init__(self, controllers): - super().__init__(controllers) - self.tests = self.generate_test_cases( - ap_power='standard', - chain_mask=['0', '1', '2x2'], - channels=[1, 6, 11, 36, 40, 44, 48, 149, 153, 157, 161], - modes=['VHT20', 'VHT40', 'VHT80'], - test_types=['test_ping_range']) - - -class WifiPing_LowPowerAP_Test(WifiPingTest): - def __init__(self, controllers): - super().__init__(controllers) - self.tests = self.generate_test_cases( - ap_power='low_power', - chain_mask=['0', '1', '2x2'], - channels=[1, 6, 11, 36, 40, 44, 48, 149, 153, 157, 161], - modes=['VHT20', 'VHT40', 'VHT80'], - test_types=['test_ping_range']) - - -# Over-the air version of ping tests -class WifiOtaPingTest(WifiPingTest): - """Class to test over-the-air ping - - This class tests WiFi ping performance in an OTA chamber. It enables - setting turntable orientation and other chamber parameters to study - performance in varying channel conditions - """ - def __init__(self, controllers): - base_test.BaseTestClass.__init__(self, controllers) - self.testcase_metric_logger = ( - BlackboxMappedMetricLogger.for_test_case()) - self.testclass_metric_logger = ( - BlackboxMappedMetricLogger.for_test_class()) - self.publish_testcase_metrics = False - - def setup_class(self): - WifiPingTest.setup_class(self) - self.ota_chamber = ota_chamber.create( - self.user_params['OTAChamber'])[0] - - def teardown_class(self): - WifiPingTest.teardown_class(self) - self.process_testclass_results() - self.ota_chamber.reset_chamber() - - def process_testclass_results(self): - """Saves all test results to enable comparison.""" - WifiPingTest.process_testclass_results(self) - - range_vs_angle = collections.OrderedDict() - for test in self.testclass_results: - curr_params = test['testcase_params'] - curr_config = curr_params['channel'] - if curr_config in range_vs_angle: - if curr_params['position'] not in range_vs_angle[curr_config][ - 'position']: - range_vs_angle[curr_config]['position'].append( - curr_params['position']) - range_vs_angle[curr_config]['range'].append(test['range']) - range_vs_angle[curr_config]['llstats_at_range'].append( - test['llstats_at_range']) - else: - range_vs_angle[curr_config]['range'][-1] = test['range'] - range_vs_angle[curr_config]['llstats_at_range'][-1] = test[ - 'llstats_at_range'] - else: - range_vs_angle[curr_config] = { - 'position': [curr_params['position']], - 'range': [test['range']], - 'llstats_at_range': [test['llstats_at_range']] - } - chamber_mode = self.testclass_results[0]['testcase_params'][ - 'chamber_mode'] - if chamber_mode == 'orientation': - x_label = 'Angle (deg)' - elif chamber_mode == 'stepped stirrers': - x_label = 'Position Index' - figure = wputils.BokehFigure( - title='Range vs. Position', - x_label=x_label, - primary_y_label='Range (dB)', - ) - for channel, channel_data in range_vs_angle.items(): - figure.add_line(x_data=channel_data['position'], - y_data=channel_data['range'], - hover_text=channel_data['llstats_at_range'], - legend='Channel {}'.format(channel)) - average_range = sum(channel_data['range']) / len( - channel_data['range']) - self.log.info('Average range for Channel {} is: {}dB'.format( - channel, average_range)) - metric_name = 'ota_summary_ch{}.avg_range'.format(channel) - self.testclass_metric_logger.add_metric(metric_name, average_range) - current_context = context.get_current_context().get_full_output_path() - plot_file_path = os.path.join(current_context, 'results.html') - figure.generate_figure(plot_file_path) - - # Save results - results_file_path = os.path.join(current_context, - 'testclass_summary.json') - with open(results_file_path, 'w') as results_file: - json.dump(range_vs_angle, results_file, indent=4) - - def setup_ping_test(self, testcase_params): - WifiPingTest.setup_ping_test(self, testcase_params) - # Setup turntable - if testcase_params['chamber_mode'] == 'orientation': - self.ota_chamber.set_orientation(testcase_params['position']) - elif testcase_params['chamber_mode'] == 'stepped stirrers': - self.ota_chamber.step_stirrers(testcase_params['total_positions']) - - def extract_test_id(self, testcase_params, id_fields): - test_id = collections.OrderedDict( - (param, testcase_params[param]) for param in id_fields) - return test_id - - def get_range_start_atten(self, testcase_params): - """Gets the starting attenuation for this ping test. - - The function gets the starting attenuation by checking whether a test - at the same configuration has executed. If so it sets the starting - point a configurable number of dBs below the reference test. - - Returns: - start_atten: starting attenuation for current test - """ - # If the test is being retried, start from the beginning - if self.retry_flag: - self.log.info('Retry flag set. Setting attenuation to minimum.') - return self.testclass_params['range_atten_start'] - # Get the current and reference test config. The reference test is the - # one performed at the current MCS+1 - ref_test_params = self.extract_test_id(testcase_params, - ['channel', 'mode']) - # Check if reference test has been run and set attenuation accordingly - previous_params = [ - self.extract_test_id(result['testcase_params'], - ['channel', 'mode']) - for result in self.testclass_results - ] - try: - ref_index = previous_params[::-1].index(ref_test_params) - ref_index = len(previous_params) - 1 - ref_index - start_atten = self.testclass_results[ref_index][ - 'atten_at_range'] - ( - self.testclass_params['adjacent_range_test_gap']) - except ValueError: - self.log.info( - 'Reference test not found. Starting from {} dB'.format( - self.testclass_params['range_atten_start'])) - start_atten = self.testclass_params['range_atten_start'] - return start_atten - - def generate_test_cases(self, ap_power, channels, modes, chamber_mode, - positions): - test_cases = [] - allowed_configs = { - 'VHT20': [ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 149, 153, - 157, 161 - ], - 'VHT40': [36, 44, 149, 157], - 'VHT80': [36, 149] - } - for channel, mode, position in itertools.product( - channels, modes, positions): - if channel not in allowed_configs[mode]: - continue - testcase_name = 'test_ping_range_ch{}_{}_pos{}'.format( - channel, mode, position) - testcase_params = collections.OrderedDict( - test_type='test_ping_range', - ap_power=ap_power, - channel=channel, - mode=mode, - chain_mask='2x2', - chamber_mode=chamber_mode, - total_positions=len(positions), - position=position) - setattr(self, testcase_name, - partial(self._test_ping, testcase_params)) - test_cases.append(testcase_name) - return test_cases - - -class WifiOtaPing_TenDegree_Test(WifiOtaPingTest): - def __init__(self, controllers): - WifiOtaPingTest.__init__(self, controllers) - self.tests = self.generate_test_cases(ap_power='standard', - channels=[6, 36, 149], - modes=['VHT20'], - chamber_mode='orientation', - positions=list(range(0, 360, - 10))) - - -class WifiOtaPing_45Degree_Test(WifiOtaPingTest): - def __init__(self, controllers): - WifiOtaPingTest.__init__(self, controllers) - self.tests = self.generate_test_cases( - ap_power='standard', - channels=[1, 6, 11, 36, 40, 44, 48, 149, 153, 157, 161], - modes=['VHT20'], - chamber_mode='orientation', - positions=list(range(0, 360, 45))) - - -class WifiOtaPing_SteppedStirrers_Test(WifiOtaPingTest): - def __init__(self, controllers): - WifiOtaPingTest.__init__(self, controllers) - self.tests = self.generate_test_cases(ap_power='standard', - channels=[6, 36, 149], - modes=['VHT20'], - chamber_mode='stepped stirrers', - positions=list(range(100))) - - -class WifiOtaPing_LowPowerAP_TenDegree_Test(WifiOtaPingTest): - def __init__(self, controllers): - WifiOtaPingTest.__init__(self, controllers) - self.tests = self.generate_test_cases(ap_power='low_power', - channels=[6, 36, 149], - modes=['VHT20'], - chamber_mode='orientation', - positions=list(range(0, 360, - 10))) - - -class WifiOtaPing_LowPowerAP_45Degree_Test(WifiOtaPingTest): - def __init__(self, controllers): - WifiOtaPingTest.__init__(self, controllers) - self.tests = self.generate_test_cases( - ap_power='low_power', - channels=[1, 6, 11, 36, 40, 44, 48, 149, 153, 157, 161], - modes=['VHT20'], - chamber_mode='orientation', - positions=list(range(0, 360, 45))) - - -class WifiOtaPing_LowPowerAP_SteppedStirrers_Test(WifiOtaPingTest): - def __init__(self, controllers): - WifiOtaPingTest.__init__(self, controllers) - self.tests = self.generate_test_cases(ap_power='low_power', - channels=[6, 36, 149], - modes=['VHT20'], - chamber_mode='stepped stirrers', - positions=list(range(100))) diff --git a/acts/tests/google/wifi/WifiPnoTest.py b/acts/tests/google/wifi/WifiPnoTest.py deleted file mode 100644 index 4bfa1d7c49..0000000000 --- a/acts/tests/google/wifi/WifiPnoTest.py +++ /dev/null @@ -1,195 +0,0 @@ -# -# Copyright 2014 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import time - -from acts import asserts -from acts import base_test -from acts.test_decorators import test_tracker_info -import acts.test_utils.wifi.wifi_test_utils as wutils -from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest - -WifiEnums = wutils.WifiEnums -MAX_ATTN = 95 - -class WifiPnoTest(WifiBaseTest): - - def setup_class(self): - super().setup_class() - - self.dut = self.android_devices[0] - wutils.wifi_test_device_init(self.dut) - req_params = ["attn_vals", "pno_interval"] - opt_param = ["reference_networks"] - self.unpack_userparams( - req_param_names=req_params, opt_param_names=opt_param) - - if "AccessPoint" in self.user_params: - self.legacy_configure_ap_and_start() - - self.pno_network_a = self.reference_networks[0]['2g'] - self.pno_network_b = self.reference_networks[0]['5g'] - self.attn_a = self.attenuators[0] - self.attn_b = self.attenuators[1] - # Disable second AP's networks, so that it does not interfere during PNO - self.attenuators[2].set_atten(MAX_ATTN) - self.attenuators[3].set_atten(MAX_ATTN) - self.set_attns("default") - - def setup_test(self): - self.dut.droid.wifiStartTrackingStateChange() - self.dut.droid.wakeLockRelease() - self.dut.droid.goToSleepNow() - wutils.reset_wifi(self.dut) - self.dut.ed.clear_all_events() - - def teardown_test(self): - self.dut.droid.wifiStopTrackingStateChange() - wutils.reset_wifi(self.dut) - self.dut.ed.clear_all_events() - self.set_attns("default") - - def on_fail(self, test_name, begin_time): - self.dut.take_bug_report(test_name, begin_time) - self.dut.cat_adb_log(test_name, begin_time) - - def teardown_class(self): - if "AccessPoint" in self.user_params: - del self.user_params["reference_networks"] - del self.user_params["open_network"] - - """Helper Functions""" - - def set_attns(self, attn_val_name): - """Sets attenuation values on attenuators used in this test. - - 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.attn_a.set_atten(self.attn_vals[attn_val_name][0]) - self.attn_b.set_atten(self.attn_vals[attn_val_name][1]) - 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", - 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) - try: - self.log.info("Connected to %s network after PNO interval" - % 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", - expected_ssid) - finally: - pass - - def add_and_enable_dummy_networks(self, num_networks): - """Add some dummy networks to the device and enable them. - - Args: - num_networks: Number of networks to add. - """ - ssid_name_base = "pno_dummy_network_" - for i in range(0, num_networks): - network = {} - network[WifiEnums.SSID_KEY] = ssid_name_base + str(i) - network[WifiEnums.PWD_KEY] = "pno_dummy" - self.add_network_and_enable(network) - - def add_network_and_enable(self, network): - """Add a network and enable it. - - Args: - network : Network details for the network to be added. - - """ - ret = self.dut.droid.wifiAddNetwork(network) - asserts.assert_true(ret != -1, "Add network %r failed" % network) - self.dut.droid.wifiEnableNetwork(ret, 0) - - - """ Tests Begin """ - - @test_tracker_info(uuid="33d3cae4-5fa7-4e90-b9e2-5d3747bba64c") - def test_simple_pno_connection_to_2g(self): - """Test PNO triggered autoconnect to a network. - - Steps: - 1. Switch off the screen on the device. - 2. Save 2 valid network configurations (a & b) in the device. - 3. Attenuate 5Ghz network and wait for a few seconds to trigger PNO. - 4. Check the device connected to 2Ghz network automatically. - """ - self.add_network_and_enable(self.pno_network_a) - self.add_network_and_enable(self.pno_network_b) - self.trigger_pno_and_assert_connect("a_on_b_off", self.pno_network_a) - - @test_tracker_info(uuid="39b945a1-830f-4f11-9e6a-9e9641066a96") - def test_simple_pno_connection_to_5g(self): - """Test PNO triggered autoconnect to a network. - - Steps: - 1. Switch off the screen on the device. - 2. Save 2 valid network configurations (a & b) in the device. - 3. Attenuate 2Ghz network and wait for a few seconds to trigger PNO. - 4. Check the device connected to 5Ghz network automatically. - - """ - self.add_network_and_enable(self.pno_network_a) - self.add_network_and_enable(self.pno_network_b) - self.trigger_pno_and_assert_connect("b_on_a_off", self.pno_network_b) - - @test_tracker_info(uuid="844b15be-ff45-4b09-a11b-0b2b4bb13b22") - def test_pno_connection_with_multiple_saved_networks(self): - """Test PNO triggered autoconnect to a network when there are more - than 16 networks saved in the device. - - 16 is the max list size of PNO watch list for most devices. The device - should automatically pick the 16 latest added networks in the list. - So add 16 dummy networks and then add 2 valid networks. - - Steps: - 1. Save 16 dummy network configurations in the device. - 2. Run the simple pno test. - """ - self.add_and_enable_dummy_networks(16) - self.add_network_and_enable(self.pno_network_a) - self.add_network_and_enable(self.pno_network_b) - # Force single scan so that both networks become preferred before PNO. - wutils.start_wifi_connection_scan_and_return_status(self.dut) - time.sleep(10) - self.trigger_pno_and_assert_connect("a_on_b_off", self.pno_network_a) - - """ Tests End """ diff --git a/acts/tests/google/wifi/WifiPreFlightTest.py b/acts/tests/google/wifi/WifiPreFlightTest.py deleted file mode 100644 index 14a4190c85..0000000000 --- a/acts/tests/google/wifi/WifiPreFlightTest.py +++ /dev/null @@ -1,180 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import copy -import pprint -import time - -import acts.base_test -import acts.test_utils.wifi.wifi_test_utils as wutils - -from acts import asserts -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest - -SCAN_TIME = 30 -WAIT_TIME = 2 - - -class WifiPreFlightTest(WifiBaseTest): - """ Pre-flight checks for Wifi tests. - - Test Bed Requirement: - * One Android device - * 4 reference networks - two 2G and two 5G networks - * Attenuators to attenuate each reference network - - Tests: - * Check if reference networks show up in wifi scan - * Check if attenuators attenuate the correct network - """ - - def setup_class(self): - super().setup_class() - self.WIFI_2G = "2g" - self.WIFI_5G = "5g" - self.PASSWORD = "password" - self.MIN_SIGNAL_LEVEL = -45 - - self.dut = self.android_devices[0] - wutils.wifi_test_device_init(self.dut) - wutils.wifi_toggle_state(self.dut, True) - - # Get reference networks as a list - opt_params = ["reference_networks"] - self.unpack_userparams(opt_param_names=opt_params) - - if "AccessPoint" in self.user_params: - self.legacy_configure_ap_and_start(ap_count=2) - networks = [] - for ref_net in self.reference_networks: - networks.append(ref_net[self.WIFI_2G]) - networks.append(ref_net[self.WIFI_5G]) - self.reference_networks = networks - asserts.assert_true( - len(self.reference_networks) == 4, - "Need at least 4 reference network with psk.") - - def teardown_class(self): - wutils.reset_wifi(self.dut) - for a in self.attenuators: - a.set_atten(0) - if "AccessPoint" in self.user_params: - del self.user_params["reference_networks"] - del self.user_params["open_network"] - - """ Helper functions """ - def _find_reference_networks_no_attn(self): - """ Verify that when ATTN set to 0, all reference networks - show up in the scanned results - - Args: - 1. List of reference networks - - Returns: - 1. List of networks not found. Empty if all reference - networks are found - """ - found_networks = copy.deepcopy(self.target_networks) - start_time = time.time() - while(time.time() < start_time + SCAN_TIME): - if not found_networks: - break - time.sleep(WAIT_TIME) - scanned_networks = self.dut.droid.wifiGetScanResults() - self.log.info("SCANNED RESULTS %s" % scanned_networks) - for net in self.target_networks: - if net in found_networks: - result = wutils.match_networks(net, scanned_networks) - if result and result[0]['level'] > self.MIN_SIGNAL_LEVEL: - found_networks.remove(net) - elif result: - self.log.warn("Signal strength for %s is low: %sdBm" - % (net, result[0]['level'])) - return found_networks - - def _find_network_after_setting_attn(self, target_network): - """ Find network after setting attenuation - - Args: - 1. target_network to find in the scanned_results - - Returns: - 1. True if - a. if max_attn is set and target_network not found - 2. False if not - """ - start_time = time.time() - while(time.time() < start_time + SCAN_TIME): - time.sleep(WAIT_TIME) - scanned_networks = self.dut.droid.wifiGetScanResults() - self.log.info("SCANNED RESULTS %s" % scanned_networks) - result = wutils.match_networks(target_network, scanned_networks) - if not result: - return True - return False - - """ Tests """ - def test_attenuators(self): - """ Test if attenuating a channel, disables the correct - reference network - - Reference networks for each testbed should match - attenuators as follows - - wh_ap1_2g - channel 1 - wh_ap1_5g - channel 2 - wh_ap2_2g - channel 3 - wh_ap2_5g - channel 4 - - Steps: - 1. Set attenuation on each channel to 95 - 2. Verify that the corresponding network does not show - up in the scanned results - """ - # Set attenuation to 0 and verify reference - # networks show up in the scanned results - self.log.info("Verify if all reference networks show with " - "attenuation set to 0") - if getattr(self, "attenuators", []): - for a in self.attenuators: - a.set_atten(0) - self.target_networks = [] - for ref_net in self.reference_networks: - self.target_networks.append( {'BSSID': ref_net['bssid']} ) - result = self._find_reference_networks_no_attn() - asserts.assert_true(not result, - "Did not find or signal strength too low " - "for the following reference networks\n%s\n" % result) - - # attenuate 1 channel at a time and find the network - self.log.info("Verify if attenuation channel matches with " - "correct reference network") - found_networks = [] - for i in range(len(self.attenuators)): - target_network = {} - target_network['BSSID'] = self.reference_networks[i]['bssid'] - - # set the attn to max and verify target network is not found - self.attenuators[i].set_atten(95) - result = self._find_network_after_setting_attn(target_network) - if result: - target_network['ATTN'] = i - found_networks.append(target_network) - - asserts.assert_true(not found_networks, - "Attenuators did not match the networks\n %s\n" - % pprint.pformat(found_networks)) diff --git a/acts/tests/google/wifi/WifiRoamingPerformanceTest.py b/acts/tests/google/wifi/WifiRoamingPerformanceTest.py deleted file mode 100644 index bfc96d5656..0000000000 --- a/acts/tests/google/wifi/WifiRoamingPerformanceTest.py +++ /dev/null @@ -1,779 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2019 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import collections -import json -import math -import os -import time -from acts import asserts -from acts import base_test -from acts import context -from acts import utils -from acts.controllers import iperf_server as ipf -from acts.controllers.utils_lib import ssh -from acts.metrics.loggers.blackbox import BlackboxMappedMetricLogger -from acts.test_utils.wifi import wifi_performance_test_utils as wputils -from acts.test_utils.wifi import wifi_retail_ap as retail_ap -from acts.test_utils.wifi import wifi_test_utils as wutils - -SHORT_SLEEP = 1 -MED_SLEEP = 5 -TRAFFIC_GAP_THRESH = 0.5 -IPERF_INTERVAL = 0.25 - - -class WifiRoamingPerformanceTest(base_test.BaseTestClass): - """Class for ping-based Wifi performance tests. - - This class implements WiFi ping performance tests such as range and RTT. - The class setups up the AP in the desired configurations, configures - and connects the phone to the AP, and runs For an example config file to - run this test class see example_connectivity_performance_ap_sta.json. - """ - def __init__(self, controllers): - base_test.BaseTestClass.__init__(self, controllers) - self.testcase_metric_logger = ( - BlackboxMappedMetricLogger.for_test_case()) - self.testclass_metric_logger = ( - BlackboxMappedMetricLogger.for_test_class()) - self.publish_testcase_metrics = True - - def setup_class(self): - """Initializes common test hardware and parameters. - - This function initializes hardwares and compiles parameters that are - common to all tests in this class. - """ - self.dut = self.android_devices[-1] - req_params = [ - 'RetailAccessPoints', 'roaming_test_params', 'testbed_params' - ] - opt_params = ['main_network', 'RemoteServer'] - self.unpack_userparams(req_params, opt_params) - self.testclass_params = self.roaming_test_params - self.num_atten = self.attenuators[0].instrument.num_atten - self.remote_server = ssh.connection.SshConnection( - ssh.settings.from_config(self.RemoteServer[0]['ssh_config'])) - self.remote_server.setup_master_ssh() - self.iperf_server = self.iperf_servers[0] - self.iperf_client = self.iperf_clients[0] - self.access_point = retail_ap.create(self.RetailAccessPoints)[0] - self.log.info('Access Point Configuration: {}'.format( - self.access_point.ap_settings)) - - # Get RF connection map - self.log.info("Getting RF connection map.") - wutils.wifi_toggle_state(self.dut, True) - self.rf_map_by_network, self.rf_map_by_atten = ( - wputils.get_full_rf_connection_map(self.attenuators, self.dut, - self.remote_server, - self.main_network)) - self.log.info("RF Map (by Network): {}".format(self.rf_map_by_network)) - self.log.info("RF Map (by Atten): {}".format(self.rf_map_by_atten)) - - #Turn WiFi ON - if self.testclass_params.get('airplane_mode', 1): - self.log.info('Turning on airplane mode.') - asserts.assert_true(utils.force_airplane_mode(self.dut, True), - "Can not turn on airplane mode.") - wutils.wifi_toggle_state(self.dut, True) - - def pass_fail_traffic_continuity(self, result): - """Pass fail check for traffic continuity - - Currently, the function only reports test results and implicitly passes - the test. A pass fail criterion is current being researched. - - Args: - result: dict containing test results - """ - self.log.info('Detected {} roam transitions:'.format( - len(result['roam_transitions']))) - for event in result['roam_transitions']: - self.log.info('Roam: {} -> {})'.format(event[0], event[1])) - self.log.info('Roam transition statistics: {}'.format( - result['roam_counts'])) - - formatted_traffic_gaps = [ - round(gap, 2) for gap in result['traffic_disruption'] - ] - self.log.info('Detected {} traffic gaps of duration: {}'.format( - len(result['traffic_disruption']), formatted_traffic_gaps)) - - if result['total_roams'] > 0: - disruption_percentage = (len(result['traffic_disruption']) / - result['total_roams']) * 100 - max_disruption = max(result['traffic_disruption']) - else: - disruption_percentage = 0 - max_disruption = 0 - self.testcase_metric_logger.add_metric('disruption_percentage', - disruption_percentage) - self.testcase_metric_logger.add_metric('max_disruption', - max_disruption) - - if disruption_percentage == 0: - asserts.explicit_pass('Test passed. No traffic disruptions found.') - elif max_disruption > self.testclass_params[ - 'traffic_disruption_threshold']: - asserts.fail('Test failed. Disruption Percentage = {}%. ' - 'Max traffic disruption: {}s.'.format( - disruption_percentage, max_disruption)) - else: - asserts.explicit_pass('Test failed. Disruption Percentage = {}%. ' - 'Max traffic disruption: {}s.'.format( - disruption_percentage, max_disruption)) - - def pass_fail_roaming_consistency(self, results_dict): - """Function to evaluate roaming consistency results. - - The function looks for the roams recorded in multiple runs of the same - attenuation waveform and checks that the DUT reliably roams to the - same network - - Args: - results_dict: dict containing consistency test results - """ - test_fail = False - for secondary_atten, roam_stats in results_dict['roam_stats'].items(): - total_roams = sum(list(roam_stats.values())) - common_roam = max(roam_stats.keys(), key=(lambda k: roam_stats[k])) - common_roam_frequency = roam_stats[common_roam] / total_roams - self.log.info( - '{}dB secondary atten. Most common roam: {}. Frequency: {}'. - format(secondary_atten, common_roam, common_roam_frequency)) - if common_roam_frequency < self.testclass_params[ - 'consistency_threshold']: - test_fail = True - self.log.info('Unstable Roams at {}dB secondary att'.format( - secondary_atten)) - self.testcase_metric_logger.add_metric('common_roam_frequency', - common_roam_frequency) - if test_fail: - asserts.fail('Incosistent roaming detected.') - else: - asserts.explicit_pass('Consistent roaming at all levels.') - - def process_traffic_continuity_results(self, testcase_params, result): - """Function to process traffic results. - - The function looks for traffic gaps during a roaming test - - Args: - testcase_params: dict containing all test results and meta data - results_dict: dict containing consistency test results - """ - self.detect_roam_events(result) - current_context = context.get_current_context().get_full_output_path() - plot_file_path = os.path.join(current_context, - self.current_test_name + '.html') - - if 'ping' in self.current_test_name: - self.detect_ping_gaps(result) - self.plot_ping_result(testcase_params, - result, - output_file_path=plot_file_path) - elif 'iperf' in self.current_test_name: - self.detect_iperf_gaps(result) - self.plot_iperf_result(testcase_params, - result, - output_file_path=plot_file_path) - - results_file_path = os.path.join(current_context, - self.current_test_name + '.json') - with open(results_file_path, 'w') as results_file: - json.dump(wputils.serialize_dict(result), results_file, indent=4) - - def process_consistency_results(self, testcase_params, results_dict): - """Function to process roaming consistency results. - - The function looks compiles the test of roams recorded in consistency - tests and plots results for easy visualization. - - Args: - testcase_params: dict containing all test results and meta data - results_dict: dict containing consistency test results - """ - # make figure placeholder and get relevant functions - if 'ping' in self.current_test_name: - detect_gaps = self.detect_ping_gaps - plot_result = self.plot_ping_result - primary_y_axis = 'RTT (ms)' - elif 'iperf' in self.current_test_name: - detect_gaps = self.detect_iperf_gaps - plot_result = self.plot_iperf_result - primary_y_axis = 'Throughput (Mbps)' - # loop over results - roam_stats = collections.OrderedDict() - current_context = context.get_current_context().get_full_output_path() - for secondary_atten, results_list in results_dict.items(): - figure = wputils.BokehFigure(title=self.current_test_name, - x_label='Time (ms)', - primary_y_label=primary_y_axis, - secondary_y_label='RSSI (dBm)') - roam_stats[secondary_atten] = collections.OrderedDict() - for result in results_list: - self.detect_roam_events(result) - for roam_transition, count in result['roam_counts'].items(): - roam_stats[secondary_atten][ - roam_transition] = roam_stats[secondary_atten].get( - roam_transition, 0) + count - detect_gaps(result) - plot_result(testcase_params, result, figure=figure) - # save plot - plot_file_name = (self.current_test_name + '_' + - str(secondary_atten) + '.html') - - plot_file_path = os.path.join(current_context, plot_file_name) - figure.save_figure(plot_file_path) - results_dict['roam_stats'] = roam_stats - - results_file_path = os.path.join(current_context, - self.current_test_name + '.json') - with open(results_file_path, 'w') as results_file: - json.dump(wputils.serialize_dict(result), results_file, indent=4) - - def detect_roam_events(self, result): - """Function to process roaming results. - - The function detects roams by looking at changes in BSSID and compiles - meta data about each roam, e.g., RSSI before and after a roam. The - function then calls the relevant method to process traffic results and - report traffic disruptions. - - Args: - testcase_params: dict containing AP and other test params - result: dict containing test results - """ - roam_events = [ - (idx, idx + 1) - for idx in range(len(result['rssi_result']['bssid']) - 1) - if result['rssi_result']['bssid'][idx] != result['rssi_result'] - ['bssid'][idx + 1] - ] - - def ignore_entry(vals): - for val in vals: - if val in {0} or math.isnan(val): - return True - return False - - for roam_idx, roam_event in enumerate(roam_events): - # Find true roam start by scanning earlier samples for valid data - while ignore_entry([ - result['rssi_result']['frequency'][roam_event[0]], - result['rssi_result']['signal_poll_rssi']['data'][ - roam_event[0]] - ]): - roam_event = (roam_event[0] - 1, roam_event[1]) - roam_events[roam_idx] = roam_event - # Find true roam end by scanning later samples for valid data - while ignore_entry([ - result['rssi_result']['frequency'][roam_event[1]], - result['rssi_result']['signal_poll_rssi']['data'][ - roam_event[1]] - ]): - roam_event = (roam_event[0], roam_event[1] + 1) - roam_events[roam_idx] = roam_event - - roam_events = list(set(roam_events)) - roam_events.sort(key=lambda event_tuple: event_tuple[1]) - roam_transitions = [] - roam_counts = {} - total_roams = 0 - for event in roam_events: - from_bssid = next( - key for key, value in self.main_network.items() - if value['BSSID'] == result['rssi_result']['bssid'][event[0]]) - to_bssid = next( - key for key, value in self.main_network.items() - if value['BSSID'] == result['rssi_result']['bssid'][event[1]]) - curr_bssid_transition = (from_bssid, to_bssid) - curr_roam_transition = ( - (from_bssid, - result['rssi_result']['signal_poll_rssi']['data'][event[0]]), - (to_bssid, - result['rssi_result']['signal_poll_rssi']['data'][event[1]])) - roam_transitions.append(curr_roam_transition) - roam_counts[curr_bssid_transition] = roam_counts.get( - curr_bssid_transition, 0) + 1 - total_roams = total_roams + 1 - result['roam_events'] = roam_events - result['roam_transitions'] = roam_transitions - result['roam_counts'] = roam_counts - result['total_roams'] = total_roams - - def detect_ping_gaps(self, result): - """Function to process ping results. - - The function looks for gaps in iperf traffic and reports them as - disruptions due to roams. - - Args: - result: dict containing test results - """ - traffic_disruption = [ - x for x in result['ping_result']['ping_interarrivals'] - if x > TRAFFIC_GAP_THRESH - ] - result['traffic_disruption'] = traffic_disruption - - def detect_iperf_gaps(self, result): - """Function to process iperf results. - - The function looks for gaps in iperf traffic and reports them as - disruptions due to roams. - - Args: - result: dict containing test results - """ - tput_thresholding = [tput < 1 for tput in result['throughput']] - window_size = int(TRAFFIC_GAP_THRESH / IPERF_INTERVAL) - tput_thresholding = [ - any(tput_thresholding[max(0, idx - window_size):idx]) - for idx in range(1, - len(tput_thresholding) + 1) - ] - - traffic_disruption = [] - current_disruption = 1 - window_size - for tput_low in tput_thresholding: - if tput_low: - current_disruption += 1 - elif current_disruption > window_size: - traffic_disruption.append(current_disruption * IPERF_INTERVAL) - current_disruption = 1 - window_size - else: - current_disruption = 1 - window_size - result['traffic_disruption'] = traffic_disruption - - def plot_ping_result(self, - testcase_params, - result, - figure=None, - output_file_path=None): - """Function to plot ping results. - - The function plots ping RTTs along with RSSI over time during a roaming - test. - - Args: - testcase_params: dict containing all test params - result: dict containing test results - figure: optional bokeh figure object to add current plot to - output_file_path: optional path to output file - """ - if not figure: - figure = wputils.BokehFigure(title=self.current_test_name, - x_label='Time (ms)', - primary_y_label='RTT (ms)', - secondary_y_label='RSSI (dBm)') - figure.add_line(x_data=result['ping_result']['time_stamp'], - y_data=result['ping_result']['rtt'], - legend='Ping RTT', - width=1) - figure.add_line( - x_data=result['rssi_result']['time_stamp'], - y_data=result['rssi_result']['signal_poll_rssi']['data'], - legend='RSSI', - y_axis='secondary') - figure.generate_figure(output_file_path) - - def plot_iperf_result(self, - testcase_params, - result, - figure=None, - output_file_path=None): - """Function to plot iperf results. - - The function plots iperf throughput and RSSI over time during a roaming - test. - - Args: - testcase_params: dict containing all test params - result: dict containing test results - figure: optional bokeh figure object to add current plot to - output_file_path: optional path to output file - """ - if not figure: - figure = wputils.BokehFigure(title=self.current_test_name, - x_label='Time (s)', - primary_y_label='Throughput (Mbps)', - secondary_y_label='RSSI (dBm)') - iperf_time_stamps = [ - idx * IPERF_INTERVAL for idx in range(len(result['throughput'])) - ] - figure.add_line(iperf_time_stamps, - result['throughput'], - 'Throughput', - width=1) - figure.add_line(result['rssi_result']['time_stamp'], - result['rssi_result']['signal_poll_rssi']['data'], - 'RSSI', - y_axis='secondary') - - figure.generate_figure(output_file_path) - - def setup_ap(self, testcase_params): - """Sets up the AP and attenuator to the test configuration. - - Args: - testcase_params: dict containing AP and other test params - """ - (primary_net_id, - primary_net_config) = next(net for net in self.main_network.items() - if net[1]['roaming_label'] == 'primary') - for idx, atten in enumerate(self.attenuators): - nets_on_port = [ - item["network"] for item in self.rf_map_by_atten[idx] - ] - if primary_net_id in nets_on_port: - atten.set_atten(0) - else: - atten.set_atten(atten.instrument.max_atten) - - def setup_dut(self, testcase_params): - """Sets up the DUT in the configuration required by the test. - - Args: - testcase_params: dict containing AP and other test params - """ - # Check battery level before test - if not wputils.health_check(self.dut, 10): - asserts.skip('Battery level too low. Skipping test.') - wutils.reset_wifi(self.dut) - wutils.set_wifi_country_code(self.dut, - self.testclass_params['country_code']) - (primary_net_id, - primary_net_config) = next(net for net in self.main_network.items() - if net[1]['roaming_label'] == 'primary') - network = primary_net_config.copy() - network.pop('BSSID', None) - self.dut.droid.wifiSetEnableAutoJoinWhenAssociated(1) - wutils.wifi_connect(self.dut, - network, - num_of_tries=5, - check_connectivity=False) - self.dut.droid.wifiSetEnableAutoJoinWhenAssociated(1) - self.dut_ip = self.dut.droid.connectivityGetIPv4Addresses('wlan0')[0] - if testcase_params['screen_on']: - self.dut.wakeup_screen() - self.dut.droid.wakeLockAcquireBright() - time.sleep(MED_SLEEP) - - def setup_roaming_test(self, testcase_params): - """Function to set up roaming test.""" - self.setup_ap(testcase_params) - self.setup_dut(testcase_params) - - def run_ping_test(self, testcase_params): - """Main function for ping roaming tests. - - Args: - testcase_params: dict including all test params encoded in test - name - Returns: - dict containing all test results and meta data - """ - self.log.info('Starting ping test.') - ping_future = wputils.get_ping_stats_nb( - self.remote_server, self.dut_ip, - testcase_params['atten_waveforms']['length'], - testcase_params['ping_interval'], 64) - rssi_future = wputils.get_connected_rssi_nb( - self.dut, - int(testcase_params['atten_waveforms']['length'] / - testcase_params['rssi_polling_frequency']), - testcase_params['rssi_polling_frequency']) - self.run_attenuation_waveform(testcase_params) - return { - 'ping_result': ping_future.result().as_dict(), - 'rssi_result': rssi_future.result(), - 'ap_settings': self.access_point.ap_settings, - } - - def run_iperf_test(self, testcase_params): - """Main function for iperf roaming tests. - - Args: - testcase_params: dict including all test params encoded in test - name - Returns: - result: dict containing all test results and meta data - """ - self.log.info('Starting iperf test.') - self.iperf_server.start(extra_args='-i {}'.format(IPERF_INTERVAL)) - self.dut_ip = self.dut.droid.connectivityGetIPv4Addresses('wlan0')[0] - if isinstance(self.iperf_server, ipf.IPerfServerOverAdb): - iperf_server_address = self.dut_ip - else: - iperf_server_address = wputils.get_server_address( - self.remote_server, self.dut_ip, '255.255.255.0') - iperf_args = '-i {} -t {} -J'.format( - IPERF_INTERVAL, testcase_params['atten_waveforms']['length']) - if not isinstance(self.iperf_server, ipf.IPerfServerOverAdb): - iperf_args = iperf_args + ' -R' - iperf_future = wputils.start_iperf_client_nb( - self.iperf_client, iperf_server_address, iperf_args, 0, - testcase_params['atten_waveforms']['length'] + MED_SLEEP) - rssi_future = wputils.get_connected_rssi_nb( - self.dut, - int(testcase_params['atten_waveforms']['length'] / - testcase_params['rssi_polling_frequency']), - testcase_params['rssi_polling_frequency']) - self.run_attenuation_waveform(testcase_params) - client_output_path = iperf_future.result() - server_output_path = self.iperf_server.stop() - if isinstance(self.iperf_server, ipf.IPerfServerOverAdb): - iperf_file = server_output_path - else: - iperf_file = client_output_path - iperf_result = ipf.IPerfResult(iperf_file) - instantaneous_rates = [ - rate * 8 * (1.024**2) for rate in iperf_result.instantaneous_rates - ] - return { - 'throughput': instantaneous_rates, - 'rssi_result': rssi_future.result(), - 'ap_settings': self.access_point.ap_settings, - } - - def run_attenuation_waveform(self, testcase_params, step_duration=1): - """Function that generates test params based on the test name. - - Args: - testcase_params: dict including all test params encoded in test - name - step_duration: int representing number of seconds to dwell on each - atten level - """ - atten_waveforms = testcase_params['atten_waveforms'] - for atten_idx in range(atten_waveforms['length']): - start_time = time.time() - for network, atten_waveform in atten_waveforms.items(): - for idx, atten in enumerate(self.attenuators): - nets_on_port = [ - item["network"] for item in self.rf_map_by_atten[idx] - ] - if network in nets_on_port: - atten.set_atten(atten_waveform[atten_idx]) - measure_time = time.time() - start_time - time.sleep(step_duration - measure_time) - - def compile_atten_waveforms(self, waveform_params): - """Function to compile all attenuation waveforms for roaming test. - - Args: - waveform_params: list of dicts representing waveforms to generate - """ - atten_waveforms = {} - for network in list(waveform_params[0]): - atten_waveforms[network] = [] - - for waveform in waveform_params: - for network, network_waveform in waveform.items(): - waveform_vector = self.gen_single_atten_waveform( - network_waveform) - atten_waveforms[network] += waveform_vector - - waveform_lengths = { - len(atten_waveforms[network]) - for network in atten_waveforms.keys() - } - if len(waveform_lengths) != 1: - raise ValueError( - 'Attenuation waveform length should be equal for all networks.' - ) - else: - atten_waveforms['length'] = waveform_lengths.pop() - return atten_waveforms - - def gen_single_atten_waveform(self, waveform_params): - """Function to generate a single attenuation waveform for roaming test. - - Args: - waveform_params: dict representing waveform to generate - """ - waveform_vector = [] - for section in range(len(waveform_params['atten_levels']) - 1): - section_limits = waveform_params['atten_levels'][section:section + - 2] - up_down = (1 - 2 * (section_limits[1] < section_limits[0])) - temp_section = list( - range(section_limits[0], section_limits[1] + up_down, - up_down * waveform_params['step_size'])) - temp_section = [ - val for val in temp_section - for _ in range(waveform_params['step_duration']) - ] - waveform_vector += temp_section - waveform_vector *= waveform_params['repetitions'] - return waveform_vector - - def parse_test_params(self, testcase_params): - """Function that generates test params based on the test name. - - Args: - test_name: current test name - Returns: - testcase_params: dict including all test params encoded in test - name - """ - if testcase_params["waveform_type"] == 'smooth': - testcase_params[ - 'roaming_waveforms_params'] = self.testclass_params[ - 'smooth_roaming_waveforms'] - elif testcase_params["waveform_type"] == 'failover': - testcase_params[ - 'roaming_waveforms_params'] = self.testclass_params[ - 'failover_roaming_waveforms'] - elif testcase_params["waveform_type"] == 'consistency': - testcase_params[ - 'roaming_waveforms_params'] = self.testclass_params[ - 'consistency_waveforms'] - return testcase_params - - def _test_traffic_continuity(self, testcase_params): - """Test function for traffic continuity""" - # Compile test parameters from config and test name - testcase_params = self.parse_test_params(testcase_params) - testcase_params.update(self.testclass_params) - testcase_params['atten_waveforms'] = self.compile_atten_waveforms( - testcase_params['roaming_waveforms_params']) - # Run traffic test - self.setup_roaming_test(testcase_params) - if testcase_params['traffic_type'] == 'iperf': - result = self.run_iperf_test(testcase_params) - elif testcase_params['traffic_type'] == 'ping': - result = self.run_ping_test(testcase_params) - # Postprocess results - self.process_traffic_continuity_results(testcase_params, result) - self.pass_fail_traffic_continuity(result) - - def _test_roam_consistency(self, testcase_params): - """Test function for roaming consistency""" - testcase_params = self.parse_test_params(testcase_params) - testcase_params.update(self.testclass_params) - # Run traffic test - secondary_attens = range( - self.testclass_params['consistency_waveforms']['secondary_loop'] - ['atten_levels'][0], self.testclass_params['consistency_waveforms'] - ['secondary_loop']['atten_levels'][1], - self.testclass_params['consistency_waveforms']['secondary_loop'] - ['step_size']) - results = collections.OrderedDict() - for secondary_atten in secondary_attens: - primary_waveform = self.gen_single_atten_waveform( - testcase_params['roaming_waveforms_params']['primary_sweep']) - secondary_waveform_params = { - 'atten_levels': [secondary_atten, secondary_atten], - 'step_size': 1, - 'step_duration': len(primary_waveform), - 'repetitions': 1 - } - secondary_waveform = self.gen_single_atten_waveform( - secondary_waveform_params) - testcase_params['atten_waveforms'] = { - 'length': len(primary_waveform) - } - for network_key, network_info in self.main_network.items(): - if 'primary' in network_info['roaming_label']: - testcase_params['atten_waveforms'][ - network_key] = primary_waveform - else: - testcase_params['atten_waveforms'][ - network_key] = secondary_waveform - results[secondary_atten] = [] - for run in range(self.testclass_params['consistency_num_runs']): - self.setup_roaming_test(testcase_params) - results[secondary_atten].append( - self.run_ping_test(testcase_params)) - # Postprocess results - self.process_consistency_results(testcase_params, results) - self.pass_fail_roaming_consistency(results) - - def test_consistency_roaming_screen_on_ping(self): - testcase_params = { - "waveform_type": "consistency", - "screen_on": 1, - "traffic_type": "ping" - } - self._test_roam_consistency(testcase_params) - - def test_smooth_roaming_screen_on_ping_continuity(self): - testcase_params = { - "waveform_type": "smooth", - "screen_on": 1, - "traffic_type": "ping" - } - self._test_traffic_continuity(testcase_params) - - def test_smooth_roaming_screen_on_iperf_continuity(self): - testcase_params = { - "waveform_type": "smooth", - "screen_on": 1, - "traffic_type": "iperf" - } - self._test_traffic_continuity(testcase_params) - - def test_failover_roaming_screen_on_ping_continuity(self): - testcase_params = { - "waveform_type": "failover", - "screen_on": 1, - "traffic_type": "ping" - } - self._test_traffic_continuity(testcase_params) - - def test_failover_roaming_screen_on_iperf_continuity(self): - testcase_params = { - "waveform_type": "failover", - "screen_on": 1, - "traffic_type": "iperf" - } - self._test_traffic_continuity(testcase_params) - - def test_smooth_roaming_screen_off_ping_continuity(self): - testcase_params = { - "waveform_type": "smooth", - "screen_on": 0, - "traffic_type": "ping" - } - self._test_traffic_continuity(testcase_params) - - def test_smooth_roaming_screen_off_iperf_continuity(self): - testcase_params = { - "waveform_type": "smooth", - "screen_on": 0, - "traffic_type": "iperf" - } - self._test_traffic_continuity(testcase_params) - - def test_failover_roaming_screen_off_ping_continuity(self): - testcase_params = { - "waveform_type": "failover", - "screen_on": 0, - "traffic_type": "ping" - } - self._test_traffic_continuity(testcase_params) - - def test_failover_roaming_screen_off_iperf_continuity(self): - testcase_params = { - "waveform_type": "failover", - "screen_on": 0, - "traffic_type": "iperf" - } - self._test_traffic_continuity(testcase_params) diff --git a/acts/tests/google/wifi/WifiRoamingTest.py b/acts/tests/google/wifi/WifiRoamingTest.py deleted file mode 100644 index 4a64ec1318..0000000000 --- a/acts/tests/google/wifi/WifiRoamingTest.py +++ /dev/null @@ -1,153 +0,0 @@ -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import pprint -import random -import time - -from acts import asserts -from acts import base_test -from acts import signals -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi import wifi_test_utils as wutils -from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest - -WifiEnums = wutils.WifiEnums - -class WifiRoamingTest(WifiBaseTest): - - def setup_class(self): - """Setup required dependencies from config file and configure - the required networks for testing roaming. - - Returns: - True if successfully configured the requirements for testing. - """ - super().setup_class() - - self.dut = self.android_devices[0] - wutils.wifi_test_device_init(self.dut) - req_params = ["roaming_attn", "roam_interval", "ping_addr", - "max_bugreports"] - opt_param = ["open_network", "reference_networks",] - self.unpack_userparams( - req_param_names=req_params, opt_param_names=opt_param) - - if "AccessPoint" in self.user_params: - self.legacy_configure_ap_and_start(ap_count=2) - - asserts.assert_true( - len(self.reference_networks) > 1, - "Need at least two psk networks for roaming.") - asserts.assert_true( - len(self.open_network) > 1, - "Need at least two open networks for roaming") - wutils.wifi_toggle_state(self.dut, True) - - def teardown_class(self): - self.dut.ed.clear_all_events() - if "AccessPoint" in self.user_params: - del self.user_params["reference_networks"] - del self.user_params["open_network"] - - def setup_test(self): - self.dut.ed.clear_all_events() - self.dut.droid.wakeLockAcquireBright() - self.dut.droid.wakeUpNow() - - def teardown_test(self): - self.dut.droid.wakeLockRelease() - self.dut.droid.goToSleepNow() - wutils.reset_wifi(self.dut) - - def on_fail(self, test_name, begin_time): - self.dut.cat_adb_log(test_name, begin_time) - self.dut.take_bug_report(test_name, begin_time) - - def roaming_from_AP1_and_AP2(self, AP1_network, AP2_network): - """Test roaming between two APs. - - Args: - AP1_network: AP-1's network information. - AP2_network: AP-2's network information. - - Steps: - 1. Make AP1 visible, AP2 not visible. - 2. Connect to AP1's ssid. - 3. Make AP1 not visible, AP2 visible. - 4. Expect DUT to roam to AP2. - 5. Validate connection information and ping. - """ - wutils.set_attns(self.attenuators, "AP1_on_AP2_off") - wutils.wifi_connect(self.dut, AP1_network) - self.log.info("Roaming from %s to %s", AP1_network, AP2_network) - wutils.trigger_roaming_and_validate(self.dut, self.attenuators, - "AP1_off_AP2_on", AP2_network) - - """ Tests Begin. - - The following tests are designed to test inter-SSID Roaming only. - - """ - @test_tracker_info(uuid="db8a46f9-713f-4b98-8d9f-d36319905b0a") - def test_roaming_between_AP1_to_AP2_open_2g(self): - AP1_network = self.open_network[0]["2g"] - AP2_network = self.open_network[1]["2g"] - self.roaming_from_AP1_and_AP2(AP1_network, AP2_network) - - @test_tracker_info(uuid="0db67d9b-6ea9-4f40-acf2-155c4ecf9dc5") - def test_roaming_between_AP1_to_AP2_open_5g(self): - AP1_network = self.open_network[0]["5g"] - AP2_network = self.open_network[1]["5g"] - self.roaming_from_AP1_and_AP2(AP1_network, AP2_network) - - @test_tracker_info(uuid="eabc7319-d962-4bef-b679-725e9ff00420") - def test_roaming_between_AP1_to_AP2_psk_2g(self): - AP1_network = self.reference_networks[0]["2g"] - AP2_network = self.reference_networks[1]["2g"] - self.roaming_from_AP1_and_AP2(AP1_network, AP2_network) - - @test_tracker_info(uuid="1cf9c681-4ff0-45c1-9719-f01629f6a7f7") - def test_roaming_between_AP1_to_AP2_psk_5g(self): - AP1_network = self.reference_networks[0]["5g"] - AP2_network = self.reference_networks[1]["5g"] - self.roaming_from_AP1_and_AP2(AP1_network, AP2_network) - - @test_tracker_info(uuid="3114d625-5cdd-4205-bb46-5a9d057dc80d") - def test_roaming_fail_psk_2g(self): - network = {'SSID':'test_roaming_fail', 'password':'roam123456@'} - # AP2 network with incorrect password. - network_fail = {'SSID':'test_roaming_fail', 'password':'roam123456@#$%^'} - # Setup AP1 with the correct password. - wutils.ap_setup(self, 0, self.access_points[0], network) - network_bssid = self.access_points[0].get_bssid_from_ssid( - network["SSID"], '2g') - # Setup AP2 with the incorrect password. - wutils.ap_setup(self, 1, self.access_points[1], network_fail) - network_fail_bssid = self.access_points[1].get_bssid_from_ssid( - network_fail["SSID"], '2g') - network['bssid'] = network_bssid - network_fail['bssid'] = network_fail_bssid - try: - # Initiate roaming with AP2 configured with incorrect password. - self.roaming_from_AP1_and_AP2(network, network_fail) - except: - self.log.info("Roaming failed to AP2 with incorrect password.") - # Re-configure AP2 after roaming failed, with correct password. - self.log.info("Re-configuring AP2 with correct password.") - wutils.ap_setup(self, 1, self.access_points[1], network) - self.roaming_from_AP1_and_AP2(network, network_fail) - - """ Tests End """ diff --git a/acts/tests/google/wifi/WifiRssiTest.py b/acts/tests/google/wifi/WifiRssiTest.py deleted file mode 100644 index 9ff9afa678..0000000000 --- a/acts/tests/google/wifi/WifiRssiTest.py +++ /dev/null @@ -1,1074 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2018 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the 'License'); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an 'AS IS' BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import collections -import itertools -import json -import logging -import math -import numpy -import os -import statistics -from acts import asserts -from acts import base_test -from acts import context -from acts import utils -from acts.controllers.utils_lib import ssh -from acts.controllers import iperf_server as ipf -from acts.metrics.loggers.blackbox import BlackboxMappedMetricLogger -from acts.test_utils.wifi import ota_chamber -from acts.test_utils.wifi import wifi_performance_test_utils as wputils -from acts.test_utils.wifi import wifi_retail_ap as retail_ap -from acts.test_utils.wifi import wifi_test_utils as wutils -from concurrent.futures import ThreadPoolExecutor -from functools import partial - -SHORT_SLEEP = 1 -MED_SLEEP = 6 -CONST_3dB = 3.01029995664 -RSSI_ERROR_VAL = float('nan') - - -class WifiRssiTest(base_test.BaseTestClass): - """Class to test WiFi RSSI reporting. - - This class tests RSSI reporting on android devices. The class tests RSSI - accuracy by checking RSSI over a large attenuation range, checks for RSSI - stability over time when attenuation is fixed, and checks that RSSI quickly - and reacts to changes attenuation by checking RSSI trajectories over - configurable attenuation waveforms.For an example config file to run this - test class see example_connectivity_performance_ap_sta.json. - """ - def __init__(self, controllers): - base_test.BaseTestClass.__init__(self, controllers) - self.testcase_metric_logger = ( - BlackboxMappedMetricLogger.for_test_case()) - self.testclass_metric_logger = ( - BlackboxMappedMetricLogger.for_test_class()) - self.publish_test_metrics = True - - def setup_class(self): - self.dut = self.android_devices[0] - req_params = [ - 'RemoteServer', 'RetailAccessPoints', 'rssi_test_params', - 'main_network', 'testbed_params' - ] - self.unpack_userparams(req_params) - self.testclass_params = self.rssi_test_params - self.num_atten = self.attenuators[0].instrument.num_atten - self.iperf_server = self.iperf_servers[0] - self.iperf_client = self.iperf_clients[0] - self.remote_server = ssh.connection.SshConnection( - ssh.settings.from_config(self.RemoteServer[0]['ssh_config'])) - self.access_point = retail_ap.create(self.RetailAccessPoints)[0] - self.log_path = os.path.join(logging.log_path, 'results') - os.makedirs(self.log_path, exist_ok=True) - self.log.info('Access Point Configuration: {}'.format( - self.access_point.ap_settings)) - self.testclass_results = [] - - # Turn WiFi ON - if self.testclass_params.get('airplane_mode', 1): - self.log.info('Turning on airplane mode.') - asserts.assert_true(utils.force_airplane_mode(self.dut, True), - "Can not turn on airplane mode.") - wutils.wifi_toggle_state(self.dut, True) - - def teardown_test(self): - self.iperf_server.stop() - - def pass_fail_check_rssi_stability(self, testcase_params, - postprocessed_results): - """Check the test result and decide if it passed or failed. - - Checks the RSSI test result and fails the test if the standard - deviation of signal_poll_rssi is beyond the threshold defined in the - config file. - - Args: - testcase_params: dict containing test-specific parameters - postprocessed_results: compiled arrays of RSSI measurements - """ - # Set Blackbox metric values - if self.publish_test_metrics: - self.testcase_metric_logger.add_metric( - 'signal_poll_rssi_stdev', - max(postprocessed_results['signal_poll_rssi']['stdev'])) - self.testcase_metric_logger.add_metric( - 'chain_0_rssi_stdev', - max(postprocessed_results['chain_0_rssi']['stdev'])) - self.testcase_metric_logger.add_metric( - 'chain_1_rssi_stdev', - max(postprocessed_results['chain_1_rssi']['stdev'])) - - # Evaluate test pass/fail - test_failed = any([ - stdev > self.testclass_params['stdev_tolerance'] - for stdev in postprocessed_results['signal_poll_rssi']['stdev'] - ]) - test_message = ( - 'RSSI stability {0}. Standard deviation was {1} dB ' - '(limit {2}), per chain standard deviation [{3}, {4}] dB'.format( - 'failed' * test_failed + 'passed' * (not test_failed), [ - float('{:.2f}'.format(x)) - for x in postprocessed_results['signal_poll_rssi']['stdev'] - ], self.testclass_params['stdev_tolerance'], [ - float('{:.2f}'.format(x)) - for x in postprocessed_results['chain_0_rssi']['stdev'] - ], [ - float('{:.2f}'.format(x)) - for x in postprocessed_results['chain_1_rssi']['stdev'] - ])) - if test_failed: - asserts.fail(test_message) - asserts.explicit_pass(test_message) - - def pass_fail_check_rssi_accuracy(self, testcase_params, - postprocessed_results): - """Check the test result and decide if it passed or failed. - - Checks the RSSI test result and compares and compute its deviation from - the predicted RSSI. This computation is done for all reported RSSI - values. The test fails if any of the RSSI values specified in - rssi_under_test have an average error beyond what is specified in the - configuration file. - - Args: - postprocessed_results: compiled arrays of RSSI measurements - testcase_params: dict containing params such as list of RSSIs under - test, i.e., can cause test to fail and boolean indicating whether - to look at absolute RSSI accuracy, or centered RSSI accuracy. - Centered accuracy is computed after systematic RSSI shifts are - removed. - """ - test_failed = False - test_message = '' - if testcase_params['absolute_accuracy']: - error_type = 'absolute' - else: - error_type = 'centered' - - for key, val in postprocessed_results.items(): - # Compute the error metrics ignoring invalid RSSI readings - # If all readings invalid, set error to RSSI_ERROR_VAL - if 'rssi' in key and 'predicted' not in key: - filtered_error = [x for x in val['error'] if not math.isnan(x)] - if filtered_error: - avg_shift = statistics.mean(filtered_error) - if testcase_params['absolute_accuracy']: - avg_error = statistics.mean( - [abs(x) for x in filtered_error]) - else: - avg_error = statistics.mean( - [abs(x - avg_shift) for x in filtered_error]) - else: - avg_error = RSSI_ERROR_VAL - avg_shift = RSSI_ERROR_VAL - # Set Blackbox metric values - if self.publish_test_metrics: - self.testcase_metric_logger.add_metric( - '{}_error'.format(key), avg_error) - self.testcase_metric_logger.add_metric( - '{}_shift'.format(key), avg_shift) - # Evaluate test pass/fail - rssi_failure = (avg_error > - self.testclass_params['abs_tolerance'] - ) or math.isnan(avg_error) - if rssi_failure and key in testcase_params['rssi_under_test']: - test_message = test_message + ( - '{} failed ({} error = {:.2f} dB, ' - 'shift = {:.2f} dB)\n').format(key, error_type, - avg_error, avg_shift) - test_failed = True - elif rssi_failure: - test_message = test_message + ( - '{} failed (ignored) ({} error = {:.2f} dB, ' - 'shift = {:.2f} dB)\n').format(key, error_type, - avg_error, avg_shift) - else: - test_message = test_message + ( - '{} passed ({} error = {:.2f} dB, ' - 'shift = {:.2f} dB)\n').format(key, error_type, - avg_error, avg_shift) - if test_failed: - asserts.fail(test_message) - asserts.explicit_pass(test_message) - - def post_process_rssi_sweep(self, rssi_result): - """Postprocesses and saves JSON formatted results. - - Args: - rssi_result: dict containing attenuation, rssi and other meta - data - Returns: - postprocessed_results: compiled arrays of RSSI data used in - pass/fail check - """ - # Save output as text file - results_file_path = os.path.join(self.log_path, self.current_test_name) - with open(results_file_path, 'w') as results_file: - json.dump(rssi_result, results_file, indent=4) - # Compile results into arrays of RSSIs suitable for plotting - # yapf: disable - postprocessed_results = collections.OrderedDict( - [('signal_poll_rssi', {}), - ('signal_poll_avg_rssi', {}), - ('scan_rssi', {}), - ('chain_0_rssi', {}), - ('chain_1_rssi', {}), - ('total_attenuation', []), - ('predicted_rssi', [])]) - # yapf: enable - for key, val in postprocessed_results.items(): - if 'scan_rssi' in key: - postprocessed_results[key]['data'] = [ - x for data_point in rssi_result['rssi_result'] for x in - data_point[key][rssi_result['connected_bssid']]['data'] - ] - postprocessed_results[key]['mean'] = [ - x[key][rssi_result['connected_bssid']]['mean'] - for x in rssi_result['rssi_result'] - ] - postprocessed_results[key]['stdev'] = [ - x[key][rssi_result['connected_bssid']]['stdev'] - for x in rssi_result['rssi_result'] - ] - elif 'predicted_rssi' in key: - postprocessed_results['total_attenuation'] = [ - att + rssi_result['fixed_attenuation'] + - rssi_result['dut_front_end_loss'] - for att in rssi_result['attenuation'] - ] - postprocessed_results['predicted_rssi'] = [ - rssi_result['ap_tx_power'] - att - for att in postprocessed_results['total_attenuation'] - ] - elif 'rssi' in key: - postprocessed_results[key]['data'] = [ - x for data_point in rssi_result['rssi_result'] - for x in data_point[key]['data'] - ] - postprocessed_results[key]['mean'] = [ - x[key]['mean'] for x in rssi_result['rssi_result'] - ] - postprocessed_results[key]['stdev'] = [ - x[key]['stdev'] for x in rssi_result['rssi_result'] - ] - # Compute RSSI errors - for key, val in postprocessed_results.items(): - if 'chain' in key: - postprocessed_results[key]['error'] = [ - postprocessed_results[key]['mean'][idx] + CONST_3dB - - postprocessed_results['predicted_rssi'][idx] - for idx in range( - len(postprocessed_results['predicted_rssi'])) - ] - elif 'rssi' in key and 'predicted' not in key: - postprocessed_results[key]['error'] = [ - postprocessed_results[key]['mean'][idx] - - postprocessed_results['predicted_rssi'][idx] - for idx in range( - len(postprocessed_results['predicted_rssi'])) - ] - return postprocessed_results - - def plot_rssi_vs_attenuation(self, postprocessed_results): - """Function to plot RSSI vs attenuation sweeps - - Args: - postprocessed_results: compiled arrays of RSSI data. - """ - figure = wputils.BokehFigure(self.current_test_name, - x_label='Attenuation (dB)', - primary_y_label='RSSI (dBm)') - figure.add_line(postprocessed_results['total_attenuation'], - postprocessed_results['signal_poll_rssi']['mean'], - 'Signal Poll RSSI', - marker='circle') - figure.add_line(postprocessed_results['total_attenuation'], - postprocessed_results['scan_rssi']['mean'], - 'Scan RSSI', - marker='circle') - figure.add_line(postprocessed_results['total_attenuation'], - postprocessed_results['chain_0_rssi']['mean'], - 'Chain 0 RSSI', - marker='circle') - figure.add_line(postprocessed_results['total_attenuation'], - postprocessed_results['chain_1_rssi']['mean'], - 'Chain 1 RSSI', - marker='circle') - figure.add_line(postprocessed_results['total_attenuation'], - postprocessed_results['predicted_rssi'], - 'Predicted RSSI', - marker='circle') - - output_file_path = os.path.join(self.log_path, - self.current_test_name + '.html') - figure.generate_figure(output_file_path) - - def plot_rssi_vs_time(self, rssi_result, postprocessed_results, - center_curves): - """Function to plot RSSI vs time. - - Args: - rssi_result: dict containing raw RSSI data - postprocessed_results: compiled arrays of RSSI data - center_curvers: boolean indicating whether to shift curves to align - them with predicted RSSIs - """ - figure = wputils.BokehFigure( - self.current_test_name, - x_label='Time (s)', - primary_y_label=center_curves * 'Centered' + 'RSSI (dBm)', - ) - - # yapf: disable - rssi_time_series = collections.OrderedDict( - [('signal_poll_rssi', []), - ('signal_poll_avg_rssi', []), - ('scan_rssi', []), - ('chain_0_rssi', []), - ('chain_1_rssi', []), - ('predicted_rssi', [])]) - # yapf: enable - for key, val in rssi_time_series.items(): - if 'predicted_rssi' in key: - rssi_time_series[key] = [ - x for x in postprocessed_results[key] for copies in range( - len(rssi_result['rssi_result'][0]['signal_poll_rssi'] - ['data'])) - ] - elif 'rssi' in key: - if center_curves: - filtered_error = [ - x for x in postprocessed_results[key]['error'] - if not math.isnan(x) - ] - if filtered_error: - avg_shift = statistics.mean(filtered_error) - else: - avg_shift = 0 - rssi_time_series[key] = [ - x - avg_shift - for x in postprocessed_results[key]['data'] - ] - else: - rssi_time_series[key] = postprocessed_results[key]['data'] - time_vec = [ - self.testclass_params['polling_frequency'] * x - for x in range(len(rssi_time_series[key])) - ] - if len(rssi_time_series[key]) > 0: - figure.add_line(time_vec, rssi_time_series[key], key) - - output_file_path = os.path.join(self.log_path, - self.current_test_name + '.html') - figure.generate_figure(output_file_path) - - def plot_rssi_distribution(self, postprocessed_results): - """Function to plot RSSI distributions. - - Args: - postprocessed_results: compiled arrays of RSSI data - """ - monitored_rssis = ['signal_poll_rssi', 'chain_0_rssi', 'chain_1_rssi'] - - rssi_dist = collections.OrderedDict() - for rssi_key in monitored_rssis: - rssi_data = postprocessed_results[rssi_key] - rssi_dist[rssi_key] = collections.OrderedDict() - unique_rssi = sorted(set(rssi_data['data'])) - rssi_counts = [] - for value in unique_rssi: - rssi_counts.append(rssi_data['data'].count(value)) - total_count = sum(rssi_counts) - rssi_dist[rssi_key]['rssi_values'] = unique_rssi - rssi_dist[rssi_key]['rssi_pdf'] = [ - x / total_count for x in rssi_counts - ] - rssi_dist[rssi_key]['rssi_cdf'] = [] - cum_prob = 0 - for prob in rssi_dist[rssi_key]['rssi_pdf']: - cum_prob += prob - rssi_dist[rssi_key]['rssi_cdf'].append(cum_prob) - - figure = wputils.BokehFigure(self.current_test_name, - x_label='RSSI (dBm)', - primary_y_label='p(RSSI = x)', - secondary_y_label='p(RSSI <= x)') - for rssi_key, rssi_data in rssi_dist.items(): - figure.add_line(x_data=rssi_data['rssi_values'], - y_data=rssi_data['rssi_pdf'], - legend='{} PDF'.format(rssi_key), - y_axis='default') - figure.add_line(x_data=rssi_data['rssi_values'], - y_data=rssi_data['rssi_cdf'], - legend='{} CDF'.format(rssi_key), - y_axis='secondary') - output_file_path = os.path.join(self.log_path, - self.current_test_name + '_dist.html') - figure.generate_figure(output_file_path) - - def run_rssi_test(self, testcase_params): - """Test function to run RSSI tests. - - The function runs an RSSI test in the current device/AP configuration. - Function is called from another wrapper function that sets up the - testbed for the RvR test - - Args: - testcase_params: dict containing test-specific parameters - Returns: - rssi_result: dict containing rssi_result and meta data - """ - # Run test and log result - rssi_result = collections.OrderedDict() - rssi_result['test_name'] = self.current_test_name - rssi_result['testcase_params'] = testcase_params - rssi_result['ap_settings'] = self.access_point.ap_settings.copy() - rssi_result['attenuation'] = list(testcase_params['rssi_atten_range']) - rssi_result['connected_bssid'] = self.main_network[ - testcase_params['band']].get('BSSID', '00:00:00:00') - channel_mode_combo = '{}_{}'.format(str(testcase_params['channel']), - testcase_params['mode']) - channel_str = str(testcase_params['channel']) - if channel_mode_combo in self.testbed_params['ap_tx_power']: - rssi_result['ap_tx_power'] = self.testbed_params['ap_tx_power'][ - channel_mode_combo] - else: - rssi_result['ap_tx_power'] = self.testbed_params['ap_tx_power'][ - str(testcase_params['channel'])] - rssi_result['fixed_attenuation'] = self.testbed_params[ - 'fixed_attenuation'][channel_str] - rssi_result['dut_front_end_loss'] = self.testbed_params[ - 'dut_front_end_loss'][channel_str] - - self.log.info('Start running RSSI test.') - rssi_result['rssi_result'] = [] - rssi_result['llstats'] = [] - llstats_obj = wputils.LinkLayerStats(self.dut) - # Start iperf traffic if required by test - if testcase_params['active_traffic'] and testcase_params[ - 'traffic_type'] == 'iperf': - self.iperf_server.start(tag=0) - if isinstance(self.iperf_server, ipf.IPerfServerOverAdb): - iperf_server_address = self.dut_ip - else: - iperf_server_address = wputils.get_server_address( - self.remote_server, self.dut_ip, '255.255.255.0') - executor = ThreadPoolExecutor(max_workers=1) - thread_future = executor.submit( - self.iperf_client.start, iperf_server_address, - testcase_params['iperf_args'], 0, - testcase_params['traffic_timeout'] + SHORT_SLEEP) - executor.shutdown(wait=False) - elif testcase_params['active_traffic'] and testcase_params[ - 'traffic_type'] == 'ping': - thread_future = wputils.get_ping_stats_nb( - self.remote_server, self.dut_ip, - testcase_params['traffic_timeout'], 0.02, 64) - else: - thread_future = wputils.get_ping_stats_nb( - self.remote_server, self.dut_ip, - testcase_params['traffic_timeout'], 0.5, 64) - for atten in testcase_params['rssi_atten_range']: - # Set Attenuation - self.log.info('Setting attenuation to {} dB'.format(atten)) - for attenuator in self.attenuators: - attenuator.set_atten(atten) - llstats_obj.update_stats() - current_rssi = collections.OrderedDict() - current_rssi = wputils.get_connected_rssi( - self.dut, testcase_params['connected_measurements'], - self.testclass_params['polling_frequency'], - testcase_params['first_measurement_delay']) - current_rssi['scan_rssi'] = wputils.get_scan_rssi( - self.dut, testcase_params['tracked_bssid'], - testcase_params['scan_measurements']) - rssi_result['rssi_result'].append(current_rssi) - llstats_obj.update_stats() - curr_llstats = llstats_obj.llstats_incremental.copy() - rssi_result['llstats'].append(curr_llstats) - self.log.info( - 'Connected RSSI at {0:.2f} dB is {1:.2f} [{2:.2f}, {3:.2f}] dB' - .format(atten, current_rssi['signal_poll_rssi']['mean'], - current_rssi['chain_0_rssi']['mean'], - current_rssi['chain_1_rssi']['mean'])) - # Stop iperf traffic if needed - for attenuator in self.attenuators: - attenuator.set_atten(0) - thread_future.result() - if testcase_params['active_traffic'] and testcase_params[ - 'traffic_type'] == 'iperf': - self.iperf_server.stop() - return rssi_result - - def setup_ap(self, testcase_params): - """Function that gets devices ready for the test. - - Args: - testcase_params: dict containing test-specific parameters - """ - if '2G' in testcase_params['band']: - frequency = wutils.WifiEnums.channel_2G_to_freq[ - testcase_params['channel']] - else: - frequency = wutils.WifiEnums.channel_5G_to_freq[ - testcase_params['channel']] - if frequency in wutils.WifiEnums.DFS_5G_FREQUENCIES: - self.access_point.set_region(self.testbed_params['DFS_region']) - else: - self.access_point.set_region(self.testbed_params['default_region']) - self.access_point.set_channel(testcase_params['band'], - testcase_params['channel']) - self.access_point.set_bandwidth(testcase_params['band'], - testcase_params['mode']) - self.log.info('Access Point Configuration: {}'.format( - self.access_point.ap_settings)) - - def setup_dut(self, testcase_params): - """Sets up the DUT in the configuration required by the test.""" - # Check battery level before test - if not wputils.health_check(self.dut, 10): - asserts.skip('Battery level too low. Skipping test.') - # Turn screen off to preserve battery - self.dut.go_to_sleep() - if wputils.validate_network(self.dut, - testcase_params['test_network']['SSID']): - self.log.info('Already connected to desired network') - else: - wutils.wifi_toggle_state(self.dut, True) - wutils.reset_wifi(self.dut) - self.main_network[testcase_params['band']][ - 'channel'] = testcase_params['channel'] - wutils.set_wifi_country_code(self.dut, - self.testclass_params['country_code']) - wutils.wifi_connect(self.dut, - self.main_network[testcase_params['band']], - num_of_tries=5) - self.dut_ip = self.dut.droid.connectivityGetIPv4Addresses('wlan0')[0] - - def setup_rssi_test(self, testcase_params): - """Main function to test RSSI. - - The function sets up the AP in the correct channel and mode - configuration and called rssi_test to sweep attenuation and measure - RSSI - - Args: - testcase_params: dict containing test-specific parameters - Returns: - rssi_result: dict containing rssi_results and meta data - """ - # Configure AP - self.setup_ap(testcase_params) - # Initialize attenuators - for attenuator in self.attenuators: - attenuator.set_atten(testcase_params['rssi_atten_range'][0]) - # Connect DUT to Network - self.setup_dut(testcase_params) - - def get_traffic_timeout(self, testcase_params): - """Function to comput iperf session length required in RSSI test. - - Args: - testcase_params: dict containing test-specific parameters - Returns: - traffic_timeout: length of iperf session required in rssi test - """ - atten_step_duration = testcase_params['first_measurement_delay'] + ( - testcase_params['connected_measurements'] * - self.testclass_params['polling_frequency'] - ) + testcase_params['scan_measurements'] * MED_SLEEP - timeout = len(testcase_params['rssi_atten_range'] - ) * atten_step_duration + MED_SLEEP - return timeout - - def compile_rssi_vs_atten_test_params(self, testcase_params): - """Function to complete compiling test-specific parameters - - Args: - testcase_params: dict containing test-specific parameters - """ - testcase_params.update( - connected_measurements=self. - testclass_params['rssi_vs_atten_connected_measurements'], - scan_measurements=self. - testclass_params['rssi_vs_atten_scan_measurements'], - first_measurement_delay=MED_SLEEP, - rssi_under_test=self.testclass_params['rssi_vs_atten_metrics'], - absolute_accuracy=1) - - testcase_params['band'] = self.access_point.band_lookup_by_channel( - testcase_params['channel']) - testcase_params['test_network'] = self.main_network[ - testcase_params['band']] - testcase_params['tracked_bssid'] = [ - self.main_network[testcase_params['band']].get( - 'BSSID', '00:00:00:00') - ] - - num_atten_steps = int((self.testclass_params['rssi_vs_atten_stop'] - - self.testclass_params['rssi_vs_atten_start']) / - self.testclass_params['rssi_vs_atten_step']) - testcase_params['rssi_atten_range'] = [ - self.testclass_params['rssi_vs_atten_start'] + - x * self.testclass_params['rssi_vs_atten_step'] - for x in range(0, num_atten_steps) - ] - testcase_params['traffic_timeout'] = self.get_traffic_timeout( - testcase_params) - - if isinstance(self.iperf_server, ipf.IPerfServerOverAdb): - testcase_params['iperf_args'] = '-i 1 -t {} -J'.format( - testcase_params['traffic_timeout']) - else: - testcase_params['iperf_args'] = '-i 1 -t {} -J -R'.format( - testcase_params['traffic_timeout']) - return testcase_params - - def compile_rssi_stability_test_params(self, testcase_params): - """Function to complete compiling test-specific parameters - - Args: - testcase_params: dict containing test-specific parameters - """ - testcase_params.update( - connected_measurements=int( - self.testclass_params['rssi_stability_duration'] / - self.testclass_params['polling_frequency']), - scan_measurements=0, - first_measurement_delay=MED_SLEEP, - rssi_atten_range=self.testclass_params['rssi_stability_atten']) - testcase_params['band'] = self.access_point.band_lookup_by_channel( - testcase_params['channel']) - testcase_params['test_network'] = self.main_network[ - testcase_params['band']] - testcase_params['tracked_bssid'] = [ - self.main_network[testcase_params['band']].get( - 'BSSID', '00:00:00:00') - ] - - testcase_params['traffic_timeout'] = self.get_traffic_timeout( - testcase_params) - if isinstance(self.iperf_server, ipf.IPerfServerOverAdb): - testcase_params['iperf_args'] = '-i 1 -t {} -J'.format( - testcase_params['traffic_timeout']) - else: - testcase_params['iperf_args'] = '-i 1 -t {} -J -R'.format( - testcase_params['traffic_timeout']) - return testcase_params - - def compile_rssi_tracking_test_params(self, testcase_params): - """Function to complete compiling test-specific parameters - - Args: - testcase_params: dict containing test-specific parameters - """ - testcase_params.update(connected_measurements=int( - 1 / self.testclass_params['polling_frequency']), - scan_measurements=0, - first_measurement_delay=0, - rssi_under_test=['signal_poll_rssi'], - absolute_accuracy=0) - testcase_params['band'] = self.access_point.band_lookup_by_channel( - testcase_params['channel']) - testcase_params['test_network'] = self.main_network[ - testcase_params['band']] - testcase_params['tracked_bssid'] = [ - self.main_network[testcase_params['band']].get( - 'BSSID', '00:00:00:00') - ] - - rssi_atten_range = [] - for waveform in self.testclass_params['rssi_tracking_waveforms']: - waveform_vector = [] - for section in range(len(waveform['atten_levels']) - 1): - section_limits = waveform['atten_levels'][section:section + 2] - up_down = (1 - 2 * (section_limits[1] < section_limits[0])) - temp_section = list( - range(section_limits[0], section_limits[1] + up_down, - up_down * waveform['step_size'])) - temp_section = [ - temp_section[idx] for idx in range(len(temp_section)) - for n in range(waveform['step_duration']) - ] - waveform_vector += temp_section - waveform_vector = waveform_vector * waveform['repetitions'] - rssi_atten_range = rssi_atten_range + waveform_vector - testcase_params['rssi_atten_range'] = rssi_atten_range - testcase_params['traffic_timeout'] = self.get_traffic_timeout( - testcase_params) - - if isinstance(self.iperf_server, ipf.IPerfServerOverAdb): - testcase_params['iperf_args'] = '-i 1 -t {} -J'.format( - testcase_params['traffic_timeout']) - else: - testcase_params['iperf_args'] = '-i 1 -t {} -J -R'.format( - testcase_params['traffic_timeout']) - return testcase_params - - def _test_rssi_vs_atten(self, testcase_params): - """Function that gets called for each test case of rssi_vs_atten - - The function gets called in each rssi test case. The function - customizes the test based on the test name of the test that called it - - Args: - testcase_params: dict containing test-specific parameters - """ - testcase_params = self.compile_rssi_vs_atten_test_params( - testcase_params) - - self.setup_rssi_test(testcase_params) - rssi_result = self.run_rssi_test(testcase_params) - rssi_result['postprocessed_results'] = self.post_process_rssi_sweep( - rssi_result) - self.testclass_results.append(rssi_result) - self.plot_rssi_vs_attenuation(rssi_result['postprocessed_results']) - self.pass_fail_check_rssi_accuracy( - testcase_params, rssi_result['postprocessed_results']) - - def _test_rssi_stability(self, testcase_params): - """ Function that gets called for each test case of rssi_stability - - The function gets called in each stability test case. The function - customizes test based on the test name of the test that called it - """ - testcase_params = self.compile_rssi_stability_test_params( - testcase_params) - - self.setup_rssi_test(testcase_params) - rssi_result = self.run_rssi_test(testcase_params) - rssi_result['postprocessed_results'] = self.post_process_rssi_sweep( - rssi_result) - self.testclass_results.append(rssi_result) - self.plot_rssi_vs_time(rssi_result, - rssi_result['postprocessed_results'], 1) - self.plot_rssi_distribution(rssi_result['postprocessed_results']) - self.pass_fail_check_rssi_stability( - testcase_params, rssi_result['postprocessed_results']) - - def _test_rssi_tracking(self, testcase_params): - """ Function that gets called for each test case of rssi_tracking - - The function gets called in each rssi test case. The function - customizes the test based on the test name of the test that called it - """ - testcase_params = self.compile_rssi_tracking_test_params( - testcase_params) - - self.setup_rssi_test(testcase_params) - rssi_result = self.run_rssi_test(testcase_params) - rssi_result['postprocessed_results'] = self.post_process_rssi_sweep( - rssi_result) - self.testclass_results.append(rssi_result) - self.plot_rssi_vs_time(rssi_result, - rssi_result['postprocessed_results'], 1) - self.pass_fail_check_rssi_accuracy( - testcase_params, rssi_result['postprocessed_results']) - - def generate_test_cases(self, test_types, channels, modes, traffic_modes): - """Function that auto-generates test cases for a test class.""" - test_cases = [] - allowed_configs = { - 'VHT20': [ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 149, 153, - 157, 161 - ], - 'VHT40': [36, 44, 149, 157], - 'VHT80': [36, 149] - } - - for channel, mode, traffic_mode, test_type in itertools.product( - channels, modes, traffic_modes, test_types): - if channel not in allowed_configs[mode]: - continue - test_name = test_type + '_ch{}_{}_{}'.format( - channel, mode, traffic_mode) - testcase_params = collections.OrderedDict( - channel=channel, - mode=mode, - active_traffic=(traffic_mode == 'ActiveTraffic'), - traffic_type=self.user_params['rssi_test_params'] - ['traffic_type'], - ) - test_function = getattr(self, '_{}'.format(test_type)) - setattr(self, test_name, partial(test_function, testcase_params)) - test_cases.append(test_name) - return test_cases - - -class WifiRssi_2GHz_ActiveTraffic_Test(WifiRssiTest): - def __init__(self, controllers): - super().__init__(controllers) - self.tests = self.generate_test_cases( - ['test_rssi_stability', 'test_rssi_vs_atten'], [1, 2, 6, 10, 11], - ['VHT20'], ['ActiveTraffic']) - - -class WifiRssi_5GHz_ActiveTraffic_Test(WifiRssiTest): - def __init__(self, controllers): - super().__init__(controllers) - self.tests = self.generate_test_cases( - ['test_rssi_stability', 'test_rssi_vs_atten'], - [36, 40, 44, 48, 149, 153, 157, 161], ['VHT20', 'VHT40', 'VHT80'], - ['ActiveTraffic']) - - -class WifiRssi_AllChannels_ActiveTraffic_Test(WifiRssiTest): - def __init__(self, controllers): - super().__init__(controllers) - self.tests = self.generate_test_cases( - ['test_rssi_stability', 'test_rssi_vs_atten'], - [1, 6, 11, 36, 40, 44, 48, 149, 153, 157, 161], - ['VHT20', 'VHT40', 'VHT80'], ['ActiveTraffic']) - - -class WifiRssi_SampleChannels_NoTraffic_Test(WifiRssiTest): - def __init__(self, controllers): - super().__init__(controllers) - self.tests = self.generate_test_cases( - ['test_rssi_stability', 'test_rssi_vs_atten'], [6, 36, 149], - ['VHT20', 'VHT40', 'VHT80'], ['NoTraffic']) - - -class WifiRssiTrackingTest(WifiRssiTest): - def __init__(self, controllers): - super().__init__(controllers) - self.tests = self.generate_test_cases(['test_rssi_tracking'], - [6, 36, 149], - ['VHT20', 'VHT40', 'VHT80'], - ['ActiveTraffic', 'NoTraffic']) - - -# Over-the air version of RSSI tests -class WifiOtaRssiTest(WifiRssiTest): - """Class to test over-the-air rssi tests. - - This class implements measures WiFi RSSI tests in an OTA chamber. - It allows setting orientation and other chamber parameters to study - performance in varying channel conditions - """ - def __init__(self, controllers): - base_test.BaseTestClass.__init__(self, controllers) - self.testcase_metric_logger = ( - BlackboxMappedMetricLogger.for_test_case()) - self.testclass_metric_logger = ( - BlackboxMappedMetricLogger.for_test_class()) - self.publish_test_metrics = False - - def setup_class(self): - WifiRssiTest.setup_class(self) - self.ota_chamber = ota_chamber.create( - self.user_params['OTAChamber'])[0] - - def teardown_class(self): - self.ota_chamber.reset_chamber() - self.process_testclass_results() - - def teardown_test(self): - if self.ota_chamber.current_mode == 'continuous': - self.ota_chamber.reset_chamber() - - def extract_test_id(self, testcase_params, id_fields): - test_id = collections.OrderedDict( - (param, testcase_params[param]) for param in id_fields) - return test_id - - def process_testclass_results(self): - """Saves all test results to enable comparison.""" - testclass_data = collections.OrderedDict() - for test_result in self.testclass_results: - current_params = test_result['testcase_params'] - - channel = current_params['channel'] - channel_data = testclass_data.setdefault( - channel, - collections.OrderedDict(orientation=[], - rssi=collections.OrderedDict( - signal_poll_rssi=[], - chain_0_rssi=[], - chain_1_rssi=[]))) - - channel_data['orientation'].append(current_params['orientation']) - channel_data['rssi']['signal_poll_rssi'].append( - test_result['postprocessed_results']['signal_poll_rssi'] - ['mean'][0]) - channel_data['rssi']['chain_0_rssi'].append( - test_result['postprocessed_results']['chain_0_rssi']['mean'] - [0]) - channel_data['rssi']['chain_1_rssi'].append( - test_result['postprocessed_results']['chain_1_rssi']['mean'] - [0]) - - # Publish test class metrics - for channel, channel_data in testclass_data.items(): - for rssi_metric, rssi_metric_value in channel_data['rssi'].items(): - metric_name = 'ota_summary_ch{}.avg_{}'.format( - channel, rssi_metric) - metric_value = numpy.mean(rssi_metric_value) - self.testclass_metric_logger.add_metric( - metric_name, metric_value) - - # Plot test class results - chamber_mode = self.testclass_results[0]['testcase_params'][ - 'chamber_mode'] - if chamber_mode == 'orientation': - x_label = 'Angle (deg)' - elif chamber_mode == 'stepped stirrers': - x_label = 'Position Index' - elif chamber_mode == 'StirrersOn': - return - plots = [] - for channel, channel_data in testclass_data.items(): - current_plot = wputils.BokehFigure( - title='Channel {} - Rssi vs. Position'.format(channel), - x_label=x_label, - primary_y_label='RSSI (dBm)', - ) - for rssi_metric, rssi_metric_value in channel_data['rssi'].items(): - legend = rssi_metric - current_plot.add_line(channel_data['orientation'], - rssi_metric_value, legend) - current_plot.generate_figure() - plots.append(current_plot) - current_context = context.get_current_context().get_full_output_path() - plot_file_path = os.path.join(current_context, 'results.html') - wputils.BokehFigure.save_figures(plots, plot_file_path) - - def setup_rssi_test(self, testcase_params): - # Test setup - WifiRssiTest.setup_rssi_test(self, testcase_params) - if testcase_params['chamber_mode'] == 'StirrersOn': - self.ota_chamber.start_continuous_stirrers() - else: - self.ota_chamber.set_orientation(testcase_params['orientation']) - - def compile_ota_rssi_test_params(self, testcase_params): - """Function to complete compiling test-specific parameters - - Args: - testcase_params: dict containing test-specific parameters - """ - if "rssi_over_orientation" in self.test_name: - rssi_test_duration = self.testclass_params[ - 'rssi_over_orientation_duration'] - elif "rssi_variation" in self.test_name: - rssi_test_duration = self.testclass_params[ - 'rssi_variation_duration'] - - testcase_params.update( - connected_measurements=int( - rssi_test_duration / - self.testclass_params['polling_frequency']), - scan_measurements=0, - first_measurement_delay=MED_SLEEP, - rssi_atten_range=[ - self.testclass_params['rssi_ota_test_attenuation'] - ]) - testcase_params['band'] = self.access_point.band_lookup_by_channel( - testcase_params['channel']) - testcase_params['test_network'] = self.main_network[ - testcase_params['band']] - testcase_params['tracked_bssid'] = [ - self.main_network[testcase_params['band']].get( - 'BSSID', '00:00:00:00') - ] - - testcase_params['traffic_timeout'] = self.get_traffic_timeout( - testcase_params) - if isinstance(self.iperf_server, ipf.IPerfServerOverAdb): - testcase_params['iperf_args'] = '-i 1 -t {} -J'.format( - testcase_params['traffic_timeout']) - else: - testcase_params['iperf_args'] = '-i 1 -t {} -J -R'.format( - testcase_params['traffic_timeout']) - return testcase_params - - def _test_ota_rssi(self, testcase_params): - testcase_params = self.compile_ota_rssi_test_params(testcase_params) - - self.setup_rssi_test(testcase_params) - rssi_result = self.run_rssi_test(testcase_params) - rssi_result['postprocessed_results'] = self.post_process_rssi_sweep( - rssi_result) - self.testclass_results.append(rssi_result) - self.plot_rssi_vs_time(rssi_result, - rssi_result['postprocessed_results'], 1) - self.plot_rssi_distribution(rssi_result['postprocessed_results']) - - def generate_test_cases(self, test_types, channels, modes, traffic_modes, - chamber_modes, orientations): - test_cases = [] - allowed_configs = { - 'VHT20': [ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 149, 153, - 157, 161 - ], - 'VHT40': [36, 44, 149, 157], - 'VHT80': [36, 149] - } - - for (channel, mode, traffic, chamber_mode, orientation, - test_type) in itertools.product(channels, modes, traffic_modes, - chamber_modes, orientations, - test_types): - if channel not in allowed_configs[mode]: - continue - test_name = test_type + '_ch{}_{}_{}_{}deg'.format( - channel, mode, traffic, orientation) - testcase_params = collections.OrderedDict( - channel=channel, - mode=mode, - active_traffic=(traffic == 'ActiveTraffic'), - traffic_type=self.user_params['rssi_test_params'] - ['traffic_type'], - chamber_mode=chamber_mode, - orientation=orientation) - test_function = self._test_ota_rssi - setattr(self, test_name, partial(test_function, testcase_params)) - test_cases.append(test_name) - return test_cases - - -class WifiOtaRssi_Accuracy_Test(WifiOtaRssiTest): - def __init__(self, controllers): - super().__init__(controllers) - self.tests = self.generate_test_cases(['test_rssi_vs_atten'], - [6, 36, 149], ['VHT20'], - ['ActiveTraffic'], - ['orientation'], - list(range(0, 360, 45))) - - -class WifiOtaRssi_StirrerVariation_Test(WifiOtaRssiTest): - def __init__(self, controllers): - WifiRssiTest.__init__(self, controllers) - self.tests = self.generate_test_cases(['test_rssi_variation'], - [6, 36, 149], ['VHT20'], - ['ActiveTraffic'], - ['StirrersOn'], [0]) - - -class WifiOtaRssi_TenDegree_Test(WifiOtaRssiTest): - def __init__(self, controllers): - WifiRssiTest.__init__(self, controllers) - self.tests = self.generate_test_cases(['test_rssi_over_orientation'], - [6, 36, 149], ['VHT20'], - ['ActiveTraffic'], - ['orientation'], - list(range(0, 360, 10))) diff --git a/acts/tests/google/wifi/WifiRttManagerTest.py b/acts/tests/google/wifi/WifiRttManagerTest.py deleted file mode 100644 index 743d89579d..0000000000 --- a/acts/tests/google/wifi/WifiRttManagerTest.py +++ /dev/null @@ -1,574 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright (C) 2016 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may not -# use this file except in compliance with the License. You may obtain a copy of -# the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations under -# the License. - -import pprint -import queue - -import acts.base_test -import acts.test_utils.wifi.wifi_test_utils as wutils -import acts.utils -from acts import asserts -from acts.controllers.sl4a_lib import rpc_client - -WifiEnums = wutils.WifiEnums - -# Macros for RttParam keywords -RttParam = WifiEnums.RttParam -# Macros for RttManager -Rtt = WifiEnums.Rtt -RttBW = WifiEnums.RttBW -RttPreamble = WifiEnums.RttPreamble -RttPeerType = WifiEnums.RttPeerType -RttType = WifiEnums.RttType - -ScanResult = WifiEnums.ScanResult -RTT_MARGIN_OF_ERROR = WifiEnums.RTT_MARGIN_OF_ERROR - - -class WifiRTTRangingError(Exception): - """Error in WifiScanner Rtt.""" - - -class WifiRttManagerTest(acts.base_test.BaseTestClass): - """Tests for wifi's RttManager APIs.""" - tests = None - MAX_RTT_AP = 10 - - def __init__(self, controllers): - acts.base_test.BaseTestClass.__init__(self, controllers) - self.tests = ("test_support_check", "test_invalid_params", - "test_capability_check", - "test_rtt_ranging_single_AP_stress", - "test_regular_scan_then_rtt_ranging_stress", - "test_gscan_then_rtt_ranging_stress") - - def setup_class(self): - self.dut = self.android_devices[0] - wutils.wifi_test_device_init(self.dut) - required_params = ("support_models", "stress_num", "vht80_5g", - "actual_distance") - self.unpack_userparams(required_params) - asserts.assert_true( - self.actual_distance >= 5, - "Actual distance should be no shorter than 5 meters.") - self.visible_networks = (self.vht80_5g, ) - self.default_rtt_params = { - RttParam.request_type: RttType.TYPE_TWO_SIDED, - RttParam.device_type: RttPeerType.PEER_TYPE_AP, - RttParam.preamble: RttPreamble.PREAMBLE_HT, - RttParam.bandwidth: RttBW.BW_80_SUPPORT - } - # Expected capability for devices that don't support RTT. - rtt_cap_neg = { - 'lcrSupported': False, - 'bwSupported': 0, - 'twoSided11McRttSupported': False, - 'preambleSupported': 0, - 'oneSidedRttSupported': False, - 'lciSupported': False - } - rtt_cap_shamu = { - 'lcrSupported': False, - 'bwSupported': 0x1C, - 'twoSided11McRttSupported': True, - 'preambleSupported': 6, - 'oneSidedRttSupported': False, - 'lciSupported': False - } - rtt_cap_bullhead = { - 'lcrSupported': True, - 'bwSupported': 0x1C, - 'twoSided11McRttSupported': True, - 'preambleSupported': 7, - 'oneSidedRttSupported': True, - 'lciSupported': True - } - rtt_cap_angler = { - 'lcrSupported': True, - 'bwSupported': 0x1C, - 'twoSided11McRttSupported': True, - 'preambleSupported': 6, - 'oneSidedRttSupported': False, - 'lciSupported': True - } - self.rtt_cap_table = { - "hammerhead": rtt_cap_neg, - "shamu": rtt_cap_shamu, - "volantis": rtt_cap_neg, - "volantisg": rtt_cap_neg, - "bullhead": rtt_cap_bullhead, - "angler": rtt_cap_angler - } - - """Helper Functions""" - - def invalid_params_logic(self, rtt_params): - try: - self.dut.droid.wifiRttStartRanging([rtt_params]) - except rpc_client.Sl4aApiError as e: - e_str = str(e) - asserts.assert_true( - "IllegalArgumentException" in e_str, - "Missing IllegalArgumentException in %s." % e_str) - msg = "Got expected exception with invalid param %s." % rtt_params - self.log.info(msg) - - def get_rtt_results(self, rtt_params): - """Starts RTT ranging and get results. - - Args: - rtt_params: A list of dicts each representing an RttParam. - - Returns: - Rtt ranging results. - """ - self.log.debug("Start ranging with:\n%s" % pprint.pformat(rtt_params)) - idx = self.dut.droid.wifiRttStartRanging(rtt_params) - event = None - try: - event = self.dut.ed.pop_events("WifiRttRanging%d" % idx, 30) - if event[0]["name"].endswith("onSuccess"): - results = event[0]["data"]["Results"] - result_len = len(results) - param_len = len(rtt_params) - asserts.assert_true(result_len == param_len, - "Expected %d results, got %d." % - (param_len, result_len)) - # Add acceptable margin of error to results, which will be used - # during result processing. - for i, r in enumerate(results): - bw_mode = rtt_params[i][RttParam.bandwidth] - r[RttParam.margin] = RTT_MARGIN_OF_ERROR[bw_mode] - self.log.debug(pprint.pformat(event)) - return event - except queue.Empty: - self.log.error("Waiting for RTT event timed out.") - return None - - def network_selector(self, network_info): - """Decides if a network should be used for rtt ranging. - - There are a few conditions: - 1. This network supports 80211mc. - 2. This network's info matches certain conditions. - - This is added to better control which networks to range against instead - of blindly use all 80211mc networks in air. - - Args: - network_info: A dict representing a WiFi network. - - Returns: - True if the input network should be used for ranging, False - otherwise. - """ - target_params = { - "is80211McRTTResponder": True, - WifiEnums.BSSID_KEY: self.vht80_5g[WifiEnums.BSSID_KEY], - } - for k, v in target_params.items(): - if k not in network_info: - return False - if type(network_info[k]) is str: - network_info[k] = network_info[k].lower() - v = v.lower() - if network_info[k] != v: - return False - return True - - def regular_scan_for_rtt_networks(self): - """Scans for 11mc-capable WiFi networks using regular wifi scan. - - Networks are selected based on self.network_selector. - - Returns: - A list of networks that have RTTResponders. - """ - wutils.start_wifi_connection_scan(self.dut) - networks = self.dut.droid.wifiGetScanResults() - rtt_networks = [] - for nw in networks: - if self.network_selector(nw): - rtt_networks.append(nw) - return rtt_networks - - def gscan_for_rtt_networks(self): - """Scans for 11mc-capable WiFi networks using wifi gscan. - - Networks are selected based on self.network_selector. - - Returns: - A list of networks that have RTTResponders. - """ - s = { - "reportEvents": WifiEnums.REPORT_EVENT_FULL_SCAN_RESULT, - "band": WifiEnums.WIFI_BAND_BOTH, - "periodInMs": 10000, - "numBssidsPerScan": 32 - } - idx = wutils.start_wifi_single_scan(self.android_devices[0], - s)["Index"] - self.log.info("Scan index is %d" % idx) - event_name = "WifiScannerScan%donFullResult" % idx - - def condition(event): - nw = event["data"]["Results"][0] - return self.network_selector(nw) - - rtt_networks = [] - try: - for i in range(len(self.visible_networks)): - event = self.dut.ed.wait_for_event(event_name, condition, 30) - rtt_networks.append(event["data"]["Results"][0]) - self.log.info("Waiting for gscan to finish.") - event_name = "WifiScannerScan%donResults" % idx - event = self.dut.ed.pop_event(event_name, 300) - total_network_cnt = len(event["data"]["Results"][0]["ScanResults"]) - self.log.info("Found %d networks in total." % total_network_cnt) - self.log.debug(rtt_networks) - return rtt_networks - except queue.Empty: - self.log.error("Timed out waiting for gscan result.") - - def process_rtt_events(self, events): - """Processes rtt ranging events. - - Validates RTT event types. - Validates RTT response status and measured RTT values. - Enforces success rate. - - Args: - events: A list of callback results from RTT ranging. - """ - total = aborted = failure = invalid = out_of_range = 0 - for e in events: - if e["name"].endswith("onAborted"): - aborted += 1 - if e["name"].endswith("onFailure"): - failure += 1 - if e["name"].endswith("onSuccess"): - results = e["data"]["Results"] - for r in results: - total += 1 - # Status needs to be "success". - status = r["status"] - if status != Rtt.STATUS_SUCCESS: - self.log.warning("Got error status %d." % status) - invalid += 1 - continue - # RTT value should be positive. - value = r["rtt"] - if value <= 0: - self.log.warning("Got error RTT value %d." % value) - invalid += 1 - continue - # Vadlidate values in successful responses. - acd = self.actual_distance - margin = r[RttParam.margin] - # If the distance is >= 0, check distance only. - d = r["distance"] / 100.0 - if d > 0: - # Distance should be in acceptable range. - is_d_valid = (acd - margin) <= d <= acd + (margin) - if not is_d_valid: - self.log.warning( - ("Reported distance %.2fm is out of the" - " acceptable range %.2f±%.2fm.") % (d, acd, - margin)) - out_of_range += 1 - continue - # Check if the RTT value is in range. - d = (value / 2) / 1E10 * wutils.SPEED_OF_LIGHT - is_rtt_valid = (acd - margin) <= d <= (acd + margin) - if not is_rtt_valid: - self.log.warning(( - "Distance calculated from RTT value %d - %.2fm is " - "out of the acceptable range %.2f±%dm.") % - (value, d, acd, margin)) - out_of_range += 1 - continue - # Check if the RSSI value is in range. - rssi = r["rssi"] - # average rssi in 0.5dB steps, e.g. 143 implies -71.5dB, - # so the valid range is 0 to 200 - is_rssi_valid = 0 <= rssi <= 200 - if not is_rssi_valid: - self.log.warning(("Reported RSSI %d is out of the" - " acceptable range 0-200") % rssi) - out_of_range += 1 - continue - self.log.info(( - "Processed %d RTT events. %d aborted, %s failed. Among" - " the %d responses in successful callbacks, %s are invalid, %s has" - " RTT values that are out of range.") % - (len(events), aborted, failure, total, invalid, - out_of_range)) - asserts.assert_true(total > 0, "No RTT response received.") - # Percentage of responses that are valid should be >= 90%. - valid_total = float(total - invalid) - valid_response_rate = valid_total / total - self.log.info("%.2f%% of the responses are valid." % - (valid_response_rate * 100)) - asserts.assert_true(valid_response_rate >= 0.9, - "Valid response rate is below 90%%.") - # Among the valid responses, the percentage of having an in-range RTT - # value should be >= 67%. - valid_value_rate = (total - invalid - out_of_range) / valid_total - self.log.info("%.2f%% of valid responses have in-range RTT value" % - (valid_value_rate * 100)) - msg = "In-range response rate is below 67%%." - asserts.assert_true(valid_value_rate >= 0.67, msg) - - def scan_then_rtt_ranging_stress_logic(self, scan_func): - """Test logic to scan then do rtt ranging based on the scan results. - - Steps: - 1. Start scan and get scan results. - 2. Filter out the networks that support rtt in scan results. - 3. Start rtt ranging against those networks that support rtt. - 4. Repeat - 5. Process RTT events. - - Args: - scan_func: A function that does a wifi scan and only returns the - networks that support rtt in the scan results. - - Returns: - True if rtt behaves as expected, False otherwise. - """ - total = self.stress_num - failed = 0 - all_results = [] - for i in range(total): - self.log.info("Iteration %d" % i) - rtt_networks = scan_func() - if not rtt_networks: - self.log.warning("Found no rtt network, skip this iteration.") - failed += 1 - continue - self.log.debug("Found rtt networks:%s" % rtt_networks) - rtt_params = [] - for rn in rtt_networks: - rtt_params.append(self.rtt_config_from_scan_result(rn)) - results = self.get_rtt_results(rtt_params) - if results: - self.log.debug(results) - all_results += results - self.process_rtt_events(all_results) - - def rtt_config_from_scan_result(self, scan_result): - """Creates an Rtt configuration based on the scan result of a network. - """ - 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 - - """Tests""" - - def test_invalid_params(self): - """Tests the sanity check function in RttManager. - """ - param_list = [{ - RttParam.device_type: 3 - }, { - RttParam.device_type: 1, - RttParam.request_type: 3 - }, { - RttParam.device_type: 1, - RttParam.request_type: 1, - RttParam.BSSID: None - }, { - RttParam.BSSID: "xxxxxxxx", - RttParam.number_burst: 1 - }, { - RttParam.number_burst: 0, - RttParam.num_samples_per_burst: -1 - }, { - RttParam.num_samples_per_burst: 32 - }, { - RttParam.num_samples_per_burst: 5, - RttParam.num_retries_per_measurement_frame: -1 - }, { - RttParam.num_retries_per_measurement_frame: 4 - }, { - RttParam.num_retries_per_measurement_frame: 2, - RttParam.num_retries_per_FTMR: -1 - }, { - RttParam.num_retries_per_FTMR: 4 - }] - for param in param_list: - self.invalid_params_logic(param) - return True - - def test_support_check(self): - """No device supports device-to-device RTT; only shamu and volantis - devices support device-to-ap RTT. - """ - model = acts.utils.trim_model_name(self.dut.model) - asserts.assert_true(self.dut.droid.wifiIsDeviceToDeviceRttSupported(), - "Device to device is supposed to be supported.") - if any([model in m for m in self.support_models]): - asserts.assert_true(self.dut.droid.wifiIsDeviceToApRttSupported(), - "%s should support device-to-ap RTT." % model) - self.log.info("%s supports device-to-ap RTT as expected." % model) - else: - asserts.assert_false( - self.dut.droid.wifiIsDeviceToApRttSupported(), - "%s should not support device-to-ap RTT." % model) - self.log.info( - ("%s does not support device-to-ap RTT as expected.") % model) - asserts.abort_class( - "Device %s does not support RTT, abort." % model) - return True - - def test_capability_check(self): - """Checks the capabilities params are reported as expected. - """ - caps = self.dut.droid.wifiRttGetCapabilities() - asserts.assert_true(caps, "Unable to get rtt capabilities.") - self.log.debug("Got rtt capabilities %s" % caps) - model = acts.utils.trim_model_name(self.dut.model) - asserts.assert_true(model in self.rtt_cap_table, - "Unknown model %s" % model) - expected_caps = self.rtt_cap_table[model] - for k, v in expected_caps.items(): - asserts.assert_true(k in caps, "%s missing in capabilities." % k) - asserts.assert_true(v == caps[k], "Expected %s for %s, got %s." % - (v, k, caps[k])) - return True - - def test_discovery(self): - """Make sure all the expected 11mc BSSIDs are discovered properly, and - they are all reported as 802.11mc Rtt Responder. - - Procedures: - 1. Scan for wifi networks. - - Expect: - All the RTT networks show up in scan results and their - "is80211McRTTResponder" is True. - All the non-RTT networks show up in scan results and their - "is80211McRTTResponder" is False. - """ - wutils.start_wifi_connection_scan(self.dut) - scan_results = self.dut.droid.wifiGetScanResults() - self.log.debug(scan_results) - for n in visible_networks: - asserts.assert_true( - wutils.match_networks(n, scan_results), - "Network %s was not discovered properly." % n) - return True - - def test_missing_bssid(self): - """Start Rtt ranging with a config that does not have BSSID set. - Should not get onSuccess. - """ - p = {} - p[RttParam.request_type] = RttType.TYPE_TWO_SIDED - p[RttParam.device_type] = RttPeerType.PEER_TYPE_AP - p[RttParam.preamble] = RttPreamble.PREAMBLE_VHT - p[RttParam.bandwidth] = RttBW.BW_80_SUPPORT - p[RttParam.frequency] = self.vht80_5g[WifiEnums.frequency_key] - p[RttParam.center_freq0] = self.vht80_5g[RttParam.center_freq0] - results = self.get_rtt_results([p]) - asserts.assert_true(results, "Did not get any result.") - self.log.info(pprint.pformat(results)) - - def test_rtt_ranging_single_AP_stress(self): - """Stress test for Rtt against one AP. - - Steps: - 1. Do RTT ranging against the self.vht80_5g BSSID. - 2. Repeat self.stress_num times. - 3. Verify RTT results. - """ - p = {} - p[RttParam.request_type] = RttType.TYPE_TWO_SIDED - p[RttParam.device_type] = RttPeerType.PEER_TYPE_AP - p[RttParam.preamble] = RttPreamble.PREAMBLE_VHT - p[RttParam.bandwidth] = RttBW.BW_80_SUPPORT - p[RttParam.BSSID] = self.vht80_5g[WifiEnums.BSSID_KEY] - p[RttParam.frequency] = self.vht80_5g[WifiEnums.frequency_key] - p[RttParam.center_freq0] = self.vht80_5g[RttParam.center_freq0] - p[RttParam.channel_width] = ScanResult.CHANNEL_WIDTH_80MHZ - all_results = [] - for i in range(self.stress_num): - self.log.info("RTT Ranging iteration %d" % (i + 1)) - results = self.get_rtt_results([p]) - if results: - all_results += results - else: - self.log.warning("Did not get result for iteration %d." % i) - frate = self.process_rtt_events(all_results) - - def test_regular_scan_then_rtt_ranging_stress(self): - """Stress test for regular scan then start rtt ranging against the RTT - compatible networks found by the scan. - - Steps: - 1. Start a WiFi connection scan. - 2. Get scan results. - 3. Find all the 11mc capable BSSIDs and choose the ones to use - (self.network_selector) - 4. Do RTT ranging against the selected BSSIDs, with the info from - the scan results. - 5. Repeat self.stress_num times. - 6. Verify RTT results. - """ - scan_func = self.regular_scan_for_rtt_networks - self.scan_then_rtt_ranging_stress_logic(scan_func) - - def test_gscan_then_rtt_ranging_stress(self): - """Stress test for gscan then start rtt ranging against the RTT - compatible networks found by the scan. - - Steps: - 1. Start a WifiScanner single shot scan on all channels. - 2. Wait for full scan results of the expected 11mc capable BSSIDs. - 3. Wait for single shot scan to finish on all channels. - 4. Do RTT ranging against the selected BSSIDs, with the info from - the scan results. - 5. Repeat self.stress_num times. - 6. Verify RTT results. - """ - scan_func = self.gscan_for_rtt_networks - self.scan_then_rtt_ranging_stress_logic(scan_func) diff --git a/acts/tests/google/wifi/WifiRvrTest.py b/acts/tests/google/wifi/WifiRvrTest.py deleted file mode 100644 index 8a8c8431f4..0000000000 --- a/acts/tests/google/wifi/WifiRvrTest.py +++ /dev/null @@ -1,853 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the 'License'); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an 'AS IS' BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import collections -import itertools -import json -import logging -import numpy -import os -import time -from acts import asserts -from acts import base_test -from acts import utils -from acts.controllers import iperf_server as ipf -from acts.controllers.utils_lib import ssh -from acts.metrics.loggers.blackbox import BlackboxMappedMetricLogger -from acts.test_utils.wifi import ota_chamber -from acts.test_utils.wifi import ota_sniffer -from acts.test_utils.wifi import wifi_performance_test_utils as wputils -from acts.test_utils.wifi import wifi_retail_ap as retail_ap -from acts.test_utils.wifi import wifi_test_utils as wutils -from functools import partial - - -class WifiRvrTest(base_test.BaseTestClass): - """Class to test WiFi rate versus range. - - This class implements WiFi rate versus range tests on single AP single STA - links. The class setups up the AP in the desired configurations, configures - and connects the phone to the AP, and runs iperf throughput test while - sweeping attenuation. For an example config file to run this test class see - example_connectivity_performance_ap_sta.json. - """ - - TEST_TIMEOUT = 6 - MAX_CONSECUTIVE_ZEROS = 3 - - def __init__(self, controllers): - base_test.BaseTestClass.__init__(self, controllers) - self.testcase_metric_logger = ( - BlackboxMappedMetricLogger.for_test_case()) - self.testclass_metric_logger = ( - BlackboxMappedMetricLogger.for_test_class()) - self.publish_testcase_metrics = True - - def setup_class(self): - """Initializes common test hardware and parameters. - - This function initializes hardwares and compiles parameters that are - common to all tests in this class. - """ - self.dut = self.android_devices[-1] - req_params = [ - 'RetailAccessPoints', 'rvr_test_params', 'testbed_params', - 'RemoteServer', 'main_network' - ] - opt_params = ['golden_files_list', 'OTASniffer'] - self.unpack_userparams(req_params, opt_params) - self.testclass_params = self.rvr_test_params - self.num_atten = self.attenuators[0].instrument.num_atten - self.iperf_server = self.iperf_servers[0] - self.remote_server = ssh.connection.SshConnection( - ssh.settings.from_config(self.RemoteServer[0]['ssh_config'])) - self.iperf_client = self.iperf_clients[0] - self.access_point = retail_ap.create(self.RetailAccessPoints)[0] - if hasattr(self, - 'OTASniffer') and self.testbed_params['sniffer_enable']: - self.sniffer = ota_sniffer.create(self.OTASniffer)[0] - self.log.info('Access Point Configuration: {}'.format( - self.access_point.ap_settings)) - self.log_path = os.path.join(logging.log_path, 'results') - os.makedirs(self.log_path, exist_ok=True) - if not hasattr(self, 'golden_files_list'): - if 'golden_results_path' in self.testbed_params: - self.golden_files_list = [ - os.path.join(self.testbed_params['golden_results_path'], - file) for file in - os.listdir(self.testbed_params['golden_results_path']) - ] - else: - self.log.warning('No golden files found.') - self.golden_files_list = [] - self.testclass_results = [] - - # Turn WiFi ON - if self.testclass_params.get('airplane_mode', 1): - self.log.info('Turning on airplane mode.') - asserts.assert_true(utils.force_airplane_mode(self.dut, True), - "Can not turn on airplane mode.") - wutils.wifi_toggle_state(self.dut, True) - - def teardown_test(self): - self.iperf_server.stop() - - def teardown_class(self): - # Turn WiFi OFF - for dev in self.android_devices: - wutils.wifi_toggle_state(dev, False) - self.process_testclass_results() - - def process_testclass_results(self): - """Saves plot with all test results to enable comparison.""" - # Plot and save all results - plots = collections.OrderedDict() - for result in self.testclass_results: - plot_id = (result['testcase_params']['channel'], - result['testcase_params']['mode']) - if plot_id not in plots: - plots[plot_id] = wputils.BokehFigure( - title='Channel {} {} ({})'.format( - result['testcase_params']['channel'], - result['testcase_params']['mode'], - result['testcase_params']['traffic_type']), - x_label='Attenuation (dB)', - primary_y_label='Throughput (Mbps)') - plots[plot_id].add_line(result['total_attenuation'], - result['throughput_receive'], - result['test_name'], - marker='circle') - figure_list = [] - for plot_id, plot in plots.items(): - plot.generate_figure() - figure_list.append(plot) - output_file_path = os.path.join(self.log_path, 'results.html') - wputils.BokehFigure.save_figures(figure_list, output_file_path) - - def pass_fail_check(self, rvr_result): - """Check the test result and decide if it passed or failed. - - Checks the RvR test result and compares to a throughput limites for - the same configuration. The pass/fail tolerances are provided in the - config file. - - Args: - rvr_result: dict containing attenuation, throughput and other data - """ - try: - throughput_limits = self.compute_throughput_limits(rvr_result) - except: - asserts.fail('Test failed: Golden file not found') - - failure_count = 0 - for idx, current_throughput in enumerate( - rvr_result['throughput_receive']): - if (current_throughput < throughput_limits['lower_limit'][idx] - or current_throughput > - throughput_limits['upper_limit'][idx]): - failure_count = failure_count + 1 - - # Set test metrics - rvr_result['metrics']['failure_count'] = failure_count - if self.publish_testcase_metrics: - self.testcase_metric_logger.add_metric('failure_count', - failure_count) - - # Assert pass or fail - if failure_count >= self.testclass_params['failure_count_tolerance']: - asserts.fail('Test failed. Found {} points outside limits.'.format( - failure_count)) - asserts.explicit_pass( - 'Test passed. Found {} points outside throughput limits.'.format( - failure_count)) - - def compute_throughput_limits(self, rvr_result): - """Compute throughput limits for current test. - - Checks the RvR test result and compares to a throughput limites for - the same configuration. The pass/fail tolerances are provided in the - config file. - - Args: - rvr_result: dict containing attenuation, throughput and other meta - data - Returns: - throughput_limits: dict containing attenuation and throughput limit data - """ - test_name = self.current_test_name - golden_path = next(file_name for file_name in self.golden_files_list - if test_name in file_name) - with open(golden_path, 'r') as golden_file: - golden_results = json.load(golden_file) - golden_attenuation = [ - att + golden_results['fixed_attenuation'] - for att in golden_results['attenuation'] - ] - attenuation = [] - lower_limit = [] - upper_limit = [] - for idx, current_throughput in enumerate( - rvr_result['throughput_receive']): - current_att = rvr_result['attenuation'][idx] + rvr_result[ - 'fixed_attenuation'] - att_distances = [ - abs(current_att - golden_att) - for golden_att in golden_attenuation - ] - sorted_distances = sorted(enumerate(att_distances), - key=lambda x: x[1]) - closest_indeces = [dist[0] for dist in sorted_distances[0:3]] - closest_throughputs = [ - golden_results['throughput_receive'][index] - for index in closest_indeces - ] - closest_throughputs.sort() - - attenuation.append(current_att) - lower_limit.append( - max( - closest_throughputs[0] - max( - self.testclass_params['abs_tolerance'], - closest_throughputs[0] * - self.testclass_params['pct_tolerance'] / 100), 0)) - upper_limit.append(closest_throughputs[-1] + max( - self.testclass_params['abs_tolerance'], closest_throughputs[-1] - * self.testclass_params['pct_tolerance'] / 100)) - throughput_limits = { - 'attenuation': attenuation, - 'lower_limit': lower_limit, - 'upper_limit': upper_limit - } - return throughput_limits - - def process_test_results(self, rvr_result): - """Saves plots and JSON formatted results. - - Args: - rvr_result: dict containing attenuation, throughput and other meta - data - """ - # Save output as text file - test_name = self.current_test_name - results_file_path = os.path.join( - self.log_path, '{}.json'.format(self.current_test_name)) - with open(results_file_path, 'w') as results_file: - json.dump(rvr_result, results_file, indent=4) - # Plot and save - figure = wputils.BokehFigure(title=test_name, - x_label='Attenuation (dB)', - primary_y_label='Throughput (Mbps)') - try: - golden_path = next(file_name - for file_name in self.golden_files_list - if test_name in file_name) - with open(golden_path, 'r') as golden_file: - golden_results = json.load(golden_file) - golden_attenuation = [ - att + golden_results['fixed_attenuation'] - for att in golden_results['attenuation'] - ] - throughput_limits = self.compute_throughput_limits(rvr_result) - shaded_region = { - 'x_vector': throughput_limits['attenuation'], - 'lower_limit': throughput_limits['lower_limit'], - 'upper_limit': throughput_limits['upper_limit'] - } - figure.add_line(golden_attenuation, - golden_results['throughput_receive'], - 'Golden Results', - color='green', - marker='circle', - shaded_region=shaded_region) - except: - self.log.warning('ValueError: Golden file not found') - - # Generate graph annotatios - hover_text = [ - 'TX MCS = {0} ({1:.1f}%). RX MCS = {2} ({3:.1f}%)'.format( - curr_llstats['summary']['common_tx_mcs'], - curr_llstats['summary']['common_tx_mcs_freq'] * 100, - curr_llstats['summary']['common_rx_mcs'], - curr_llstats['summary']['common_rx_mcs_freq'] * 100) - for curr_llstats in rvr_result['llstats'] - ] - figure.add_line(rvr_result['total_attenuation'], - rvr_result['throughput_receive'], - 'Test Results', - hover_text=hover_text, - color='red', - marker='circle') - - output_file_path = os.path.join(self.log_path, - '{}.html'.format(test_name)) - figure.generate_figure(output_file_path) - - #Set test metrics - rvr_result['metrics'] = {} - rvr_result['metrics']['peak_tput'] = max( - rvr_result['throughput_receive']) - if self.publish_testcase_metrics: - self.testcase_metric_logger.add_metric( - 'peak_tput', rvr_result['metrics']['peak_tput']) - - tput_below_limit = [ - tput < self.testclass_params['tput_metric_targets'][ - rvr_result['testcase_params']['mode']]['high'] - for tput in rvr_result['throughput_receive'] - ] - rvr_result['metrics']['high_tput_range'] = -1 - for idx in range(len(tput_below_limit)): - if all(tput_below_limit[idx:]): - if idx == 0: - #Throughput was never above limit - rvr_result['metrics']['high_tput_range'] = -1 - else: - rvr_result['metrics']['high_tput_range'] = rvr_result[ - 'total_attenuation'][max(idx, 1) - 1] - break - if self.publish_testcase_metrics: - self.testcase_metric_logger.add_metric( - 'high_tput_range', rvr_result['metrics']['high_tput_range']) - - tput_below_limit = [ - tput < self.testclass_params['tput_metric_targets'][ - rvr_result['testcase_params']['mode']]['low'] - for tput in rvr_result['throughput_receive'] - ] - for idx in range(len(tput_below_limit)): - if all(tput_below_limit[idx:]): - rvr_result['metrics']['low_tput_range'] = rvr_result[ - 'total_attenuation'][max(idx, 1) - 1] - break - else: - rvr_result['metrics']['low_tput_range'] = -1 - if self.publish_testcase_metrics: - self.testcase_metric_logger.add_metric( - 'low_tput_range', rvr_result['metrics']['low_tput_range']) - - def run_rvr_test(self, testcase_params): - """Test function to run RvR. - - The function runs an RvR test in the current device/AP configuration. - Function is called from another wrapper function that sets up the - testbed for the RvR test - - Args: - testcase_params: dict containing test-specific parameters - Returns: - rvr_result: dict containing rvr_results and meta data - """ - self.log.info('Start running RvR') - # Refresh link layer stats before test - llstats_obj = wputils.LinkLayerStats(self.dut) - zero_counter = 0 - throughput = [] - llstats = [] - rssi = [] - for atten in testcase_params['atten_range']: - for dev in self.android_devices: - if not wputils.health_check(dev, 5, 50): - asserts.skip('DUT health check failed. Skipping test.') - # Set Attenuation - for attenuator in self.attenuators: - attenuator.set_atten(atten, strict=False) - # Refresh link layer stats - llstats_obj.update_stats() - # Setup sniffer - if self.testbed_params['sniffer_enable']: - self.sniffer.start_capture( - network=testcase_params['test_network'], - chan=int(testcase_params['channel']), - bw=int(testcase_params['mode'][3:]), - duration=self.testclass_params['iperf_duration'] / 5) - # Start iperf session - self.iperf_server.start(tag=str(atten)) - rssi_future = wputils.get_connected_rssi_nb( - self.dut, self.testclass_params['iperf_duration'] - 1, 1, 1) - client_output_path = self.iperf_client.start( - testcase_params['iperf_server_address'], - testcase_params['iperf_args'], str(atten), - self.testclass_params['iperf_duration'] + self.TEST_TIMEOUT) - server_output_path = self.iperf_server.stop() - rssi_result = rssi_future.result() - current_rssi = { - 'signal_poll_rssi': rssi_result['signal_poll_rssi']['mean'], - 'chain_0_rssi': rssi_result['chain_0_rssi']['mean'], - 'chain_1_rssi': rssi_result['chain_1_rssi']['mean'] - } - rssi.append(current_rssi) - # Stop sniffer - if self.testbed_params['sniffer_enable']: - self.sniffer.stop_capture(tag=str(atten)) - # Parse and log result - if testcase_params['use_client_output']: - iperf_file = client_output_path - else: - iperf_file = server_output_path - try: - iperf_result = ipf.IPerfResult(iperf_file) - curr_throughput = numpy.mean(iperf_result.instantaneous_rates[ - self.testclass_params['iperf_ignored_interval']:-1] - ) * 8 * (1.024**2) - except: - self.log.warning( - 'ValueError: Cannot get iperf result. Setting to 0') - curr_throughput = 0 - throughput.append(curr_throughput) - llstats_obj.update_stats() - curr_llstats = llstats_obj.llstats_incremental.copy() - llstats.append(curr_llstats) - self.log.info( - ('Throughput at {0:.2f} dB is {1:.2f} Mbps. ' - 'RSSI = {2:.2f} [{3:.2f}, {4:.2f}].').format( - atten, curr_throughput, current_rssi['signal_poll_rssi'], - current_rssi['chain_0_rssi'], - current_rssi['chain_1_rssi'])) - if curr_throughput == 0 and ( - current_rssi['signal_poll_rssi'] < -80 - or numpy.isnan(current_rssi['signal_poll_rssi'])): - zero_counter = zero_counter + 1 - else: - zero_counter = 0 - if zero_counter == self.MAX_CONSECUTIVE_ZEROS: - self.log.info( - 'Throughput stable at 0 Mbps. Stopping test now.') - throughput.extend( - [0] * - (len(testcase_params['atten_range']) - len(throughput))) - break - for attenuator in self.attenuators: - attenuator.set_atten(0, strict=False) - # Compile test result and meta data - rvr_result = collections.OrderedDict() - rvr_result['test_name'] = self.current_test_name - rvr_result['testcase_params'] = testcase_params.copy() - rvr_result['ap_settings'] = self.access_point.ap_settings.copy() - rvr_result['fixed_attenuation'] = self.testbed_params[ - 'fixed_attenuation'][str(testcase_params['channel'])] - rvr_result['attenuation'] = list(testcase_params['atten_range']) - rvr_result['total_attenuation'] = [ - att + rvr_result['fixed_attenuation'] - for att in rvr_result['attenuation'] - ] - rvr_result['rssi'] = rssi - rvr_result['throughput_receive'] = throughput - rvr_result['llstats'] = llstats - return rvr_result - - def setup_ap(self, testcase_params): - """Sets up the access point in the configuration required by the test. - - Args: - testcase_params: dict containing AP and other test params - """ - band = self.access_point.band_lookup_by_channel( - testcase_params['channel']) - if '2G' in band: - frequency = wutils.WifiEnums.channel_2G_to_freq[ - testcase_params['channel']] - else: - frequency = wutils.WifiEnums.channel_5G_to_freq[ - testcase_params['channel']] - if frequency in wutils.WifiEnums.DFS_5G_FREQUENCIES: - self.access_point.set_region(self.testbed_params['DFS_region']) - else: - self.access_point.set_region(self.testbed_params['default_region']) - self.access_point.set_channel(band, testcase_params['channel']) - self.access_point.set_bandwidth(band, testcase_params['mode']) - self.log.info('Access Point Configuration: {}'.format( - self.access_point.ap_settings)) - - def setup_dut(self, testcase_params): - """Sets up the DUT in the configuration required by the test. - - Args: - testcase_params: dict containing AP and other test params - """ - # Check battery level before test - if not wputils.health_check( - self.dut, 20) and testcase_params['traffic_direction'] == 'UL': - asserts.skip('Overheating or Battery level low. Skipping test.') - # Turn screen off to preserve battery - self.dut.go_to_sleep() - if wputils.validate_network(self.dut, - testcase_params['test_network']['SSID']): - self.log.info('Already connected to desired network') - else: - wutils.reset_wifi(self.dut) - wutils.set_wifi_country_code(self.dut, - self.testclass_params['country_code']) - testcase_params['test_network']['channel'] = testcase_params[ - 'channel'] - wutils.wifi_connect(self.dut, - testcase_params['test_network'], - num_of_tries=5, - check_connectivity=True) - self.dut_ip = self.dut.droid.connectivityGetIPv4Addresses('wlan0')[0] - - def setup_rvr_test(self, testcase_params): - """Function that gets devices ready for the test. - - Args: - testcase_params: dict containing test-specific parameters - """ - # Configure AP - self.setup_ap(testcase_params) - # Set attenuator to 0 dB - for attenuator in self.attenuators: - attenuator.set_atten(0, strict=False) - # Reset, configure, and connect DUT - self.setup_dut(testcase_params) - # Wait before running the first wifi test - first_test_delay = self.testclass_params.get('first_test_delay', 600) - if first_test_delay > 0 and len(self.testclass_results) == 0: - self.log.info('Waiting before the first RvR test.') - time.sleep(first_test_delay) - self.setup_dut(testcase_params) - # Get iperf_server address - if isinstance(self.iperf_server, ipf.IPerfServerOverAdb): - testcase_params['iperf_server_address'] = self.dut_ip - else: - testcase_params[ - 'iperf_server_address'] = wputils.get_server_address( - self.remote_server, self.dut_ip, '255.255.255.0') - - def compile_test_params(self, testcase_params): - """Function that completes all test params based on the test name. - - Args: - testcase_params: dict containing test-specific parameters - """ - num_atten_steps = int((self.testclass_params['atten_stop'] - - self.testclass_params['atten_start']) / - self.testclass_params['atten_step']) - testcase_params['atten_range'] = [ - self.testclass_params['atten_start'] + - x * self.testclass_params['atten_step'] - for x in range(0, num_atten_steps) - ] - band = self.access_point.band_lookup_by_channel( - testcase_params['channel']) - testcase_params['test_network'] = self.main_network[band] - if (testcase_params['traffic_direction'] == 'DL' - and not isinstance(self.iperf_server, ipf.IPerfServerOverAdb) - ) or (testcase_params['traffic_direction'] == 'UL' - and isinstance(self.iperf_server, ipf.IPerfServerOverAdb)): - testcase_params['iperf_args'] = wputils.get_iperf_arg_string( - duration=self.testclass_params['iperf_duration'], - reverse_direction=1, - traffic_type=testcase_params['traffic_type']) - testcase_params['use_client_output'] = True - else: - testcase_params['iperf_args'] = wputils.get_iperf_arg_string( - duration=self.testclass_params['iperf_duration'], - reverse_direction=0, - traffic_type=testcase_params['traffic_type']) - testcase_params['use_client_output'] = False - return testcase_params - - def _test_rvr(self, testcase_params): - """ Function that gets called for each test case - - Args: - testcase_params: dict containing test-specific parameters - """ - # Compile test parameters from config and test name - testcase_params = self.compile_test_params(testcase_params) - - # Prepare devices and run test - self.setup_rvr_test(testcase_params) - rvr_result = self.run_rvr_test(testcase_params) - - # Post-process results - self.testclass_results.append(rvr_result) - self.process_test_results(rvr_result) - self.pass_fail_check(rvr_result) - - def generate_test_cases(self, channels, modes, traffic_types, - traffic_directions): - """Function that auto-generates test cases for a test class.""" - test_cases = [] - allowed_configs = { - 'VHT20': [ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 64, 100, - 116, 132, 140, 149, 153, 157, 161 - ], - 'VHT40': [36, 44, 100, 149, 157], - 'VHT80': [36, 100, 149] - } - - for channel, mode, traffic_type, traffic_direction in itertools.product( - channels, modes, traffic_types, traffic_directions): - if channel not in allowed_configs[mode]: - continue - test_name = 'test_rvr_{}_{}_ch{}_{}'.format( - traffic_type, traffic_direction, channel, mode) - test_params = collections.OrderedDict( - channel=channel, - mode=mode, - traffic_type=traffic_type, - traffic_direction=traffic_direction) - setattr(self, test_name, partial(self._test_rvr, test_params)) - test_cases.append(test_name) - return test_cases - - -# Classes defining test suites -class WifiRvr_2GHz_Test(WifiRvrTest): - def __init__(self, controllers): - super().__init__(controllers) - self.tests = self.generate_test_cases(channels=[1, 6, 11], - modes=['VHT20'], - traffic_types=['TCP'], - traffic_directions=['DL', 'UL']) - - -class WifiRvr_UNII1_Test(WifiRvrTest): - def __init__(self, controllers): - super().__init__(controllers) - self.tests = self.generate_test_cases( - channels=[36, 40, 44, 48], - modes=['VHT20', 'VHT40', 'VHT80'], - traffic_types=['TCP'], - traffic_directions=['DL', 'UL']) - - -class WifiRvr_UNII3_Test(WifiRvrTest): - def __init__(self, controllers): - super().__init__(controllers) - self.tests = self.generate_test_cases( - channels=[149, 153, 157, 161], - modes=['VHT20', 'VHT40', 'VHT80'], - traffic_types=['TCP'], - traffic_directions=['DL', 'UL']) - - -class WifiRvr_SampleDFS_Test(WifiRvrTest): - def __init__(self, controllers): - super().__init__(controllers) - self.tests = self.generate_test_cases( - channels=[64, 100, 116, 132, 140], - modes=['VHT20', 'VHT40', 'VHT80'], - traffic_types=['TCP'], - traffic_directions=['DL', 'UL']) - - -class WifiRvr_SampleUDP_Test(WifiRvrTest): - def __init__(self, controllers): - super().__init__(controllers) - self.tests = self.generate_test_cases( - channels=[6, 36, 149], - modes=['VHT20', 'VHT40', 'VHT80'], - traffic_types=['UDP'], - traffic_directions=['DL', 'UL']) - - -class WifiRvr_TCP_All_Test(WifiRvrTest): - def __init__(self, controllers): - super().__init__(controllers) - self.tests = self.generate_test_cases( - channels=[1, 6, 11, 36, 40, 44, 48, 149, 153, 157, 161], - modes=['VHT20', 'VHT40', 'VHT80'], - traffic_types=['TCP'], - traffic_directions=['DL', 'UL']) - - -class WifiRvr_TCP_Downlink_Test(WifiRvrTest): - def __init__(self, controllers): - super().__init__(controllers) - self.tests = self.generate_test_cases( - channels=[1, 6, 11, 36, 40, 44, 48, 149, 153, 157, 161], - modes=['VHT20', 'VHT40', 'VHT80'], - traffic_types=['TCP'], - traffic_directions=['DL']) - - -class WifiRvr_TCP_Uplink_Test(WifiRvrTest): - def __init__(self, controllers): - super().__init__(controllers) - self.tests = self.generate_test_cases( - channels=[1, 6, 11, 36, 40, 44, 48, 149, 153, 157, 161], - modes=['VHT20', 'VHT40', 'VHT80'], - traffic_types=['TCP'], - traffic_directions=['UL']) - - -# Over-the air version of RVR tests -class WifiOtaRvrTest(WifiRvrTest): - """Class to test over-the-air RvR - - This class implements measures WiFi RvR tests in an OTA chamber. It enables - setting turntable orientation and other chamber parameters to study - performance in varying channel conditions - """ - def __init__(self, controllers): - base_test.BaseTestClass.__init__(self, controllers) - self.testcase_metric_logger = ( - BlackboxMappedMetricLogger.for_test_case()) - self.testclass_metric_logger = ( - BlackboxMappedMetricLogger.for_test_class()) - self.publish_testcase_metrics = False - - def setup_class(self): - WifiRvrTest.setup_class(self) - self.ota_chamber = ota_chamber.create( - self.user_params['OTAChamber'])[0] - - def teardown_class(self): - WifiRvrTest.teardown_class(self) - self.ota_chamber.reset_chamber() - - def extract_test_id(self, testcase_params, id_fields): - test_id = collections.OrderedDict( - (param, testcase_params[param]) for param in id_fields) - return test_id - - def process_testclass_results(self): - """Saves plot with all test results to enable comparison.""" - # Plot individual test id results raw data and compile metrics - plots = collections.OrderedDict() - compiled_data = collections.OrderedDict() - for result in self.testclass_results: - test_id = tuple( - self.extract_test_id( - result['testcase_params'], - ['channel', 'mode', 'traffic_type', 'traffic_direction' - ]).items()) - if test_id not in plots: - # Initialize test id data when not present - compiled_data[test_id] = {'throughput': [], 'metrics': {}} - compiled_data[test_id]['metrics'] = { - key: [] - for key in result['metrics'].keys() - } - plots[test_id] = wputils.BokehFigure( - title='Channel {} {} ({} {})'.format( - result['testcase_params']['channel'], - result['testcase_params']['mode'], - result['testcase_params']['traffic_type'], - result['testcase_params']['traffic_direction']), - x_label='Attenuation (dB)', - primary_y_label='Throughput (Mbps)') - # Compile test id data and metrics - compiled_data[test_id]['throughput'].append( - result['throughput_receive']) - compiled_data[test_id]['total_attenuation'] = result[ - 'total_attenuation'] - for metric_key, metric_value in result['metrics'].items(): - compiled_data[test_id]['metrics'][metric_key].append( - metric_value) - # Add test id to plots - plots[test_id].add_line(result['total_attenuation'], - result['throughput_receive'], - result['test_name'], - width=1, - style='dashed', - marker='circle') - - # Compute average RvRs and compount metrics over orientations - for test_id, test_data in compiled_data.items(): - test_id_dict = dict(test_id) - metric_tag = '{}_{}_ch{}_{}'.format( - test_id_dict['traffic_type'], - test_id_dict['traffic_direction'], test_id_dict['channel'], - test_id_dict['mode']) - high_tput_hit_freq = numpy.mean( - numpy.not_equal(test_data['metrics']['high_tput_range'], -1)) - self.testclass_metric_logger.add_metric( - '{}.high_tput_hit_freq'.format(metric_tag), high_tput_hit_freq) - for metric_key, metric_value in test_data['metrics'].items(): - metric_key = "{}.avg_{}".format(metric_tag, metric_key) - metric_value = numpy.mean(metric_value) - self.testclass_metric_logger.add_metric( - metric_key, metric_value) - test_data['avg_rvr'] = numpy.mean(test_data['throughput'], 0) - test_data['median_rvr'] = numpy.median(test_data['throughput'], 0) - plots[test_id].add_line(test_data['total_attenuation'], - test_data['avg_rvr'], - legend='Average Throughput', - marker='circle') - plots[test_id].add_line(test_data['total_attenuation'], - test_data['median_rvr'], - legend='Median Throughput', - marker='square') - - figure_list = [] - for test_id, plot in plots.items(): - plot.generate_figure() - figure_list.append(plot) - output_file_path = os.path.join(self.log_path, 'results.html') - wputils.BokehFigure.save_figures(figure_list, output_file_path) - - def setup_rvr_test(self, testcase_params): - # Set turntable orientation - self.ota_chamber.set_orientation(testcase_params['orientation']) - # Continue test setup - WifiRvrTest.setup_rvr_test(self, testcase_params) - - def generate_test_cases(self, channels, modes, angles, traffic_types, - directions): - test_cases = [] - allowed_configs = { - 'VHT20': [ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 149, 153, - 157, 161 - ], - 'VHT40': [36, 44, 149, 157], - 'VHT80': [36, 149] - } - for channel, mode, angle, traffic_type, direction in itertools.product( - channels, modes, angles, traffic_types, directions): - if channel not in allowed_configs[mode]: - continue - testcase_name = 'test_rvr_{}_{}_ch{}_{}_{}deg'.format( - traffic_type, direction, channel, mode, angle) - test_params = collections.OrderedDict(channel=channel, - mode=mode, - traffic_type=traffic_type, - traffic_direction=direction, - orientation=angle) - setattr(self, testcase_name, partial(self._test_rvr, test_params)) - test_cases.append(testcase_name) - return test_cases - - -class WifiOtaRvr_StandardOrientation_Test(WifiOtaRvrTest): - def __init__(self, controllers): - WifiOtaRvrTest.__init__(self, controllers) - self.tests = self.generate_test_cases( - [1, 6, 11, 36, 40, 44, 48, 149, 153, 157, 161], - ['VHT20', 'VHT40', 'VHT80'], list(range(0, 360, - 45)), ['TCP'], ['DL']) - - -class WifiOtaRvr_SampleChannel_Test(WifiOtaRvrTest): - def __init__(self, controllers): - WifiOtaRvrTest.__init__(self, controllers) - self.tests = self.generate_test_cases([6], ['VHT20'], - list(range(0, 360, 45)), ['TCP'], - ['DL']) - self.tests.extend( - self.generate_test_cases([36, 149], ['VHT80'], - list(range(0, 360, 45)), ['TCP'], ['DL'])) - - -class WifiOtaRvr_SingleOrientation_Test(WifiOtaRvrTest): - def __init__(self, controllers): - WifiOtaRvrTest.__init__(self, controllers) - self.tests = self.generate_test_cases( - [6, 36, 40, 44, 48, 149, 153, 157, 161], - ['VHT20', 'VHT40', 'VHT80'], [0], ['TCP'], ['DL', 'UL']) diff --git a/acts/tests/google/wifi/WifiRvrTwTest.py b/acts/tests/google/wifi/WifiRvrTwTest.py deleted file mode 100644 index 2f9dc12fdd..0000000000 --- a/acts/tests/google/wifi/WifiRvrTwTest.py +++ /dev/null @@ -1,480 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2018 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import itertools -import pprint -import time - -import acts.signals -import acts.test_utils.wifi.wifi_test_utils as wutils - -from acts import asserts -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest -from acts.controllers import iperf_server as ipf - -import json -import logging -import math -import os -from acts import utils -import csv - -import serial -import sys - - -WifiEnums = wutils.WifiEnums - - -class WifiRvrTWTest(WifiBaseTest): - """ Tests for wifi RVR performance - - Test Bed Requirement: - * One Android device - * Wi-Fi networks visible to the device - """ - TEST_TIMEOUT = 10 - - def setup_class(self): - super().setup_class() - - self.dut = self.android_devices[0] - wutils.wifi_test_device_init(self.dut) - - req_params = [ "iot_networks","rvr_test_params"] - opt_params = [ "angle_params","usb_port"] - self.unpack_userparams(req_param_names=req_params, - opt_param_names=opt_params) - - asserts.assert_true( - len(self.iot_networks) > 0, - "Need at least one iot network with psk.") - - wutils.wifi_toggle_state(self.dut, True) - if "rvr_test_params" in self.user_params: - self.iperf_server = self.iperf_servers[0] - self.MaxdB= self.rvr_test_params ["rvr_atten_MaxDB"] - self.MindB= self.rvr_test_params ["rvr_atten_MinDB"] - self.stepdB= self.rvr_test_params ["rvr_atten_step"] - - if "angle_params" in self.user_params: - self.angle = self.angle_params - - if "usb_port" in self.user_params: - self.T1=self.readport(self.usb_port["turntable"]) - self.ATT1=self.readport(self.usb_port["atten1"]) - self.ATT2=self.readport(self.usb_port["atten2"]) - self.ATT3=self.readport(self.usb_port["atten3"]) - - # create hashmap for testcase name and SSIDs - self.iot_test_prefix = "test_iot_connection_to_" - self.ssid_map = {} - for network in self.iot_networks: - SSID = network['SSID'].replace('-','_') - self.ssid_map[SSID] = network - - # create folder for rvr test result - self.log_path = os.path.join(logging.log_path, "rvr_results") - os.makedirs(self.log_path, exist_ok=True) - - Header=("test_SSID","Turn table (angle)","Attenuator(dBm)", - "TX throughput (Mbps)","RX throughput (Mbps)", - "RSSI","Link speed","Frequency") - self.csv_write(Header) - - def setup_test(self): - self.dut.droid.wakeLockAcquireBright() - self.dut.droid.wakeUpNow() - - def teardown_test(self): - self.dut.droid.wakeLockRelease() - self.dut.droid.goToSleepNow() - - def teardown_class(self): - if "rvr_test_params" in self.user_params: - self.iperf_server.stop() - - def on_fail(self, test_name, begin_time): - self.dut.take_bug_report(test_name, begin_time) - self.dut.cat_adb_log(test_name, begin_time) - - """Helper Functions""" - - def csv_write(self,data): - """Output .CSV file for test result. - - Args: - data: Dict containing attenuation, throughput and other meta data. - """ - with open("{}/Result.csv".format(self.log_path), "a", newline="") as csv_file: - csv_writer = csv.writer(csv_file,delimiter=',') - csv_writer.writerow(data) - csv_file.close() - - def readport(self,com): - """Read com port for current test. - - Args: - com: Attenuator or turn table com port - """ - port=serial.Serial(com,9600,timeout=1) - time.sleep(1) - return port - - def getdB(self,port): - """Get attenuator dB for current test. - - Args: - port: Attenuator com port - """ - port.write('V?;'.encode()) - dB=port.readline().decode() - dB=dB.strip(';') - dB=dB[dB.find('V')+1:] - return int(dB) - - def setdB(self,port,dB): - """Setup attenuator dB for current test. - - Args: - port: Attenuator com port - dB: Attenuator setup dB - """ - if dB<0: - dB=0 - elif dB>101: - dB=101 - self.log.info("Set dB to "+str(dB)) - InputdB=str('V')+str(dB)+str(';') - port.write(InputdB.encode()) - time.sleep(0.1) - - def set_Three_Att_dB(self,port1,port2,port3,dB): - """Setup 3 attenuator dB for current test. - - Args: - port1: Attenuator1 com port - port1: Attenuator2 com port - port1: Attenuator com port - dB: Attenuator setup dB - """ - self.setdB(port1,dB) - self.setdB(port2,dB) - self.setdB(port3,dB) - self.checkdB(port1,dB) - self.checkdB(port2,dB) - self.checkdB(port3,dB) - - def checkdB(self,port,dB): - """Check attenuator dB for current test. - - Args: - port: Attenuator com port - dB: Attenuator setup dB - """ - retry=0 - while self.getdB(port)!=dB and retry<10: - retry=retry+1 - self.log.info("Current dB = "+str(self.getdB(port))) - self.log.info("Fail to set Attenuator to "+str(dB)+", " - +str(retry)+" times try to reset") - self.setdB(port,dB) - if retry ==10: - self.log.info("Retry Attenuator fail for 9 cycles, end test!") - sys.exit() - return 0 - - def getDG(self,port): - """Get turn table angle for current test. - - Args: - port: Turn table com port - """ - DG = "" - port.write('DG?;'.encode()) - time.sleep(0.1) - data = port.readline().decode('utf-8') - for i in range(len(data)): - if (data[i].isdigit()) == True: - DG = DG + data[i] - if DG == "": - return -1 - return int(DG) - - def setDG(self,port,DG): - """Setup turn table angle for current test. - - Args: - port: Turn table com port - DG: Turn table setup angle - """ - if DG>359: - DG=359 - elif DG<0: - DG=0 - self.log.info("Set angle to "+str(DG)) - InputDG=str('DG')+str(DG)+str(';') - port.write(InputDG.encode()) - - def checkDG(self,port,DG): - """Check turn table angle for current test. - - Args: - port: Turn table com port - DG: Turn table setup angle - """ - retrytime = self.TEST_TIMEOUT - retry = 0 - while self.getDG(port)!=DG and retry<retrytime: - retry=retry+1 - self.log.info('Current angle = '+str(self.getDG(port))) - self.log.info('Fail set angle to '+str(DG)+', '+str(retry)+' times try to reset') - self.setDG(port,DG) - time.sleep(10) - if retry == retrytime: - self.log.info('Retry turntable fail for '+str(retry)+' cycles, end test!') - sys.exit() - return 0 - - def getwifiinfo(self): - """Get WiFi RSSI/ link speed/ frequency for current test. - - Returns: - [RSSI,LS,FR]: WiFi RSSI/ link speed/ frequency - """ - def is_number(string): - for i in string: - if i.isdigit() == False: - if (i=="-" or i=="."): - continue - return str(-1) - return string - - try: - cmd = "adb shell iw wlan0 link" - wifiinfo = utils.subprocess.check_output(cmd,shell=True, - timeout=self.TEST_TIMEOUT) - # Check RSSI - RSSI = wifiinfo.decode("utf-8")[wifiinfo.decode("utf-8").find("signal:") + - 7:wifiinfo.decode("utf-8").find("dBm") - 1] - RSSI = RSSI.strip(' ') - RSSI = is_number(RSSI) - # Check link speed - LS = wifiinfo.decode("utf-8")[wifiinfo.decode("utf-8").find("bitrate:") + - 8:wifiinfo.decode("utf-8").find("Bit/s") - 2] - LS = LS.strip(' ') - LS = is_number(LS) - # Check frequency - FR = wifiinfo.decode("utf-8")[wifiinfo.decode("utf-8").find("freq:") + - 6:wifiinfo.decode("utf-8").find("freq:") + 10] - FR = FR.strip(' ') - FR = is_number(FR) - except: - return -1, -1, -1 - return [RSSI,LS,FR] - - def post_process_results(self, rvr_result): - """Saves JSON formatted results. - - Args: - rvr_result: Dict containing attenuation, throughput and other meta - data - """ - # Save output as text file - data=(rvr_result["test_name"],rvr_result["test_angle"],rvr_result["test_dB"], - rvr_result["throughput_TX"][0],rvr_result["throughput_RX"][0], - rvr_result["test_RSSI"],rvr_result["test_LS"],rvr_result["test_FR"]) - self.csv_write(data) - - results_file_path = "{}/{}_angle{}_{}dB.json".format(self.log_path, - self.ssid, - self.angle[self.ag],self.DB) - with open(results_file_path, 'w') as results_file: - json.dump(rvr_result, results_file, indent=4) - - def connect_to_wifi_network(self, network): - """Connection logic for psk wifi networks. - - Args: - params: Dictionary with network info. - """ - SSID = network[WifiEnums.SSID_KEY] - self.dut.ed.clear_all_events() - wutils.start_wifi_connection_scan(self.dut) - scan_results = self.dut.droid.wifiGetScanResults() - wutils.assert_network_in_list({WifiEnums.SSID_KEY: SSID}, scan_results) - wutils.wifi_connect(self.dut, network, num_of_tries=3) - - def run_iperf_client(self, network): - """Run iperf TX throughput after connection. - - Args: - params: Dictionary with network info. - - Returns: - rvr_result: Dict containing rvr_results - """ - rvr_result = [] - self.iperf_server.start(tag="TX_server_{}_angle{}_{}dB".format( - self.ssid,self.angle[self.ag],self.DB)) - wait_time = 5 - SSID = network[WifiEnums.SSID_KEY] - self.log.info("Starting iperf traffic TX through {}".format(SSID)) - time.sleep(wait_time) - port_arg = "-p {} -J {}".format(self.iperf_server.port, - self.rvr_test_params["iperf_port_arg"]) - success, data = self.dut.run_iperf_client( - self.rvr_test_params["iperf_server_address"], - port_arg, - timeout=self.rvr_test_params["iperf_duration"] + self.TEST_TIMEOUT) - # Parse and log result - client_output_path = os.path.join( - self.iperf_server.log_path, "IperfDUT,{},TX_client_{}_angle{}_{}dB".format( - self.iperf_server.port,self.ssid,self.angle[self.ag],self.DB)) - with open(client_output_path, 'w') as out_file: - out_file.write("\n".join(data)) - self.iperf_server.stop() - - iperf_file = self.iperf_server.log_files[-1] - try: - iperf_result = ipf.IPerfResult(iperf_file) - curr_throughput = (math.fsum(iperf_result.instantaneous_rates[ - self.rvr_test_params["iperf_ignored_interval"]:-1]) / len( - iperf_result.instantaneous_rates[self.rvr_test_params[ - "iperf_ignored_interval"]:-1])) * 8 * (1.024**2) - except: - self.log.warning( - "ValueError: Cannot get iperf result. Setting to 0") - curr_throughput = 0 - rvr_result.append(curr_throughput) - self.log.info("TX Throughput at {0:.2f} dB is {1:.2f} Mbps".format( - self.DB, curr_throughput)) - - self.log.debug(pprint.pformat(data)) - asserts.assert_true(success, "Error occurred in iPerf traffic.") - return rvr_result - - def run_iperf_server(self, network): - """Run iperf RX throughput after connection. - - Args: - params: Dictionary with network info. - - Returns: - rvr_result: Dict containing rvr_results - """ - rvr_result = [] - self.iperf_server.start(tag="RX_client_{}_angle{}_{}dB".format( - self.ssid,self.angle[self.ag],self.DB)) - wait_time = 5 - SSID = network[WifiEnums.SSID_KEY] - self.log.info("Starting iperf traffic RX through {}".format(SSID)) - time.sleep(wait_time) - port_arg = "-p {} -J -R {}".format(self.iperf_server.port, - self.rvr_test_params["iperf_port_arg"]) - success, data = self.dut.run_iperf_client( - self.rvr_test_params["iperf_server_address"], - port_arg, - timeout=self.rvr_test_params["iperf_duration"] + self.TEST_TIMEOUT) - # Parse and log result - client_output_path = os.path.join( - self.iperf_server.log_path, "IperfDUT,{},RX_server_{}_angle{}_{}dB".format( - self.iperf_server.port,self.ssid,self.angle[self.ag],self.DB)) - with open(client_output_path, 'w') as out_file: - out_file.write("\n".join(data)) - self.iperf_server.stop() - - iperf_file = client_output_path - try: - iperf_result = ipf.IPerfResult(iperf_file) - curr_throughput = (math.fsum(iperf_result.instantaneous_rates[ - self.rvr_test_params["iperf_ignored_interval"]:-1]) / len( - iperf_result.instantaneous_rates[self.rvr_test_params[ - "iperf_ignored_interval"]:-1])) * 8 * (1.024**2) - except: - self.log.warning( - "ValueError: Cannot get iperf result. Setting to 0") - curr_throughput = 0 - rvr_result.append(curr_throughput) - self.log.info("RX Throughput at {0:.2f} dB is {1:.2f} Mbps".format( - self.DB, curr_throughput)) - - self.log.debug(pprint.pformat(data)) - asserts.assert_true(success, "Error occurred in iPerf traffic.") - return rvr_result - - def iperf_test_func(self,network): - """Main function to test iperf TX/RX. - - Args: - params: Dictionary with network info - """ - if "rvr_test_params" in self.user_params: - # Initialize - rvr_result = {} - # Run RvR and log result - wifiinfo = self.getwifiinfo() - rvr_result["throughput_TX"] = self.run_iperf_client(network) - rvr_result["throughput_RX"] = self.run_iperf_server(network) - rvr_result["test_name"] = self.ssid - rvr_result["test_angle"] = self.angle[self.ag] - rvr_result["test_dB"] = self.DB - rvr_result["test_RSSI"] = wifiinfo[0] - rvr_result["test_LS"] = wifiinfo[1] - rvr_result["test_FR"] = wifiinfo[2] - self.post_process_results(rvr_result) - - def rvr_test(self,network): - """Test function to run RvR. - - The function runs an RvR test in the current device/AP configuration. - Function is called from another wrapper function that sets up the - testbed for the RvR test - - Args: - params: Dictionary with network info - """ - wait_time = 5 - utils.subprocess.check_output('adb root', shell=True, timeout=20) - self.ssid = network[WifiEnums.SSID_KEY] - self.log.info("Start rvr test") - for i in range(len(self.angle)): - self.setDG(self.T1,self.angle[i]) - time.sleep(wait_time) - self.checkDG(self.T1,self.angle[i]) - self.set_Three_Att_dB(self.ATT1,self.ATT2,self.ATT3,0) - time.sleep(wait_time) - self.connect_to_wifi_network(network) - self.set_Three_Att_dB(self.ATT1,self.ATT2,self.ATT3,self.MindB) - for j in range(self.MindB,self.MaxdB+self.stepdB,self.stepdB): - self.DB=j - self.ag=i - self.set_Three_Att_dB(self.ATT1,self.ATT2,self.ATT3,self.DB) - self.iperf_test_func(network) - wutils.reset_wifi(self.dut) - - """Tests""" - - @test_tracker_info(uuid="93816af8-4c63-45f8-b296-cb49fae0b158") - def test_iot_connection_to_RVR_2G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.rvr_test(self.ssid_map[ssid_key]) - - @test_tracker_info(uuid="e1a67e13-946f-4d91-aa73-3f945438a1ac") - def test_iot_connection_to_RVR_5G(self): - ssid_key = self.current_test_name.replace(self.iot_test_prefix, "") - self.rvr_test(self.ssid_map[ssid_key])
\ No newline at end of file diff --git a/acts/tests/google/wifi/WifiScannerBssidTest.py b/acts/tests/google/wifi/WifiScannerBssidTest.py deleted file mode 100644 index e91c449924..0000000000 --- a/acts/tests/google/wifi/WifiScannerBssidTest.py +++ /dev/null @@ -1,482 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2016 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import itertools -import queue - -from acts import asserts -from acts import base_test -from acts import utils -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi import wifi_test_utils as wutils - -BSSID_EVENT_WAIT = 30 - -BSSID_EVENT_TAG = "WifiScannerBssid" -SCAN_EVENT_TAG = "WifiScannerScan" -SCANTIME = 10000 #framework support only 10s as minimum scan interval - - -class WifiScannerBssidError(Exception): - pass - - -class WifiScannerBssidTest(base_test.BaseTestClass): - def __init__(self, controllers): - base_test.BaseTestClass.__init__(self, controllers) - # A list of all test cases to be executed in this class. - self.tests = ("test_wifi_track_bssid_sanity", - "test_wifi_track_bssid_found", - "test_wifi_track_bssid_lost", - "test_wifi_track_bssid_for_2g_while_scanning_5g_channels", - "test_wifi_track_bssid_for_5g_while_scanning_2g_channels",) - - def setup_class(self): - self.default_scan_setting = { - "band": wutils.WifiEnums.WIFI_BAND_BOTH_WITH_DFS, - "periodInMs": SCANTIME, - "reportEvents": wutils.WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, - 'numBssidsPerScan': 32 - } - self.leeway = 5 - self.stime_channel = 47 #dwell time plus 2ms - self.dut = self.android_devices[0] - wutils.wifi_test_device_init(self.dut) - self.attenuators = wutils.group_attenuators(self.attenuators) - asserts.assert_true(self.dut.droid.wifiIsScannerSupported(), - "Device %s doesn't support WifiScanner, abort." % - self.dut.model) - """It will setup the required dependencies and fetch the user params from - config file""" - self.attenuators[0].set_atten(0) - self.attenuators[1].set_atten(0) - req_params = ("bssid_2g", "bssid_5g", "bssid_dfs", "attenuator_id", - "max_bugreports") - self.wifi_chs = wutils.WifiChannelUS(self.dut.model) - self.unpack_userparams(req_params, two_ap_testbed=False) - - def teardown_class(self): - BaseTestClass.teardown_test(self) - self.log.debug("Shut down all wifi scanner activities.") - self.dut.droid.wifiScannerShutdown() - - def on_fail(self, test_name, begin_time): - if self.max_bugreports > 0: - self.dut.take_bug_report(test_name, begin_time) - self.max_bugreports -= 1 - - """ Helper Functions Begin """ - - def fetch_scan_result(self, scan_idx, scan_setting): - """Fetch the scan result for provider listener index. - - This function calculate the time required for scanning based on scan setting - and wait for scan result event, on triggering of event process the scan result. - - Args: - scan_idx: Index of the scan listener. - scan_setting: Setting used for starting the scan. - - Returns: - scan_results: if scan result available. - """ - #generating event wait time from scan setting plus leeway - self.log.debug(scan_setting) - scan_time, scan_channels = wutils.get_scan_time_and_channels( - self.wifi_chs, scan_setting, self.stime_channel) - scan_time += scan_setting['periodInMs' - ] #add scan period delay for next cycle - if scan_setting[ - "reportEvents"] == wutils.WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN: - waittime = int(scan_time / 1000) + self.leeway - else: - time_cache = scan_setting['periodInMs'] * 10 #default cache - waittime = int((time_cache + scan_time) / 1000) + self.leeway - event_name = "%s%sonResults" % (SCAN_EVENT_TAG, scan_idx) - self.log.info("Waiting for the scan result event %s", event_name) - event = self.dut.ed.pop_event(event_name, waittime) - results = event["data"]["Results"] - if len(results) > 0 and "ScanResults" in results[0]: - return results[0]["ScanResults"] - - def start_scan_and_validate_environment(self, scan_setting, - bssid_settings): - """Validate environment for test using current scan result for provided - settings. - - This function start the scan for given setting and verify that interested - Bssids are in scan result or not. - - Args: - scan_setting: Setting used for starting the scan. - bssid_settings: list of bssid settings. - - Returns: - True, if bssid not found in scan result. - """ - try: - data = wutils.start_wifi_background_scan(self.dut, scan_setting) - self.scan_idx = data["Index"] - results = self.fetch_scan_result(self.scan_idx, scan_setting) - self.log.debug("scan result %s.", results) - asserts.assert_true(results, - "Device is not able to fetch the scan results") - for result in results: - for bssid_setting in bssid_settings: - if bssid_setting[wutils.WifiEnums.BSSID_KEY] == result[ - wutils.WifiEnums.BSSID_KEY]: - asserts.fail(("Test environment is not valid: Bssid %s" - "already exist in current scan results") - % result[wutils.WifiEnums.BSSID_KEY]) - except queue.Empty as error: - self.dut.droid.wifiScannerStopBackgroundScan(self.scan_idx) - raise AssertionError( - "OnResult event did not triggered for scanner\n%s" % error) - - def check_bssid_in_found_result(self, bssid_settings, found_results): - """look for any tracked bssid in reported result of found bssids. - - Args: - bssid_settings:Setting used for tracking bssids. - found_results: Result reported in found event. - - Returns: - True if bssid is present in result. - """ - for bssid_setting in bssid_settings: - for found_result in found_results: - if found_result[wutils.WifiEnums.BSSID_KEY] == bssid_setting[ - wutils.WifiEnums.BSSID_KEY]: - return - asserts.fail("Test fail because Bssid %s is not found in event results" - % bssid_settings) - - def track_bssid_with_vaild_scan_for_found(self, track_setting): - """Common logic for tracking a bssid for Found event. - - 1. Starts Wifi Scanner bssid tracking for interested bssids in track_setting. - 2. Start Wifi Scanner scan with default scan settings. - 3. Validate the environment to check AP is not in range. - 4. Attenuate the signal to make AP in range. - 5. Verified that onFound event is triggered for interested bssids in - track setting. - - Args: - track_setting: Setting for bssid tracking. - - Returns: - True if found event occur for interested BSSID. - """ - self.attenuators[self.attenuator_id].set_atten(90) - data = wutils.start_wifi_track_bssid(self.dut, track_setting) - idx = data["Index"] - self.start_scan_and_validate_environment(self.default_scan_setting, - track_setting["bssidInfos"]) - try: - self.attenuators[self.attenuator_id].set_atten(0) - event_name = "%s%sonFound" % (BSSID_EVENT_TAG, idx) - self.log.info("Waiting for the BSSID event %s", event_name) - event = self.dut.ed.pop_event(event_name, BSSID_EVENT_WAIT) - self.log.debug(event) - self.check_bssid_in_found_result(track_setting["bssidInfos"], - event["data"]["Results"]) - except queue.Empty as error: - self.log.error(error) - # log scan result for debugging - results = self.fetch_scan_result(self.scan_idx, - self.default_scan_setting) - self.log.debug("scan result %s", results) - raise AssertionError("Event %s did not triggered for %s\n%s" % - (event_name, track_setting["bssidInfos"], - error)) - finally: - self.dut.droid.wifiScannerStopBackgroundScan(self.scan_idx) - self.dut.droid.wifiScannerStopTrackingBssids(idx) - - def track_bssid_with_vaild_scan_for_lost(self, track_setting): - """Common logic for tracking a bssid for Lost event. - - 1. Start Wifi Scanner scan with default scan settings. - 2. Validate the environment to check AP is not in range. - 3. Starts Wifi Scanner bssid tracking for interested bssids in track_setting. - 4. Attenuate the signal to make Bssids in range. - 5. Verified that onFound event is triggered for interested bssids in - track setting. - 6. Attenuate the signal to make Bssids out of range. - 7. Verified that onLost event is triggered. - - Args: - track_setting: Setting for bssid tracking. - scan_setting: Setting used for starting the scan. - - Returns: - True if Lost event occur for interested BSSID. - """ - self.attenuators[self.attenuator_id].set_atten(90) - self.start_scan_and_validate_environment(self.default_scan_setting, - track_setting["bssidInfos"]) - idx = None - found = False - try: - data = wutils.start_wifi_track_bssid(self.dut, track_setting) - idx = data["Index"] - self.attenuators[self.attenuator_id].set_atten(0) - #onFound event should be occurre before tracking for onLost event - event_name = "%s%sonFound" % (BSSID_EVENT_TAG, idx) - self.log.info("Waiting for the BSSID event %s", event_name) - event = self.dut.ed.pop_event(event_name, BSSID_EVENT_WAIT) - self.log.debug(event) - self.check_bssid_in_found_result(track_setting["bssidInfos"], - event["data"]["Results"]) - self.attenuators[self.attenuator_id].set_atten(90) - # log scan result for debugging - for i in range(1, track_setting["apLostThreshold"]): - results = self.fetch_scan_result(self.scan_idx, - self.default_scan_setting) - self.log.debug("scan result %s %s", i, results) - event_name = "%s%sonLost" % (BSSID_EVENT_TAG, idx) - self.log.info("Waiting for the BSSID event %s", event_name) - event = self.dut.ed.pop_event(event_name, BSSID_EVENT_WAIT) - self.log.debug(event) - except queue.Empty as error: - raise AssertionError("Event %s did not triggered for %s\n%s" % - (event_name, track_setting["bssidInfos"], - error)) - finally: - self.dut.droid.wifiScannerStopBackgroundScan(self.scan_idx) - if idx: - self.dut.droid.wifiScannerStopTrackingBssids(idx) - - def wifi_generate_track_bssid_settings(self, isLost): - """Generates all the combinations of different track setting parameters. - - Returns: - A list of dictionaries each representing a set of track settings. - """ - bssids = [[self.bssid_2g], [self.bssid_5g], - [self.bssid_2g, self.bssid_5g]] - if self.dut.model != "hammerhead" or not self.two_ap_testbed: - bssids.append([self.bssid_dfs]) - if isLost: - apthreshold = (3, 5) - else: - apthreshold = (1, ) - # Create track setting strings based on the combinations - setting_combinations = list(itertools.product(bssids, apthreshold)) - # Create scan setting strings based on the combinations - track_settings = [] - for combo in setting_combinations: - s = {} - s["bssidInfos"] = combo[0] - s["apLostThreshold"] = combo[1] - track_settings.append(s) - return track_settings - - def track_setting_to_string(self, track_setting): - """Convert track setting to string for Bssids in that""" - string = "" - for bssid_setting in track_setting: - string += bssid_setting[wutils.WifiEnums.BSSID_KEY] - string += "_" - return string - - def combineBssids(self, *track_settings): - """Combine bssids in the track_settings to one list""" - bssids = [] - for track_setting in track_settings: - bssids.extend(track_setting["bssidInfos"]) - return bssids - - """ Helper Functions End """ - """ Tests Begin """ - - @test_tracker_info(uuid="599a30b8-73ad-4314-a245-7ec58fc7e74b") - def test_wifi_track_bssid_found(self): - """Test bssid track for event found with a list of different settings. - - 1. Starts Wifi Scanner bssid tracking for interested bssids in track_setting. - 2. Start Wifi Scanner scan with default scan settings. - 3. Validate the environment to check AP is not in range. - 4. Attenuate the signal to make AP in range. - 5. Verified that onFound event is triggered for interested bssids in - track setting. - """ - track_settings = self.wifi_generate_track_bssid_settings(False) - name_func = lambda track_setting: "test_wifi_track_found_bssidInfos_%sapLostThreshold_%s" % (self.track_setting_to_string(track_setting["bssidInfos"]), track_setting["apLostThreshold"]) - failed = self.run_generated_testcases( - self.track_bssid_with_vaild_scan_for_found, - track_settings, - name_func=name_func) - asserts.assert_false( - failed, "Track bssid found failed with these bssids: %s" % failed) - - @test_tracker_info(uuid="7ebd4b61-c408-45b3-b9b6-098753d46aa7") - def test_wifi_track_bssid_lost(self): - """Test bssid track for event lost with a list of different settings. - - 1. Start Wifi Scanner scan with default scan settings. - 2. Validate the environment to check AP is not in range. - 3. Starts Wifi Scanner bssid tracking for interested bssids in track_setting. - 4. Attenuate the signal to make Bssids in range. - 5. Verified that onFound event is triggered for interested bssids in - track setting. - 6. Attenuate the signal to make Bssids out of range. - 7. Verified that onLost event is triggered. - """ - track_settings = self.wifi_generate_track_bssid_settings(True) - name_func = lambda track_setting: "test_wifi_track_lost_bssidInfos_%sapLostThreshold_%s" % (self.track_setting_to_string(track_setting["bssidInfos"]), track_setting["apLostThreshold"]) - failed = self.run_generated_testcases( - self.track_bssid_with_vaild_scan_for_lost, - track_settings, - name_func=name_func) - asserts.assert_false( - failed, "Track bssid lost failed with these bssids: %s" % failed) - - def test_wifi_track_bssid_sanity(self): - """Test bssid track for event found and lost with default settings. - - 1. Start WifiScanner scan for default scan settings. - 2. Start Bssid track for "bssid_2g" AP. - 3. Attenuate the signal to move in AP range. - 4. Verify that onFound event occur. - 5. Attenuate the signal to move out of range - 6. Verify that onLost event occur. - """ - track_setting = {"bssidInfos": [self.bssid_2g], "apLostThreshold": 3} - self.track_bssid_with_vaild_scan_for_lost(track_setting) - - def test_wifi_track_bssid_for_2g_while_scanning_5g_channels(self): - """Test bssid track for 2g bssids while scanning 5g channels. - - 1. Starts Wifi Scanner bssid tracking for 2g bssids in track_setting. - 2. Start Wifi Scanner scan for 5G Band only. - 3. Validate the environment to check AP is not in range. - 4. Attenuate the signal to make AP in range. - 5. Verified that onFound event isn't triggered for 2g bssids. - """ - self.attenuators[self.attenuator_id].set_atten(90) - scan_setting = {"band": wutils.WifiEnums.WIFI_BAND_5_GHZ, - "periodInMs": SCANTIME, - "reportEvents": - wutils.WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, - "numBssidsPerScan": 32} - track_setting = {"bssidInfos": [self.bssid_2g], "apLostThreshold": 3} - self.start_scan_and_validate_environment(scan_setting, - track_setting["bssidInfos"]) - idx = None - try: - data = wutils.start_wifi_track_bssid(self.dut, track_setting) - idx = data["Index"] - self.attenuators[self.attenuator_id].set_atten(0) - event_name = "%s%sonFound" % (BSSID_EVENT_TAG, idx) - self.log.info("Waiting for the BSSID event %s", event_name) - #waiting for 2x time to make sure - event = self.dut.ed.pop_event(event_name, BSSID_EVENT_WAIT * 2) - self.log.debug(event) - self.check_bssid_in_found_result(track_setting["bssidInfos"], - event["data"]["Results"]) - except queue.Empty as error: - self.log.info( - "As excepted event didn't occurred with different scan setting") - finally: - self.dut.droid.wifiScannerStopBackgroundScan(self.scan_idx) - if idx: - self.dut.droid.wifiScannerStopTrackingBssids(idx) - - def test_wifi_track_bssid_for_5g_while_scanning_2g_channels(self): - """Test bssid track for 5g bssids while scanning 2g channels. - - 1. Starts Wifi Scanner bssid tracking for 5g bssids in track_setting. - 2. Start Wifi Scanner scan for 2G Band only. - 3. Validate the environment to check AP is not in range. - 4. Attenuate the signal to make AP in range. - 5. Verified that onFound event isn't triggered for 5g bssids. - """ - self.attenuators[self.attenuator_id].set_atten(90) - scan_setting = {"band": wutils.WifiEnums.WIFI_BAND_24_GHZ, - "periodInMs": SCANTIME, - "reportEvents": - wutils.WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, - "numBssidsPerScan": 32} - track_setting = {"bssidInfos": [self.bssid_5g], "apLostThreshold": 3} - data = wutils.start_wifi_track_bssid(self.dut, track_setting) - idx = data["Index"] - self.start_scan_and_validate_environment(scan_setting, - track_setting["bssidInfos"]) - try: - self.attenuators[self.attenuator_id].set_atten(0) - event_name = "%s%sonFound" % (BSSID_EVENT_TAG, idx) - self.log.info("Waiting for the BSSID event %s", event_name) - #waiting for 2x time to make sure - event = self.dut.ed.pop_event(event_name, BSSID_EVENT_WAIT * 2) - self.log.debug(event) - self.check_bssid_in_found_result(track_setting["bssidInfos"], - event["data"]["Results"]) - except queue.Empty as error: - self.log.info( - "As excepted event didn't occurred with different scan setting") - finally: - self.dut.droid.wifiScannerStopBackgroundScan(self.scan_idx) - if idx: - self.dut.droid.wifiScannerStopTrackingBssids(idx) - - def test_wifi_tracking_bssid_multi_listeners_found(self): - """Test bssid tracking for multiple listeners - 1. Start BSSID tracking for 5g bssids - 2. Start BSSID tracking for 2g bssids - 3. Start WifiScanner scan on both bands. - 4. Valid the environment and check the APs are not in range. - 5. Attenuate the signal to make the APs in range. - 6. Verify onFound event triggered on both APs. - """ - # Attenuate the signal to make APs invisible. - self.attenuators[self.attenuator_id].set_atten(90) - scan_setting = { "band": WifiEnums.WIFI_BAND_BOTH_WITH_DFS, - "periodInMs": SCANTIME, - "reportEvents": WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, - "numBssidsPerScan": 32} - track_setting_5g = {"bssidInfos":[self.bssid_5g], "apLostThreshold":3} - data_5g = start_wifi_track_bssid(self.dut, track_setting_5g) - idx_5g = data_5g["Index"] - - track_setting_2g = {"bssidInfos":[self.bssid_2g], "apLostThreshold":3} - data_2g = start_wifi_track_bssid(self.dut, track_setting_2g) - idx_2g = data_2g["Index"] - - valid_env = self.start_scan_and_validate_environment( - scan_setting, self.combineBssids(track_setting_5g, track_setting_2g)) - try: - asserts.assert_true(valid_env, - "Test environment is not valid, AP is in range") - self.attenuators[self.attenuator_id].set_atten(0) - event_name = "{}{}{}{}onFound".format(BSSID_EVENT_TAG, idx_5g, BSSID_EVENT_TAG, idx_2g) - self.log.info("Waiting for the BSSID event {}".format(event_name)) - #waiting for 2x time to make sure - event = self.dut.ed.pop_event(event_name, BSSID_EVENT_WAIT * 2) - self.log.debug(event) - found = self.check_bssid_in_found_result( - self.combineBssids(track_setting_5g, track_setting_2g), - event["data"]["Results"]) - asserts.assert_true(found, - "Test failed because Bssid onFound event is not triggered") - finally: - self.dut.droid.wifiScannerStopBackgroundScan(self.scan_idx) - if idx_5g: - self.dut.droid.wifiScannerStopTrackingBssids(idx_5g) - if idx_2g: - self.dut.droid.wifiScannerStopTrackingBssids(idx_2g); - -""" Tests End """ diff --git a/acts/tests/google/wifi/WifiScannerMultiScanTest.py b/acts/tests/google/wifi/WifiScannerMultiScanTest.py deleted file mode 100755 index f8804bb887..0000000000 --- a/acts/tests/google/wifi/WifiScannerMultiScanTest.py +++ /dev/null @@ -1,660 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2016 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import queue -import time - -from acts import asserts -from acts import base_test -from acts import signals -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi import wifi_test_utils as wutils -from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest - -WifiChannelUS = wutils.WifiChannelUS -WifiEnums = wutils.WifiEnums - -SCAN_EVENT_TAG = "WifiScannerScan" - - -class WifiScanResultEvents(): - """This class stores the setting of a scan, parameters generated - from starting the scan, and events reported later from the scan - for validation. - - Attributes: - scan_setting: Setting used to perform the scan. - scan_channels: Channels used for scanning. - events: A list to store the scan result events. - """ - - def __init__(self, scan_setting, scan_channels): - self.scan_setting = scan_setting - self.scan_channels = scan_channels - self.results_events = [] - - def add_results_event(self, event): - self.results_events.append(event) - - def check_interval(self, scan_result, scan_result_next): - """Verifies that the time gap between two consecutive results is within - expected range. - - Right now it is hard coded to be 20 percent of the interval specified - by scan settings. This threshold can be imported from the configuration - file in the future if necessary later. - - Note the scan result timestamps are in microseconds, but "periodInMs" - in scan settings is in milliseconds. - - Args: - scan_result: A dictionary representing a scan result for a BSSID. - scan_result_next: A dictionary representing a scan result for a - BSSID, whose scan happened after scan_result. - """ - actual_interval = scan_result_next["timestamp"] - scan_result[ - "timestamp"] - expected_interval = self.scan_setting['periodInMs'] * 1000 - delta = abs(actual_interval - expected_interval) - margin = expected_interval * 0.25 # 25% of the expected_interval - asserts.assert_true( - delta < margin, "The difference in time between scan %s and " - "%s is %dms, which is out of the expected range %sms" % ( - scan_result, scan_result_next, delta / 1000, - self.scan_setting['periodInMs'])) - - def verify_one_scan_result(self, scan_result): - """Verifies the scan result of a single BSSID. - - 1. Verifies the frequency of the network is within the range requested - in the scan. - - Args: - scan_result: A dictionary representing the scan result of a single - BSSID. - """ - freq = scan_result["frequency"] - asserts.assert_true( - freq in self.scan_channels, - "Frequency %d of result entry %s is out of the expected range %s." - % (freq, scan_result, self.scan_channels)) - # TODO(angli): add RSSI check. - - def verify_one_scan_result_group(self, batch): - """Verifies a group of scan results obtained during one scan. - - 1. Verifies the number of BSSIDs in the batch is less than the - threshold set by scan settings. - 2. Verifies each scan result for individual BSSID. - - Args: - batch: A list of dictionaries, each dictionary represents a scan - result. - """ - scan_results = batch["ScanResults"] - actual_num_of_results = len(scan_results) - expected_num_of_results = self.scan_setting['numBssidsPerScan'] - asserts.assert_true(actual_num_of_results <= expected_num_of_results, - "Expected no more than %d BSSIDs, got %d." % - (expected_num_of_results, actual_num_of_results)) - for scan_result in scan_results: - self.verify_one_scan_result(scan_result) - - def have_enough_events(self): - """Check if there are enough events to properly validate the scan""" - return len(self.results_events) >= 2 - - def check_scan_results(self): - """Validate the reported scan results against the scan settings. - Assert if any error detected in the results. - - 1. For each scan setting there should be no less than 2 events received. - 2. For batch scan, the number of buffered results in each event should - be exactly what the scan setting specified. - 3. Each scan result should contain no more BBSIDs than what scan - setting specified. - 4. The frequency reported by each scan result should comply with its - scan setting. - 5. The time gap between two consecutive scan results should be - approximately equal to the scan interval specified by the scan - setting. - A scan result looks like this: - { - 'data': - { - 'Type': 'onResults', - 'ResultElapsedRealtime': 4280931, - 'Index': 10, - 'Results': [ - { - 'Flags': 0, - 'Id': 4, - 'ScanResults':[ - { - 'is80211McRTTResponder': False, - 'channelWidth': 0, - 'numUsage': 0, - 'SSID': '"wh_ap1_2g"', - 'timestamp': 4280078660, - 'BSSID': '30:b5:c2:33:f9:05', - 'frequency': 2412, - 'distanceSdCm': 0, - 'distanceCm': 0, - 'centerFreq1': 0, - 'centerFreq0': 0, - 'venueName': '', - 'seen': 0, - 'operatorFriendlyName': '', - 'level': -31, - 'passpointNetwork': False, - 'untrusted': False - } - ] - } - ] - }, - 'time': 1491744576383, - 'name': 'WifiScannerScan10onResults' - } - """ - num_of_events = len(self.results_events) - asserts.assert_true( - num_of_events >= 2, - "Expected more than one scan result events, got %d." % - num_of_events) - for event_idx in range(num_of_events): - batches = self.results_events[event_idx]["data"]["Results"] - actual_num_of_batches = len(batches) - if not actual_num_of_batches: - raise signals.TestFailure("Scan returned empty Results list %s " - "% batches") - # For batch scan results. - report_type = self.scan_setting['reportEvents'] - if not (report_type & WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN): - # Verifies that the number of buffered results matches the - # number defined in scan settings. - expected_num_of_batches = self.scan_setting['maxScansToCache'] - asserts.assert_true( - actual_num_of_batches <= expected_num_of_batches, - "Expected to get at most %d batches in event No.%d, got %d." - % (expected_num_of_batches, event_idx, - actual_num_of_batches)) - # Check the results within each event of batch scan - for batch_idx in range(actual_num_of_batches): - if not len(batches[batch_idx]["ScanResults"]): - raise signals.TestFailure("Scan event %d returned empty" - " scan results in batch %d" % (event_idx, batch_idx)) - # Start checking interval from the second batch. - if batch_idx >=1: - self.check_interval( - batches[batch_idx - 1]["ScanResults"][0], - batches[batch_idx]["ScanResults"][0]) - for batch in batches: - self.verify_one_scan_result_group(batch) - - # Check the time gap between the first result of an event and - # the last result of its previous event - # Skip the very first event. - if event_idx >= 1: - previous_batches = self.results_events[event_idx - 1]["data"][ - "Results"] - self.check_interval(previous_batches[-1]["ScanResults"][0], - batches[0]["ScanResults"][0]) - - -class WifiScannerMultiScanTest(WifiBaseTest): - """This class is the WiFi Scanner Multi-Scan Test suite. - It collects a number of test cases, sets up and executes - the tests, and validates the scan results. - - Attributes: - tests: A collection of tests to excute. - leeway: Scan interval drift time (in seconds). - stime_channels: Dwell time plus 2ms. - dut: Android device(s). - wifi_chs: WiFi channels according to the device model. - max_bugreports: Max number of bug reports allowed. - """ - - def __init__(self, controllers): - WifiBaseTest.__init__(self, controllers) - self.tests = ( - 'test_wifi_two_scans_at_same_interval', - 'test_wifi_two_scans_at_different_interval', - 'test_wifi_scans_24GHz_and_both', - 'test_wifi_scans_5GHz_and_both', - 'test_wifi_scans_batch_and_24GHz', - 'test_wifi_scans_batch_and_5GHz', - 'test_wifi_scans_24GHz_5GHz_full_result',) - - def setup_class(self): - # If running in a setup with attenuators, set attenuation on all - # channels to zero. - if getattr(self, "attenuators", []): - for a in self.attenuators: - a.set_atten(0) - self.leeway = 5 # seconds, for event wait time computation - self.stime_channel = 47 #dwell time plus 2ms - self.dut = self.android_devices[0] - wutils.wifi_test_device_init(self.dut) - asserts.assert_true(self.dut.droid.wifiIsScannerSupported(), - "Device %s doesn't support WifiScanner, abort." % - self.dut.model) - """ Setup the required dependencies and fetch the user params from - config file. - """ - req_params = ["max_bugreports"] - opt_param = ["reference_networks"] - self.unpack_userparams( - req_param_names=req_params, opt_param_names=opt_param) - - if "AccessPoint" in self.user_params: - self.legacy_configure_ap_and_start() - - self.wifi_chs = WifiChannelUS(self.dut.model) - - def on_fail(self, test_name, begin_time): - if self.max_bugreports > 0: - self.dut.take_bug_report(test_name, begin_time) - self.max_bugreports -= 1 - self.dut.cat_adb_log(test_name, begin_time) - - def teardown_class(self): - if "AccessPoint" in self.user_params: - del self.user_params["reference_networks"] - del self.user_params["open_network"] - - """ Helper Functions Begin """ - - def start_scan(self, scan_setting): - data = wutils.start_wifi_background_scan(self.dut, scan_setting) - idx = data["Index"] - # Calculate event wait time from scan setting plus leeway - scan_time, scan_channels = wutils.get_scan_time_and_channels( - self.wifi_chs, scan_setting, self.stime_channel) - scan_period = scan_setting['periodInMs'] - report_type = scan_setting['reportEvents'] - if report_type & WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN: - scan_time += scan_period - else: - max_scan = scan_setting['maxScansToCache'] - scan_time += max_scan * scan_period - wait_time = scan_time / 1000 + self.leeway - return idx, wait_time, scan_channels - - def validate_scan_results(self, scan_results_dict): - # Sanity check to make sure the dict is not empty - asserts.assert_true(scan_results_dict, "Scan result dict is empty.") - for scan_result_obj in scan_results_dict.values(): - # Validate the results received for each scan setting - scan_result_obj.check_scan_results() - - def wait_for_scan_events(self, wait_time_list, scan_results_dict): - """Poll for WifiScanner events and record them""" - - # Compute the event wait time - event_wait_time = min(wait_time_list) - - # Compute the maximum test time that guarantee that even the scan - # which requires the most wait time will receive at least two - # results. - max_wait_time = max(wait_time_list) - max_end_time = time.monotonic() + max_wait_time - self.log.debug("Event wait time %s seconds", event_wait_time) - - try: - # Wait for scan results on all the caller specified bands - event_name = SCAN_EVENT_TAG - while True: - self.log.debug("Waiting for events '%s' for up to %s seconds", - event_name, event_wait_time) - events = self.dut.ed.pop_events(event_name, event_wait_time) - for event in events: - self.log.debug("Event received: %s", event) - # Event name is the key to the scan results dictionary - actual_event_name = event["name"] - asserts.assert_true( - actual_event_name in scan_results_dict, - "Expected one of these event names: %s, got '%s'." % - (scan_results_dict.keys(), actual_event_name)) - - # TODO validate full result callbacks also - if event["name"].endswith("onResults"): - # Append the event - scan_results_dict[actual_event_name].add_results_event( - event) - - # If we time out then stop waiting for events. - if time.monotonic() >= max_end_time: - break - # If enough scan results have been returned to validate the - # results then break early. - have_enough_events = True - for key in scan_results_dict: - if not scan_results_dict[key].have_enough_events(): - have_enough_events = False - if have_enough_events: - break - except queue.Empty: - asserts.fail("Event did not trigger for {} in {} seconds".format( - event_name, event_wait_time)) - - def scan_and_validate_results(self, scan_settings): - """Perform WifiScanner scans and check the scan results - - Procedures: - * Start scans for each caller specified setting - * Wait for at least two results for each scan - * Check the results received for each scan - """ - # Awlays get a clean start - self.dut.ed.clear_all_events() - - # Start scanning with the caller specified settings and - # compute parameters for receiving events - idx_list = [] - wait_time_list = [] - scan_results_dict = {} - - try: - for scan_setting in scan_settings: - self.log.debug( - "Scan setting: band %s, interval %s, reportEvents " - "%s, numBssidsPerScan %s", scan_setting["band"], - scan_setting["periodInMs"], scan_setting["reportEvents"], - scan_setting["numBssidsPerScan"]) - idx, wait_time, scan_chan = self.start_scan(scan_setting) - self.log.debug( - "Scan started for band %s: idx %s, wait_time %ss, scan_channels %s", - scan_setting["band"], idx, wait_time, scan_chan) - idx_list.append(idx) - wait_time_list.append(wait_time) - - report_type = scan_setting['reportEvents'] - scan_results_events = WifiScanResultEvents(scan_setting, - scan_chan) - scan_results_dict["{}{}onResults".format( - SCAN_EVENT_TAG, idx)] = scan_results_events - if (scan_setting['reportEvents'] - & WifiEnums.REPORT_EVENT_FULL_SCAN_RESULT): - scan_results_dict["{}{}onFullResult".format( - SCAN_EVENT_TAG, idx)] = scan_results_events - - self.wait_for_scan_events(wait_time_list, scan_results_dict) - - # Validate the scan results - self.validate_scan_results(scan_results_dict) - - finally: - # Tear down and clean up - for idx in idx_list: - self.dut.droid.wifiScannerStopBackgroundScan(idx) - self.dut.ed.clear_all_events() - - """ Helper Functions End """ - """ Tests Begin """ - - @test_tracker_info(uuid="d490b146-5fc3-4fc3-9958-78ba0ad63211") - @WifiBaseTest.wifi_test_wrap - def test_wifi_two_scans_at_same_interval(self): - """Perform two WifiScanner background scans, one at 2.4GHz and the other - at 5GHz, the same interval and number of BSSIDs per scan. - - Initial Conditions: - * Set multiple APs broadcasting 2.4GHz and 5GHz. - - Expected Results: - * DUT reports success for starting both scans - * Scan results for each callback contains only the results on the - frequency scanned - * Wait for at least two scan results and confirm that separation - between them approximately equals to the expected interval - * Number of BSSIDs doesn't exceed - """ - scan_settings = [{"band": WifiEnums.WIFI_BAND_24_GHZ, - "periodInMs": 10000, # ms - "reportEvents": - WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, - "numBssidsPerScan": 24}, - {"band": WifiEnums.WIFI_BAND_5_GHZ, - "periodInMs": 10000, # ms - "reportEvents": - WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, - "numBssidsPerScan": 24}] - - self.scan_and_validate_results(scan_settings) - - @test_tracker_info(uuid="0ec9a554-f942-41a9-8096-6b0b400f60b0") - @WifiBaseTest.wifi_test_wrap - def test_wifi_two_scans_at_different_interval(self): - """Perform two WifiScanner background scans, one at 2.4GHz and the other - at 5GHz, different interval and number of BSSIDs per scan. - - Initial Conditions: - * Set multiple APs broadcasting 2.4GHz and 5GHz. - - Expected Results: - * DUT reports success for starting both scans - * Scan results for each callback contains only the results on the - frequency scanned - * Wait for at least two scan results and confirm that separation - between them approximately equals to the expected interval - * Number of BSSIDs doesn't exceed - """ - scan_settings = [{"band": WifiEnums.WIFI_BAND_24_GHZ, - "periodInMs": 10000, # ms - "reportEvents": - WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, - "numBssidsPerScan": 20}, - {"band": WifiEnums.WIFI_BAND_5_GHZ, - "periodInMs": 30000, # ms - "reportEvents": - WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, - "numBssidsPerScan": 24}] - - self.scan_and_validate_results(scan_settings) - - @test_tracker_info(uuid="0d616591-0d32-4be6-8fd4-e4a5e9ccdce0") - @WifiBaseTest.wifi_test_wrap - def test_wifi_scans_24GHz_and_both(self): - """Perform two WifiScanner background scans, one at 2.4GHz and - the other at both 2.4GHz and 5GHz - - Initial Conditions: - * Set multiple APs broadcasting 2.4GHz and 5GHz. - - Expected Results: - * DUT reports success for starting both scans - * Scan results for each callback contains only the results on the - frequency scanned - * Wait for at least two scan results and confirm that separation - between them approximately equals to the expected interval - * Number of BSSIDs doesn't exceed - """ - scan_settings = [{"band": WifiEnums.WIFI_BAND_BOTH, - "periodInMs": 10000, # ms - "reportEvents": - WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, - "numBssidsPerScan": 24}, - {"band": WifiEnums.WIFI_BAND_24_GHZ, - "periodInMs": 10000, # ms - "reportEvents": - WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, - "numBssidsPerScan": 24}] - - self.scan_and_validate_results(scan_settings) - - @test_tracker_info(uuid="ddcf959e-512a-4e86-b3d3-18cebd0b22a0") - @WifiBaseTest.wifi_test_wrap - def test_wifi_scans_5GHz_and_both(self): - """Perform two WifiScanner scans, one at 5GHz and the other at both - 2.4GHz and 5GHz - - Initial Conditions: - * Set multiple APs broadcasting 2.4GHz and 5GHz. - - Expected Results: - * DUT reports success for starting both scans - * Scan results for each callback contains only the results on the - frequency scanned - * Wait for at least two scan results and confirm that separation - between them approximately equals to the expected interval - * Number of BSSIDs doesn't exceed - """ - scan_settings = [{"band": WifiEnums.WIFI_BAND_BOTH, - "periodInMs": 10000, # ms - "reportEvents": - WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, - "numBssidsPerScan": 24}, - {"band": WifiEnums.WIFI_BAND_5_GHZ, - "periodInMs": 10000, # ms - "reportEvents": - WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, - "numBssidsPerScan": 24}] - - self.scan_and_validate_results(scan_settings) - - @test_tracker_info(uuid="060469f1-fc6b-4255-ab6e-b1d5b54db53d") - @WifiBaseTest.wifi_test_wrap - def test_wifi_scans_24GHz_5GHz_and_DFS(self): - """Perform three WifiScanner scans, one at 5GHz, one at 2.4GHz and the - other at just 5GHz DFS channels - - Initial Conditions: - * Set multiple APs broadcasting 2.4GHz and 5GHz. - - Expected Results: - * DUT reports success for starting both scans - * Scan results for each callback contains only the results on the - frequency scanned - * Wait for at least two scan results and confirm that separation - between them approximately equals to the expected interval - * Number of BSSIDs doesn't exceed - """ - scan_settings = [ - {"band": WifiEnums.WIFI_BAND_5_GHZ_DFS_ONLY, - "periodInMs": 10000, # ms - "reportEvents": WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, - "numBssidsPerScan": 24}, - {"band": WifiEnums.WIFI_BAND_5_GHZ, - "periodInMs": 10000, # ms - "reportEvents": WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, - "numBssidsPerScan": 24}, - {"band": WifiEnums.WIFI_BAND_24_GHZ, - "periodInMs": 30000, # ms - "reportEvents": WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, - "numBssidsPerScan": 24} - ] - - self.scan_and_validate_results(scan_settings) - - @test_tracker_info(uuid="14104e98-27a0-43d5-9525-b36b65ac3957") - @WifiBaseTest.wifi_test_wrap - def test_wifi_scans_batch_and_24GHz(self): - """Perform two WifiScanner background scans, one in batch mode for both - bands and the other in periodic mode at 2.4GHz - - Initial Conditions: - * Set multiple APs broadcasting 2.4GHz and 5GHz. - - Expected Results: - * DUT reports success for starting both scans - * Scan results for each callback contains only the results on the - frequency scanned - * Wait for at least two scan results and confirm that separation - between them approximately equals to the expected interval - * Number of results in batch mode should match the setting - * Number of BSSIDs doesn't exceed - """ - scan_settings = [{"band": WifiEnums.WIFI_BAND_BOTH, - "periodInMs": 10000, # ms - "reportEvents": - WifiEnums.REPORT_EVENT_AFTER_BUFFER_FULL, - "numBssidsPerScan": 24, - "maxScansToCache": 2}, - {"band": WifiEnums.WIFI_BAND_24_GHZ, - "periodInMs": 10000, # ms - "reportEvents": - WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, - "numBssidsPerScan": 24}] - - self.scan_and_validate_results(scan_settings) - - @test_tracker_info(uuid="cd6064b5-840b-4334-8cd4-8320a6cda52f") - @WifiBaseTest.wifi_test_wrap - def test_wifi_scans_batch_and_5GHz(self): - """Perform two WifiScanner background scans, one in batch mode for both - bands and the other in periodic mode at 5GHz - - Initial Conditions: - * Set multiple APs broadcasting 2.4GHz and 5GHz. - - Expected Results: - * DUT reports success for starting both scans - * Scan results for each callback contains only the results on the - frequency scanned - * Wait for at least two scan results and confirm that separation - between them approximately equals to the expected interval - * Number of results in batch mode should match the setting - * Number of BSSIDs doesn't exceed - """ - scan_settings = [{"band": WifiEnums.WIFI_BAND_BOTH, - "periodInMs": 10000, # ms - "reportEvents": - WifiEnums.REPORT_EVENT_AFTER_BUFFER_FULL, - "numBssidsPerScan": 24, - "maxScansToCache": 2}, - {"band": WifiEnums.WIFI_BAND_5_GHZ, - "periodInMs": 10000, # ms - "reportEvents": - WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, - "numBssidsPerScan": 24}] - - self.scan_and_validate_results(scan_settings) - - @test_tracker_info(uuid="9f48cb0c-de87-4cd2-9e50-857579d44079") - @WifiBaseTest.wifi_test_wrap - def test_wifi_scans_24GHz_5GHz_full_result(self): - """Perform two WifiScanner background scans, one at 2.4GHz and - the other at 5GHz. Report full scan results. - - Initial Conditions: - * Set multiple APs broadcasting 2.4GHz and 5GHz. - - Expected Results: - * DUT reports success for starting both scans - * Scan results for each callback contains only the results on the - frequency scanned - * Wait for at least two scan results and confirm that separation - between them approximately equals to the expected interval - * Number of BSSIDs doesn't exceed - """ - scan_settings = [ - {"band": WifiEnums.WIFI_BAND_24_GHZ, - "periodInMs": 10000, # ms - "reportEvents": WifiEnums.REPORT_EVENT_FULL_SCAN_RESULT - | WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, - "numBssidsPerScan": 24}, - {"band": WifiEnums.WIFI_BAND_5_GHZ, - "periodInMs": 10000, # ms - "reportEvents": WifiEnums.REPORT_EVENT_FULL_SCAN_RESULT - | WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, - "numBssidsPerScan": 24} - ] - - self.scan_and_validate_results(scan_settings) - - """ Tests End """ diff --git a/acts/tests/google/wifi/WifiScannerScanTest.py b/acts/tests/google/wifi/WifiScannerScanTest.py deleted file mode 100755 index 05945dcbc3..0000000000 --- a/acts/tests/google/wifi/WifiScannerScanTest.py +++ /dev/null @@ -1,1097 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2016 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import itertools -import queue -import time -import traceback - -from acts import asserts -from acts import base_test -from acts import utils -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi import wifi_constants -from acts.test_utils.wifi import wifi_test_utils as wutils -from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest - -SCANTIME = 10000 #framework support only 10s as minimum scan interval -NUMBSSIDPERSCAN = 8 -EVENT_TAG = "WifiScannerScan" -SCAN_TIME_PASSIVE = 47 # dwell time plus 2ms -SCAN_TIME_ACTIVE = 32 # dwell time plus 2ms -SHORT_TIMEOUT = 30 -NETWORK_ID_ERROR = "Network don't have ID" -NETWORK_ERROR = "Device is not connected to reference network" -INVALID_RESULT = "Test fail because scan result reported are not valid" -EMPTY_RESULT = "Test fail because empty scan result reported" -KEY_RET = "ResultElapsedRealtime" -ATTENUATOR = 0 - -class WifiScannerScanError(Exception): - pass - - -class WifiScannerScanTest(WifiBaseTest): - def __init__(self, controllers): - WifiBaseTest.__init__(self, controllers) - # TODO(angli): Remove this list. - # There are order dependencies among these tests so we'll have to leave - # it here for now. :( - self.tests = ( - "test_available_channels_band_1", - "test_available_channels_band_2", - "test_available_channels_band_3", - "test_available_channels_band_4", - "test_available_channels_band_6", - "test_available_channels_band_7", - "test_wifi_scanner_single_scan_channel_sanity", - "test_wifi_scanner_with_wifi_off", - "test_single_scan_report_each_scan_for_channels_with_enumerated_params", - "test_single_scan_report_each_scan_for_band_with_enumerated_params", - "test_single_scan_report_full_scan_for_channels_with_enumerated_params", - "test_single_scan_report_full_scan_for_band_with_enumerated_params", - "test_single_scan_while_pno", - "test_wifi_scanner_single_scan_in_isolated", - "test_wifi_scanner_with_invalid_numBssidsPerScan", - "test_wifi_scanner_dual_radio_low_latency", - "test_wifi_scanner_dual_radio_low_power", - "test_wifi_scanner_dual_radio_high_accuracy") - - def setup_class(self): - self.dut = self.android_devices[0] - wutils.wifi_test_device_init(self.dut) - req_params = ("run_extended_test", "ping_addr", "max_bugreports", "dbs_supported_models") - opt_param = ["reference_networks"] - self.unpack_userparams( - req_param_names=req_params, opt_param_names=opt_param) - - if "AccessPoint" in self.user_params: - self.legacy_configure_ap_and_start(ap_count=2, mirror_ap=False) - - self.leeway = 10 - self.stime_channel = SCAN_TIME_PASSIVE - self.default_scan_setting = { - "band": wutils.WifiEnums.WIFI_BAND_BOTH, - "periodInMs": SCANTIME, - "reportEvents": wutils.WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN - } - self.default_batch_scan_setting = { - "band": wutils.WifiEnums.WIFI_BAND_BOTH, - "periodInMs": SCANTIME, - "reportEvents": wutils.WifiEnums.REPORT_EVENT_AFTER_BUFFER_FULL - } - self.log.debug("Run extended test: {}".format(self.run_extended_test)) - self.wifi_chs = wutils.WifiChannelUS(self.dut.model) - asserts.assert_true(self.dut.droid.wifiIsScannerSupported(), - "Device %s doesn't support WifiScanner, abort." % - self.dut.model) - self.attenuators = wutils.group_attenuators(self.attenuators) - self.attenuators[0].set_atten(0) - self.attenuators[1].set_atten(0) - - def teardown_test(self): - base_test.BaseTestClass.teardown_test(self) - self.log.debug("Shut down all wifi scanner activities.") - self.dut.droid.wifiScannerShutdown() - - def on_fail(self, test_name, begin_time): - if self.max_bugreports > 0: - self.dut.take_bug_report(test_name, begin_time) - self.max_bugreports -= 1 - self.dut.cat_adb_log(test_name, begin_time) - - def teardown_class(self): - if "AccessPoint" in self.user_params: - del self.user_params["reference_networks"] - del self.user_params["open_network"] - - """ Helper Functions Begin """ - - def wifi_generate_scanner_scan_settings(self, extended, scan_type, - report_result): - """Generates all the combinations of different scan setting parameters. - - Args: - extended: True for extended setting - scan_type: key for type of scan - report_result: event type of report scan results - - Returns: - A list of dictionaries each representing a set of scan settings. - """ - base_scan_time = [SCANTIME * 2] - if scan_type == "band": - scan_types_setting = [wutils.WifiEnums.WIFI_BAND_BOTH] - else: - scan_types_setting = [self.wifi_chs.MIX_CHANNEL_SCAN] - num_of_bssid = [NUMBSSIDPERSCAN * 4] - max_scan_cache = [0] - if extended: - base_scan_time.append(SCANTIME) - if scan_type == "band": - scan_types_setting.extend( - [wutils.WifiEnums.WIFI_BAND_24_GHZ, - wutils.WifiEnums.WIFI_BAND_5_GHZ_WITH_DFS, - wutils.WifiEnums.WIFI_BAND_BOTH_WITH_DFS]) - else: - scan_types_setting.extend( - [self.wifi_chs.NONE_DFS_5G_FREQUENCIES, self.wifi_chs. - ALL_2G_FREQUENCIES, self.wifi_chs.DFS_5G_FREQUENCIES, - self.wifi_chs.ALL_5G_FREQUENCIES]) - num_of_bssid.append(NUMBSSIDPERSCAN * 3) - max_scan_cache.append(5) - # Generate all the combinations of report types and scan types - if report_result == wutils.WifiEnums.REPORT_EVENT_FULL_SCAN_RESULT: - report_types = {"reportEvents": report_result} - setting_combinations = list(itertools.product(scan_types_setting, - base_scan_time)) - # Create scan setting strings based on the combinations - scan_settings = [] - for combo in setting_combinations: - s = dict(report_types) - s[scan_type] = combo[0] - s["periodInMs"] = combo[1] - scan_settings.append(s) - else: - report_types = {"reportEvents": report_result} - setting_combinations = list( - itertools.product(scan_types_setting, base_scan_time, - num_of_bssid, max_scan_cache)) - # Create scan setting strings based on the combinations - scan_settings = [] - for combo in setting_combinations: - s = dict(report_types) - s[scan_type] = combo[0] - s["periodInMs"] = combo[1] - s["numBssidsPerScan"] = combo[2] - s["maxScansToCache"] = combo[3] - scan_settings.append(s) - return scan_settings - - def proces_and_valid_batch_scan_result(self, scan_resutls, scan_rt, - result_rt, scan_setting): - """This function process scan results and validate against settings used - while starting the scan. - - There are two steps for the verification. First it checks that all the - wifi networks in results are of the correct frequencies set by scan setting - params. Then it checks that the delta between the batch of scan results less - than the time required for scanning channel set by scan setting params. - - Args: - scan_results: scan results reported. - scan_rt: Elapsed real time on start scan. - result_rt: Elapsed ral time on results reported. - scan_setting: The params for the single scan. - - Returns: - bssids: total number of bssids scan result have - validity: True if the all scan result are valid. - """ - bssids = 0 - validity = True - scan_time_mic = 0 - scan_channels = [] - scan_time, scan_channels = wutils.get_scan_time_and_channels( - self.wifi_chs, scan_setting, self.stime_channel) - scan_time_mic = scan_time * 1000 - for i, batch in enumerate(scan_resutls, start=1): - asserts.assert_true( - batch["ScanResults"], - "At least one scan result is required to validate") - max_scan_interval = batch["ScanResults"][0][ - "timestamp"] + scan_time_mic - self.log.debug("max_scan_interval: %s", max_scan_interval) - for result in batch["ScanResults"]: - # Though the tests are run in shield box, there are leakes - # from outside environment. This would ignore any such SSIDs - ssid = result["SSID"] - if not ssid.startswith("2g_") or not ssid.startswith("5g_"): - continue - if (result["frequency"] not in scan_channels or - result["timestamp"] > max_scan_interval or - result["timestamp"] < scan_rt * 1000 or - result["timestamp"] > result_rt * 1000): - self.log.error("Result didn't match requirement: %s", - result) - validity = False - self.log.info("Number of scan result in batch %s: %s", i, - len(batch["ScanResults"])) - bssids += len(batch["ScanResults"]) - return bssids, validity - - def pop_scan_result_events(self, event_name): - """Function to pop all the scan result events. - - Args: - event_name: event name. - - Returns: - results: list of scan result reported in events - """ - results = [] - try: - events = self.dut.ed.pop_all(event_name) - for event in events: - results.append(event["data"]["Results"]) - except queue.Empty as error: - self.log.debug("Number of Full scan results %s", len(results)) - return results - - def wifi_scanner_single_scan(self, scan_setting): - """Common logic for an enumerated wifi scanner single scan test case. - - 1. Start WifiScanner single scan for scan_setting. - 2. Wait for the scan result event, wait time depend on scan settings - parameter. - 3. Verify that scan results match with scan settings parameters. - 4. Also verify that only one scan result event trigger. - - Args: - scan_setting: The params for the single scan. - """ - data = wutils.start_wifi_single_scan(self.dut, scan_setting) - idx = data["Index"] - scan_rt = data["ScanElapsedRealtime"] - self.log.info( - "Wifi single shot scan started index: %s at real time: %s", idx, - scan_rt) - results = [] - #generating event wait time from scan setting plus leeway - scan_time, scan_channels = wutils.get_scan_time_and_channels( - self.wifi_chs, scan_setting, self.stime_channel) - wait_time = int(scan_time / 1000) + self.leeway - validity = False - #track number of result received - result_received = 0 - try: - for snumber in range(1, 3): - event_name = "{}{}onResults".format(EVENT_TAG, idx) - self.log.debug("Waiting for event: %s for time %s", event_name, - wait_time) - event = self.dut.ed.pop_event(event_name, wait_time) - self.log.debug("Event received: %s", event) - results = event["data"]["Results"] - result_received += 1 - bssids, validity = self.proces_and_valid_batch_scan_result( - results, scan_rt, event["data"][KEY_RET], scan_setting) - asserts.assert_equal( - len(results), 1, - "Test fail because number of scan result %s" % - len(results)) - asserts.assert_true(bssids > 0, EMPTY_RESULT) - asserts.assert_true(validity, INVALID_RESULT) - self.log.info("Scan number Buckets: %s\nTotal BSSID: %s", - len(results), bssids) - except queue.Empty as error: - asserts.assert_true( - result_received >= 1, - "Event did not triggered for single shot {}".format(error)) - finally: - self.dut.droid.wifiScannerStopScan(idx) - #For single shot number of result received and length of result should be one - asserts.assert_true( - result_received == 1, - "Test fail because received result {}".format(result_received)) - - def wifi_scanner_single_scan_full(self, scan_setting): - """Common logic for single scan test case for full scan result. - - 1. Start WifiScanner single scan with scan_setting for full scan result. - 2. Wait for the scan result event, wait time depend on scan settings - parameter. - 3. Pop all full scan result events occurred earlier. - 4. Verify that full scan results match with normal scan results. - 5. If the scan type is included in scan_setting, verify that the - radioChainInfos length. - - Args: - scan_setting: The parameters for the single scan. - """ - self.dut.ed.clear_all_events() - data = wutils.start_wifi_single_scan(self.dut, scan_setting) - idx = data["Index"] - scan_rt = data["ScanElapsedRealtime"] - self.log.info("Wifi single shot scan started with index: %s", idx) - #generating event wait time from scan setting plus leeway - scan_time, scan_channels = wutils.get_scan_time_and_channels( - self.wifi_chs, scan_setting, self.stime_channel) - wait_time = int(scan_time / 1000) + self.leeway - results = [] - validity = False - try: - event_name = "%s%sonResults" % (EVENT_TAG, idx) - self.log.debug("Waiting for event: %s for time %s", event_name, - wait_time) - event = self.dut.ed.pop_event(event_name, wait_time) - self.log.info("Event received: %s", event) - bssids, validity = (self.proces_and_valid_batch_scan_result( - event["data"]["Results"], scan_rt, event["data"][KEY_RET], - scan_setting)) - asserts.assert_true(bssids > 0, EMPTY_RESULT) - asserts.assert_true(validity, INVALID_RESULT) - event_name = "{}{}onFullResult".format(EVENT_TAG, idx) - results = self.pop_scan_result_events(event_name) - asserts.assert_true( - len(results) >= bssids, - "Full single shot result don't match {}".format(len(results))) - if 'type' in scan_setting.keys(): - for item in results: - self.verify_radio_chain_length(scan_setting['type'], item) - except queue.Empty as error: - raise AssertionError( - "Event did not triggered for single shot {}".format(error)) - finally: - self.dut.droid.wifiScannerStopScan(idx) - - def verify_radio_chain_length(self, scan_setting_type, scan_result): - llen = len(scan_result[0]["radioChainInfos"]) - if scan_setting_type == wutils.WifiEnums.SCAN_TYPE_LOW_LATENCY \ - or scan_setting_type == wutils.WifiEnums.SCAN_TYPE_LOW_POWER: - asserts.assert_true(llen == 1, - "radioChainInfos len expected:{} " - "actual:{}".format(1, llen)) - else: - asserts.assert_true(llen == 2, - "radioChainInfos len expected:{} " - "actual:{}".format(2, llen)) - - def wifi_scanner_batch_scan_full(self, scan_setting): - """Common logic for batch scan test case for full scan result. - - 1. Start WifiScanner batch scan with scan_setting for full scan result. - 2. Wait for the scan result event, wait time depend on scan settings - parameter. - 3. Pop all full scan result events occurred earlier. - 4. Verify that full scan results match with scan results. - - Args: - scan_setting: The params for the batch scan. - """ - self.dut.ed.clear_all_events() - data = wutils.start_wifi_background_scan(self.dut, scan_setting) - idx = data["Index"] - scan_rt = data["ScanElapsedRealtime"] - self.log.info("Wifi batch shot scan started with index: %s", idx) - #generating event wait time from scan setting plus leeway - scan_time, scan_channels = wutils.get_scan_time_and_channels( - self.wifi_chs, scan_setting, self.stime_channel) - # multiply scan period by two to account for scheduler changing period - scan_time += scan_setting[ - 'periodInMs'] * 2 #add scan period delay for next cycle - wait_time = scan_time / 1000 + self.leeway - validity = False - try: - for snumber in range(1, 3): - results = [] - event_name = "%s%sonResults" % (EVENT_TAG, idx) - self.log.debug("Waiting for event: %s for time %s", event_name, - wait_time) - event = self.dut.ed.pop_event(event_name, wait_time) - self.log.debug("Event received: %s", event) - bssids, validity = self.proces_and_valid_batch_scan_result( - event["data"]["Results"], scan_rt, event["data"][KEY_RET], - scan_setting) - event_name = "%s%sonFullResult" % (EVENT_TAG, idx) - results = self.pop_scan_result_events(event_name) - asserts.assert_true( - len(results) >= bssids, - "Full single shot result don't match %s" % len(results)) - asserts.assert_true(bssids > 0, EMPTY_RESULT) - asserts.assert_true(validity, INVALID_RESULT) - except queue.Empty as error: - raise AssertionError("Event did not triggered for batch scan %s" % - error) - finally: - self.dut.droid.wifiScannerStopBackgroundScan(idx) - self.dut.ed.clear_all_events() - - def wifi_scanner_batch_scan(self, scan_setting): - """Common logic for an enumerated wifi scanner batch scan test case. - - 1. Start WifiScanner batch scan for given scan_setting. - 2. Wait for the scan result event, wait time depend on scan settings - parameter. - 3. Verify that scan results match with scan settings parameters. - 4. Also verify that multiple scan result events trigger. - - Args: - scan_setting: The parameters for the batch scan. - """ - data = wutils.start_wifi_background_scan(self.dut, scan_setting) - idx = data["Index"] - scan_rt = data["ScanElapsedRealtime"] - self.log.info( - "Wifi background scan started with index: %s real time %s", idx, - scan_rt) - scan_time, scan_channels = wutils.get_scan_time_and_channels( - self.wifi_chs, scan_setting, self.stime_channel) - #generating event wait time from scan setting plus leeway - time_cache = 0 - number_bucket = 1 #bucket for Report result on each scan - check_get_result = False - if scan_setting[ - 'reportEvents'] == wutils.WifiEnums.REPORT_EVENT_AFTER_BUFFER_FULL: - check_get_result = True - if ('maxScansToCache' in scan_setting and - scan_setting['maxScansToCache'] != 0): - time_cache = (scan_setting['maxScansToCache'] * - scan_setting['periodInMs']) - number_bucket = scan_setting['maxScansToCache'] - else: - time_cache = 10 * scan_setting['periodInMs' - ] #10 as default max scan cache - number_bucket = 10 - else: - time_cache = scan_setting[ - 'periodInMs' - ] #need while waiting for seconds resutls - # multiply cache time by two to account for scheduler changing period - wait_time = (time_cache * 2 + scan_time) / 1000 + self.leeway - validity = False - try: - for snumber in range(1, 3): - event_name = "%s%sonResults" % (EVENT_TAG, idx) - self.log.info("Waiting for event: %s for time %s", event_name, - wait_time) - event = self.dut.ed.pop_event(event_name, wait_time) - self.log.debug("Event received: %s", event) - results = event["data"]["Results"] - bssids, validity = (self.proces_and_valid_batch_scan_result( - results, scan_rt, event["data"][KEY_RET], scan_setting)) - self.log.info("Scan number: %s\n Buckets: %s\n BSSID: %s", - snumber, len(results), bssids) - asserts.assert_equal( - len(results), number_bucket, - "Test fail because number_bucket %s" % len(results)) - asserts.assert_true(bssids >= 1, EMPTY_RESULT) - asserts.assert_true(validity, INVALID_RESULT) - if snumber % 2 == 1 and check_get_result: - self.log.info("Get Scan result using GetScanResult API") - time.sleep(wait_time / number_bucket) - if self.dut.droid.wifiScannerGetScanResults(): - event = self.dut.ed.pop_event(event_name, 1) - self.log.debug("Event onResults: %s", event) - results = event["data"]["Results"] - bssids, validity = self.proces_and_valid_batch_scan_result( - results, scan_rt, event["data"][KEY_RET], - scan_setting) - self.log.info("Got Scan result number: %s BSSID: %s", - snumber, bssids) - asserts.assert_true(bssids >= 1, EMPTY_RESULT) - asserts.assert_true(validity, INVALID_RESULT) - else: - self.log.error("Error while fetching the scan result") - except queue.Empty as error: - raise AssertionError("Event did not triggered for batch scan %s" % - error) - finally: - self.dut.droid.wifiScannerStopBackgroundScan(idx) - self.dut.ed.clear_all_events() - - def start_wifi_scanner_single_scan_expect_failure(self, scan_setting): - """Common logic to test wif scanner single scan with invalid settings - or environment - - 1. Start WifiScanner batch scan for setting parameters. - 2. Verify that scan is not started. - - Args: - scan_setting: The params for the single scan. - """ - try: - idx = self.dut.droid.wifiScannerStartScan(scan_setting) - event = self.dut.ed.pop_event( - "{}{}onFailure".format(EVENT_TAG, idx), SHORT_TIMEOUT) - except queue.Empty as error: - raise AssertionError("Did not get expected onFailure {}".format( - error)) - - def start_wifi_scanner_background_scan_expect_failure(self, scan_setting): - """Common logic to test wif scanner batch scan with invalid settings - or environment - - 1. Start WifiScanner batch scan for setting parameters. - 2. Verify that scan is not started. - - Args: - scan_setting: The params for the single scan. - """ - try: - idx = self.dut.droid.wifiScannerStartBackgroundScan(scan_setting) - event = self.dut.ed.pop_event( - "{}{}onFailure".format(EVENT_TAG, idx), SHORT_TIMEOUT) - except queue.Empty as error: - raise AssertionError("Did not get expected onFailure {}".format( - error)) - - def check_get_available_channels_with_one_band(self, band): - """Common logic to check available channels for a band. - - 1. Get available channels for band. - 2. Verify that channels match with supported channels for band. - - Args: - band: wifi band.""" - - r = self.dut.droid.wifiScannerGetAvailableChannels(band) - self.log.debug(band) - self.log.debug(r) - expected = self.wifi_chs.band_to_freq(band) - asserts.assert_equal(set(r), set(expected), "Band %s failed." % band) - - def connect_to_reference_network(self): - """Connect to reference network and make sure that connection happen""" - self.dut.droid.wakeLockAcquireBright() - self.dut.droid.wakeUpNow() - try: - self.dut.droid.wifiConnectByConfig(self.reference_networks[0]["2g"]) - connect_result = self.dut.ed.pop_event( - wifi_constants.CONNECT_BY_CONFIG_SUCCESS, SHORT_TIMEOUT) - self.log.info(connect_result) - return wutils.track_connection(self.dut, - self.reference_networks[0]["2g"]["SSID"], 1) - except Exception as error: - self.log.exception(traceback.format_exc()) - self.log.error("Connection to network fail because %s", error) - return False - finally: - self.dut.droid.wifiLockRelease() - self.dut.droid.goToSleepNow() - - """ Helper Functions End """ - """ Tests Begin """ - - # Test channels - """ Test available channels for different bands. - - 1. Get available channels for different bands. - 2. Verify that channels match with supported channels for respective band. - """ - @test_tracker_info(uuid="7cca8142-529f-4951-ab6f-cd03b359b3cc") - def test_available_channels_band_1(self): - self.check_get_available_channels_with_one_band(1) - - @test_tracker_info(uuid="612afda1-0d74-4d2f-bc37-72ef2b98310a") - def test_available_channels_band_2(self): - self.check_get_available_channels_with_one_band(2) - - @test_tracker_info(uuid="a9275bb9-afa7-4dd4-b2e0-60296ffd33bb") - def test_available_channels_band_3(self): - self.check_get_available_channels_with_one_band(3) - - @test_tracker_info(uuid="5413632e-ce72-4ecc-bf9b-33ac9e4bf3fc") - def test_available_channels_band_4(self): - self.check_get_available_channels_with_one_band(4) - - @test_tracker_info(uuid="a8f40b4f-d79d-4d2f-bed8-3b139a082f6c") - def test_available_channels_band_6(self): - self.check_get_available_channels_with_one_band(6) - - @test_tracker_info(uuid="84cdfc25-8e64-42c7-b7f9-0a04e45d78b6") - def test_available_channels_band_7(self): - self.check_get_available_channels_with_one_band(7) - - @test_tracker_info(uuid="95069244-b76c-4834-b3a6-96b0d8da98d8") - def test_single_scan_report_each_scan_for_channels_with_enumerated_params( - self): - """Test WiFi scanner single scan for channels with enumerated settings. - - 1. Start WifiScanner single scan for different channels with enumerated - scan settings. - 2. Verify that scan results match with respective scan settings. - """ - scan_settings = self.wifi_generate_scanner_scan_settings( - self.run_extended_test, "channels", - wutils.WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN) - self.log.debug("Scan settings: %s\n%s", len(scan_settings), - scan_settings) - self.wifi_scanner_single_scan(scan_settings[0]) - - @test_tracker_info(uuid="5595ebe5-6d91-4379-a606-be59967e5ec9") - def test_single_scan_report_each_scan_for_band_with_enumerated_params( - self): - """Test WiFi scanner single scan for bands with enumerated settings. - - 1. Start WifiScanner single scan for different bands with enumerated - scan settings. - 2. Verify that scan results match with respective scan settings. - """ - scan_settings = self.wifi_generate_scanner_scan_settings( - self.run_extended_test, "band", - wutils.WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN) - self.log.debug("Scan settings:%s\n%s", len(scan_settings), - scan_settings) - self.wifi_scanner_single_scan(scan_settings[0]) - - @test_tracker_info(uuid="44989f93-e63b-4c2e-a90a-a483477303bb") - def test_batch_scan_report_buffer_full_for_channels_with_enumerated_params( - self): - """Test WiFi scanner batch scan using channels with enumerated settings - to report buffer full scan results. - - 1. Start WifiScanner batch scan using different channels with enumerated - scan settings to report buffer full scan results. - 2. Verify that scan results match with respective scan settings. - """ - scan_settings = self.wifi_generate_scanner_scan_settings( - self.run_extended_test, "channels", - wutils.WifiEnums.REPORT_EVENT_AFTER_BUFFER_FULL) - self.log.debug("Scan settings:%s\n%s", len(scan_settings), - scan_settings) - self.wifi_scanner_batch_scan(scan_settings[0]) - - @test_tracker_info(uuid="63538df6-388a-4c16-964f-e9c19b750e07") - def test_batch_scan_report_buffer_full_for_band_with_enumerated_params( - self): - """Test WiFi scanner batch scan using band with enumerated settings - to report buffer full scan results. - - 1. Start WifiScanner batch scan using different bands with enumerated - scan settings to report buffer full scan results. - 2. Verify that scan results match with respective scan settings. - """ - scan_settings = self.wifi_generate_scanner_scan_settings( - self.run_extended_test, "band", - wutils.WifiEnums.REPORT_EVENT_AFTER_BUFFER_FULL) - self.log.debug("Scan settings:{}\n{}".format( - len(scan_settings), scan_settings)) - self.wifi_scanner_batch_scan(scan_settings[0]) - - @test_tracker_info(uuid="bd4e8c53-16c8-4ed6-b680-55c1ba688ad8") - def test_batch_scan_report_each_scan_for_channels_with_enumerated_params( - self): - """Test WiFi scanner batch scan using channels with enumerated settings - to report each scan results. - - 1. Start WifiScanner batch scan using different channels with enumerated - scan settings to report each scan results. - 2. Verify that scan results match with respective scan settings. - """ - scan_settings = self.wifi_generate_scanner_scan_settings( - self.run_extended_test, "channels", - wutils.WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN) - self.log.debug("Scan settings:{}\n{}".format( - len(scan_settings), scan_settings)) - self.wifi_scanner_batch_scan(scan_settings[0]) - - @test_tracker_info(uuid="d11e8c09-97d0-49c1-bf09-b9ec672c2fa6") - def test_batch_scan_report_each_scan_for_band_with_enumerated_params(self): - """Test WiFi scanner batch scan using band with enumerated settings - to report each scan results. - - 1. Start WifiScanner batch scan using different bands with enumerated - scan settings to report each scan results. - 2. Verify that scan results match with respective scan settings. - """ - scan_settings = self.wifi_generate_scanner_scan_settings( - self.run_extended_test, "band", - wutils.WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN) - self.log.debug("Scan settings:{}\n{}".format( - len(scan_settings), scan_settings)) - self.wifi_scanner_batch_scan(scan_settings[0]) - - @test_tracker_info(uuid="7f967b0e-82fe-403e-9d74-0dee7f09a21d") - def test_single_scan_report_full_scan_for_channels_with_enumerated_params( - self): - """Test WiFi scanner single scan using channels with enumerated settings - to report full scan results. - - 1. Start WifiScanner single scan using different channels with enumerated - scan settings to report full scan results. - 2. Verify that scan results match with respective scan settings. - """ - scan_settings = self.wifi_generate_scanner_scan_settings( - self.run_extended_test, "channels", - wutils.WifiEnums.REPORT_EVENT_FULL_SCAN_RESULT) - self.log.debug("Full Scan settings:{}\n{}".format( - len(scan_settings), scan_settings)) - self.wifi_scanner_single_scan_full(scan_settings[0]) - - @test_tracker_info(uuid="34d09f60-31bf-4952-8fb3-03fc93ec98fa") - def test_single_scan_report_full_scan_for_band_with_enumerated_params( - self): - """Test WiFi scanner single scan using band with enumerated settings - to report full scan results. - - 1. Start WifiScanner single scan using different bands with enumerated - scan settings to report full scan results. - 2. Verify that scan results match with respective scan settings. - """ - scan_settings = self.wifi_generate_scanner_scan_settings( - self.run_extended_test, "band", - wutils.WifiEnums.REPORT_EVENT_FULL_SCAN_RESULT) - self.log.debug("Full Scan settings:{}\n{}".format( - len(scan_settings), scan_settings)) - self.wifi_scanner_single_scan_full(scan_settings[0]) - - @test_tracker_info(uuid="0ddccf2e-b518-45a7-ae75-96924070b841") - def test_batch_scan_report_full_scan_for_channels_with_enumerated_params( - self): - """Test WiFi scanner batch scan using channels with enumerated settings - to report full scan results. - - 1. Start WifiScanner batch scan using different channels with enumerated - scan settings to report full scan results. - 2. Verify that scan results match with respective scan settings. - """ - scan_settings = self.wifi_generate_scanner_scan_settings( - self.run_extended_test, "channels", - wutils.WifiEnums.REPORT_EVENT_FULL_SCAN_RESULT) - self.log.debug("Full Scan settings:{}\n{}".format( - len(scan_settings), scan_settings)) - self.wifi_scanner_batch_scan_full(scan_settings[0]) - - @test_tracker_info(uuid="0685b667-8470-43a0-923d-dee71428f8ce") - def test_batch_scan_report_full_scan_for_band_with_enumerated_params(self): - """Test WiFi scanner batch scan using channels with enumerated settings - to report full scan results. - - 1. Start WifiScanner batch scan using different channels with enumerated - scan settings to report full scan results. - 2. Verify that scan results match with respective scan settings. - """ - scan_settings = self.wifi_generate_scanner_scan_settings( - self.run_extended_test, "band", - wutils.WifiEnums.REPORT_EVENT_FULL_SCAN_RESULT) - self.log.debug("Full Scan settings:{}\n{}".format( - len(scan_settings), scan_settings)) - self.wifi_scanner_batch_scan_full(scan_settings[0]) - - @test_tracker_info(uuid="e9a7cfb5-21c4-4c40-8169-8d88b65a1dee") - @WifiBaseTest.wifi_test_wrap - def test_single_scan_while_pno(self): - """Test wifi scanner single scan parallel to PNO connection. - - 1. Check device have a saved network. - 2. Trigger PNO by attenuate the signal to move out of range. - 3. Start WifiScanner single scan for both band with default scan settings. - 4. Verify that scanner report single scan results. - 5. Attenuate the signal to move in range. - 6. Verify connection occurred through PNO. - """ - self.log.info("Check connection through PNO for reference network") - self.attenuators[ATTENUATOR].set_atten(0) - asserts.assert_true(self.connect_to_reference_network(), NETWORK_ERROR) - time.sleep(10) #wait for connection to be active - asserts.assert_true( - wutils.validate_connection(self.dut, self.ping_addr), - "Error, No internet connection for current network") - - current_network = self.dut.droid.wifiGetConnectionInfo() - self.log.info("Current network: {}".format(current_network)) - asserts.assert_true('network_id' in current_network, NETWORK_ID_ERROR) - asserts.assert_true(current_network['network_id'] >= 0, NETWORK_ERROR) - self.log.info("Kicking PNO for reference network") - self.attenuators[ATTENUATOR].set_atten(90) - time.sleep(10) #wait for PNO to be kicked - self.log.info("Starting single scan while PNO") - self.wifi_scanner_single_scan(self.default_scan_setting) - self.attenuators[ATTENUATOR].set_atten(0) - self.log.info("Check connection through PNO for reference network") - time.sleep(60) #wait for connection through PNO - current_network = self.dut.droid.wifiGetConnectionInfo() - self.log.info("Current network: {}".format(current_network)) - asserts.assert_true('network_id' in current_network, NETWORK_ID_ERROR) - asserts.assert_true(current_network['network_id'] >= 0, NETWORK_ERROR) - time.sleep(10) #wait for IP to be assigned - asserts.assert_true( - wutils.validate_connection(self.dut, self.ping_addr), - "Error, No internet connection for current network") - wutils.wifi_forget_network(self.dut, - self.reference_networks[0]["2g"]["SSID"]) - - @test_tracker_info(uuid="fc18d947-0b5a-42b4-98f3-dd1f2b52a7af") - def test_wifi_connection_and_pno_while_batch_scan(self): - """Test configuring a connection and PNO connection parallel to wifi - scanner batch scan. - - 1. Start WifiScanner batch scan with default batch scan settings. - 2. Wait for scan result event for a time depend on scan settings. - 3. Verify reported batch scan results. - 4. Configure a connection to reference network. - 5. Verify that connection to reference network occurred. - 6. Wait for scan result event for a time depend on scan settings. - 7. Verify reported batch scan results. - 8. Trigger PNO by attenuate the signal to move out of range. - 9. Wait for scan result event for a time depend on scan settings. - 10. Verify reported batch scan results. - 11. Attenuate the signal to move in range. - 12. Verify connection occurred through PNO. - """ - self.attenuators[ATTENUATOR].set_atten(0) - data = wutils.start_wifi_background_scan( - self.dut, self.default_batch_scan_setting) - idx = data["Index"] - scan_rt = data["ScanElapsedRealtime"] - self.log.info( - "Wifi background scan started with index: {} rt {}".format( - idx, scan_rt)) - #generating event wait time from scan setting plus leeway - scan_time, scan_channels = wutils.get_scan_time_and_channels( - self.wifi_chs, self.default_batch_scan_setting, self.stime_channel) - #default number buckets - number_bucket = 10 - time_cache = self.default_batch_scan_setting[ - 'periodInMs'] * number_bucket #default cache - #add 2 seconds extra time for switch between the channel for connection scan - #multiply cache time by two to account for scheduler changing period - wait_time = (time_cache * 2 + scan_time) / 1000 + self.leeway + 2 - result_flag = 0 - try: - for snumber in range(1, 7): - event_name = "{}{}onResults".format(EVENT_TAG, idx) - self.log.info("Waiting for event: {}".format(event_name)) - event = self.dut.ed.pop_event(event_name, wait_time) - self.log.debug("Event onResults: {}".format(event)) - results = event["data"]["Results"] - bssids, validity = self.proces_and_valid_batch_scan_result( - results, scan_rt, event["data"][KEY_RET], - self.default_batch_scan_setting) - self.log.info( - "Scan number: {}\n Buckets: {}\n BSSID: {}".format( - snumber, len(results), bssids)) - asserts.assert_true(bssids >= 1, - "Not able to fetch scan result") - if snumber == 1: - self.log.info( - "Try to connect AP while waiting for event: {}".format( - event_name)) - asserts.assert_true(self.connect_to_reference_network(), - NETWORK_ERROR) - time.sleep(10) #wait for connection to be active - asserts.assert_true( - wutils.validate_connection(self.dut, self.ping_addr), - "Error, No internet connection for current network") - elif snumber == 3: - self.log.info("Kicking PNO for reference network") - self.attenuators[ATTENUATOR].set_atten(90) - elif snumber == 4: - self.log.info("Bring back device for PNO connection") - current_network = self.dut.droid.wifiGetConnectionInfo() - self.log.info("Current network: {}".format( - current_network)) - asserts.assert_true('network_id' in current_network, - NETWORK_ID_ERROR) - asserts.assert_true( - current_network['network_id'] == -1, - "Device is still connected to network {}".format( - current_network[wutils.WifiEnums.SSID_KEY])) - self.attenuators[ATTENUATOR].set_atten(0) - time.sleep( - 10 - ) #wait for connection to take place before waiting for scan result - elif snumber == 6: - self.log.info( - "Check connection through PNO for reference network") - current_network = self.dut.droid.wifiGetConnectionInfo() - self.log.info("Current network: {}".format( - current_network)) - asserts.assert_true('network_id' in current_network, - NETWORK_ID_ERROR) - asserts.assert_true(current_network['network_id'] >= 0, - NETWORK_ERROR) - time.sleep(10) #wait for connection to be active - asserts.assert_true( - wutils.validate_connection(self.dut, self.ping_addr), - "Error, No internet connection for current network") - wutils.wifi_forget_network(self.dut, - self.reference_networks[0]["2g"]["SSID"]) - except queue.Empty as error: - raise AssertionError( - "Event did not triggered for batch scan {}".format(error)) - finally: - self.dut.droid.wifiScannerStopBackgroundScan(idx) - self.dut.ed.clear_all_events() - - @test_tracker_info(uuid="7c25ce32-0fae-4a68-a7cb-fdf6d4d03caf") - def test_wifi_scanner_single_scan_channel_sanity(self): - """Test WiFi scanner single scan for mix channel with default setting - parameters. - - 1. Start WifiScanner single scan for mix channels with default setting - parameters. - 2. Verify that scan results match with respective scan settings. - """ - scan_setting = {"channels": self.wifi_chs.MIX_CHANNEL_SCAN, - "periodInMs": SCANTIME, - "reportEvents": - wutils.WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN} - self.wifi_scanner_single_scan(scan_setting) - - @test_tracker_info(uuid="7c8da0c4-dec7-4d04-abd4-f8ea467a5c6d") - @WifiBaseTest.wifi_test_wrap - def test_wifi_scanner_dual_radio_low_latency(self): - """Test WiFi scanner single scan for mix channel with default setting - parameters. - - 1. Start WifiScanner single scan for type = SCAN_TYPE_LOW_LATENCY. - 2. Verify that scan results match with respective scan settings. - """ - if self.dut.model not in self.dbs_supported_models: - asserts.skip( - ("Device %s does not support dual radio scanning.") - % self.dut.model) - scan_setting = {"channels": self.wifi_chs.MIX_CHANNEL_SCAN, - "periodInMs": SCANTIME, - "reportEvents": - wutils.WifiEnums.REPORT_EVENT_FULL_SCAN_RESULT, - "type": wutils.WifiEnums.SCAN_TYPE_LOW_LATENCY} - self.wifi_scanner_single_scan_full(scan_setting) - - @test_tracker_info(uuid="58b49b01-851b-4e45-b218-9fd27c0be921") - @WifiBaseTest.wifi_test_wrap - def test_wifi_scanner_dual_radio_low_power(self): - """Test WiFi scanner single scan for mix channel with default setting - parameters. - - 1. Start WifiScanner single scan for type = SCAN_TYPE_LOW_POWER. - 2. Verify that scan results match with respective scan settings. - """ - if self.dut.model not in self.dbs_supported_models: - asserts.skip( - ("Device %s does not support dual radio scanning.") - % self.dut.model) - scan_setting = {"channels": self.wifi_chs.MIX_CHANNEL_SCAN, - "periodInMs": SCANTIME, - "reportEvents": - wutils.WifiEnums.REPORT_EVENT_FULL_SCAN_RESULT, - "type": wutils.WifiEnums.SCAN_TYPE_LOW_POWER} - self.wifi_scanner_single_scan_full(scan_setting) - - @test_tracker_info(uuid="3e7288bc-45e4-497c-bf3a-977eec4e896e") - @WifiBaseTest.wifi_test_wrap - def test_wifi_scanner_dual_radio_high_accuracy(self): - """Test WiFi scanner single scan for mix channel with default setting - parameters. - - 1. Start WifiScanner single scan for type = SCAN_TYPE_HIGH_ACCURACY. - 2. Verify that scan results match with respective scan settings. - """ - if self.dut.model not in self.dbs_supported_models: - asserts.skip( - ("Device %s does not support dual radio scanning.") - % self.dut.model) - scan_setting = {"channels": self.wifi_chs.MIX_CHANNEL_SCAN, - "periodInMs": SCANTIME, - "reportEvents": - wutils.WifiEnums.REPORT_EVENT_FULL_SCAN_RESULT, - "type": wutils.WifiEnums.SCAN_TYPE_HIGH_ACCURACY} - self.wifi_scanner_single_scan_full(scan_setting) - - @test_tracker_info(uuid="e9f3aaad-4af3-4c54-9829-65dc1d6d4987") - def test_wifi_scanner_batch_scan_channel_sanity(self): - """Test WiFi scanner batch scan for mix channel with default setting - parameters to report the result on buffer full. - - 1. Start WifiScanner batch scan for mix channels with default setting - parameters. - 2. Verify that scan results match with respective scan settings. - """ - scan_setting = {"channels": self.wifi_chs.MIX_CHANNEL_SCAN, - "periodInMs": SCANTIME, - "reportEvents": - wutils.WifiEnums.REPORT_EVENT_AFTER_BUFFER_FULL} - self.wifi_scanner_batch_scan(scan_setting) - - @test_tracker_info(uuid="49ba245a-52e2-4c9b-90ad-a2fbc97e3d9f") - def test_wifi_scanner_batch_scan_period_too_short(self): - """Test WiFi scanner batch scan for band with too short period time. - - 1. Start WifiScanner batch scan for both band with interval period as 5s. - 2. Verify that scan is not started.""" - scan_setting = {"band": wutils.WifiEnums.WIFI_BAND_BOTH_WITH_DFS, - "periodInMs": 5000, - "reportEvents": - wutils.WifiEnums.REPORT_EVENT_AFTER_BUFFER_FULL} - self.start_wifi_scanner_background_scan_expect_failure(scan_setting) - - @test_tracker_info(uuid="6fe45cd7-4fac-4ddd-a950-b9431e68f735") - def test_wifi_scanner_single_scan_in_isolated(self): - """Test WiFi scanner in isolated environment with default scan settings. - - 1. Created isolated environment by attenuating the single by 90db - 2. Start WifiScanner single scan for mix channels with default setting - parameters. - 3. Verify that empty scan results reported. - """ - self.attenuators[0].set_atten(90) - self.attenuators[1].set_atten(90) - data = wutils.start_wifi_single_scan(self.dut, - self.default_scan_setting) - idx = data["Index"] - scan_rt = data["ScanElapsedRealtime"] - self.log.info("Wifi single shot scan started with index: {}".format( - idx)) - results = [] - #generating event wait time from scan setting plus leeway - scan_time, scan_channels = wutils.get_scan_time_and_channels( - self.wifi_chs, self.default_scan_setting, self.stime_channel) - wait_time = int(scan_time / 1000) + self.leeway - try: - event_name = "{}{}onResults".format(EVENT_TAG, idx) - self.log.debug("Waiting for event: {} for time {}".format( - event_name, wait_time)) - event = self.dut.ed.pop_event(event_name, wait_time) - self.log.debug("Event received: {}".format(event)) - results = event["data"]["Results"] - for batch in results: - asserts.assert_false(batch["ScanResults"], - "Test fail because report scan " - "results reported are not empty") - except queue.Empty as error: - raise AssertionError( - "Event did not triggered for in isolated environment {}".format( - error)) - finally: - self.dut.ed.clear_all_events() - self.attenuators[0].set_atten(0) - self.attenuators[1].set_atten(0) - - @test_tracker_info(uuid="46f817b9-97a3-455e-af2c-56f9aea64f7e") - def test_wifi_scanner_with_wifi_off(self): - """Test WiFi scanner single scan when wifi is off. - - 1. Toggle wifi state to off. - 2. Start WifiScanner single scan for both band with default scan settings. - 3. Verify that scan is not started. - """ - self.log.debug("Make sure wifi is off.") - wutils.wifi_toggle_state(self.dut, False) - self.start_wifi_scanner_single_scan_expect_failure( - self.default_scan_setting) - self.log.debug("Turning wifi back on.") - wutils.wifi_toggle_state(self.dut, True) - - @test_tracker_info(uuid="257ad734-c21f-49f4-b448-3986b70eba3d") - def test_wifi_scanner_with_invalid_numBssidsPerScan(self): - """Test WiFi scanner single scan with invalid number of bssids reported - per scan. - - 1. Start WifiScanner single scan with invalid number of bssids reported - per scan. - 2. Verify that scan results triggered for default supported number of - bssids per scan. - """ - scan_setting = { - "band": wutils.WifiEnums.WIFI_BAND_BOTH_WITH_DFS, - "periodInMs": SCANTIME, - "reportEvents": wutils.WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, - 'numBssidsPerScan': 33 - } - self.wifi_scanner_single_scan(scan_setting) - - """ Tests End """ diff --git a/acts/tests/google/wifi/WifiScannerTests.config b/acts/tests/google/wifi/WifiScannerTests.config deleted file mode 100755 index 85d599c2a8..0000000000 --- a/acts/tests/google/wifi/WifiScannerTests.config +++ /dev/null @@ -1,28 +0,0 @@ -{ - "_description": "Default wireless network setup for APs used in the test.", - "AP": [{"index": 0, - "radio0": {"settings": {"channel": 1}, "wifi-iface" : [{"ssid": "Test_1", "key": "hahahaha", "encryption": "psk2"},{"ssid": "Test_1.1", "key": "hahahaha", "encryption": "psk2"}, - {"ssid": "Test_1.2", "key": "hahahaha", "encryption": "psk2"},{"ssid": "Test_1.3", "key": "hahahaha", "encryption": "psk2"}]}, - "radio1": {"settings": {"channel": 40}, "wifi-iface" : [{"ssid": "Test_40", "key": "hahahaha", "encryption": "psk2"},{"ssid": "Test_40.1", "key": "hahahaha", "encryption": "psk2"}, - {"ssid": "Test_40.2", "key": "hahahaha", "encryption": "psk2"},{"ssid": "Test_40.3", "key": "hahahaha", "encryption": "psk2"}]} - }, - {"index": 1, - "radio0": {"settings": {"channel": 6}, "wifi-iface" : [{"ssid": "Test_6", "key": "hahahaha", "encryption": "psk"}, {"ssid": "Test_6.1", "key": "hahahaha", "encryption": "psk2"}, - {"ssid": "Test_6.2", "key": "hahahaha", "encryption": "psk2"}, {"ssid": "Test_6.3", "key": "hahahaha", "encryption": "psk2"}]}, - "radio1": {"settings": {"channel": 40}, "wifi-iface" : [{"ssid": "Test_40", "key": "hahahaha", "encryption": "psk"}, {"ssid": "Test_40.1", "key": "hahahaha", "encryption": "psk2"}, - {"ssid": "Test_40.3", "key": "hahahaha", "encryption": "psk2"}, {"ssid": "Test_40.2", "key": "hahahaha", "encryption": "psk2"}]} - }, - {"index": 2, - "radio0": {"settings": {"channel": 10}, "wifi-iface" : [{"ssid": "Test_10", "key": "hahahaha", "encryption": "psk2"}, {"ssid": "Test_10.1", "key": "hahahaha", "encryption": "psk2"}, - {"ssid": "Test_10.2", "key": "hahahaha", "encryption": "psk2"}, {"ssid": "Test_10.3", "key": "hahahaha", "encryption": "psk2"}]}, - "radio1": {"settings": {"channel": 44}, "wifi-iface" : [{"ssid": "Test_44", "key": "hahahaha", "encryption": "psk2"}, {"ssid": "Test_44.1", "key": "hahahaha", "encryption": "psk2"}, - {"ssid": "Test_44.2", "key": "hahahaha", "encryption": "psk2"}, {"ssid": "Test_44.3", "key": "hahahaha", "encryption": "psk2"}]} - }, - {"index": 3, - "radio0": {"settings": {"channel": 11}, "wifi-iface" : [{"ssid": "Test_11", "key": "hahahaha", "encryption": "psk2"}, {"ssid": "Test_11.1", "key": "hahahaha", "encryption": "psk2"}, - {"ssid": "Test_11.2", "key": "hahahaha", "encryption": "psk2"}, {"ssid": "Test_11.3", "key": "hahahaha", "encryption": "psk2"}]}, - "radio1": {"settings": {"channel": 149}, "wifi-iface" : [{"ssid": "Test_149", "key": "hahahaha", "encryption": "psk2"}, {"ssid": "Test_149.1", "key": "hahahaha", "encryption": "psk2"}, - {"ssid": "Test_149.2", "key": "hahahaha", "encryption": "psk2"}, {"ssid": "Test_149.3", "key": "hahahaha", "encryption": "psk2"}]} - } - ] -}
\ No newline at end of file diff --git a/acts/tests/google/wifi/WifiSensitivityTest.py b/acts/tests/google/wifi/WifiSensitivityTest.py deleted file mode 100644 index 73078501f2..0000000000 --- a/acts/tests/google/wifi/WifiSensitivityTest.py +++ /dev/null @@ -1,934 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the 'License'); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an 'AS IS' BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import collections -import csv -import itertools -import logging -import numpy -import os -from acts import asserts -from acts import context -from acts import base_test -from acts import utils -from acts.controllers import iperf_client -from acts.controllers.utils_lib import ssh -from acts.metrics.loggers.blackbox import BlackboxMappedMetricLogger -from acts.test_utils.wifi import ota_chamber -from acts.test_utils.wifi import wifi_performance_test_utils as wputils -from acts.test_utils.wifi import wifi_test_utils as wutils -from acts.test_utils.wifi import wifi_retail_ap as retail_ap -from functools import partial -from WifiRvrTest import WifiRvrTest -from WifiPingTest import WifiPingTest - - -class WifiSensitivityTest(WifiRvrTest, WifiPingTest): - """Class to test WiFi sensitivity tests. - - This class implements measures WiFi sensitivity per rate. It heavily - leverages the WifiRvrTest class and introduced minor differences to set - specific rates and the access point, and implements a different pass/fail - check. For an example config file to run this test class see - example_connectivity_performance_ap_sta.json. - """ - - RSSI_POLL_INTERVAL = 0.2 - VALID_TEST_CONFIGS = { - 1: ['legacy', 'VHT20'], - 2: ['legacy', 'VHT20'], - 6: ['legacy', 'VHT20'], - 10: ['legacy', 'VHT20'], - 11: ['legacy', 'VHT20'], - 36: ['legacy', 'VHT20', 'VHT40', 'VHT80'], - 40: ['legacy', 'VHT20'], - 44: ['legacy', 'VHT20'], - 48: ['legacy', 'VHT20'], - 149: ['legacy', 'VHT20', 'VHT40', 'VHT80'], - 153: ['legacy', 'VHT20'], - 157: ['legacy', 'VHT20'], - 161: ['legacy', 'VHT20'] - } - RateTuple = collections.namedtuple(('RateTuple'), - ['mcs', 'streams', 'data_rate']) - #yapf:disable - VALID_RATES = { - 'legacy_2GHz': [ - RateTuple(54, 1, 54), RateTuple(48, 1, 48), - RateTuple(36, 1, 36), RateTuple(24, 1, 24), - RateTuple(18, 1, 18), RateTuple(12, 1, 12), - RateTuple(11, 1, 11), RateTuple(9, 1, 9), - RateTuple(6, 1, 6), RateTuple(5.5, 1, 5.5), - RateTuple(2, 1, 2), RateTuple(1, 1, 1)], - 'legacy_5GHz': [ - RateTuple(54, 1, 54), RateTuple(48, 1, 48), - RateTuple(36, 1, 36), RateTuple(24, 1, 24), - RateTuple(18, 1, 18), RateTuple(12, 1, 12), - RateTuple(9, 1, 9), RateTuple(6, 1, 6)], - 'HT20': [ - RateTuple(7, 1, 72.2), RateTuple(6, 1, 65), - RateTuple(5, 1, 57.8), RateTuple(4, 1, 43.3), - RateTuple(3, 1, 26), RateTuple(2, 1, 21.7), - RateTuple(1, 1, 14.4), RateTuple(0, 1, 7.2), - RateTuple(15, 2, 144.4), RateTuple(14, 2, 130), - RateTuple(13, 2, 115.6), RateTuple(12, 2, 86.7), - RateTuple(11, 2, 57.8), RateTuple(10, 2, 43.4), - RateTuple(9, 2, 28.9), RateTuple(8, 2, 14.4)], - 'VHT20': [ - RateTuple(9, 1, 96), RateTuple(8, 1, 86.7), - RateTuple(7, 1, 72.2), RateTuple(6, 1, 65), - RateTuple(5, 1, 57.8), RateTuple(4, 1, 43.3), - RateTuple(3, 1, 28.9), RateTuple(2, 1, 21.7), - RateTuple(1, 1, 14.4), RateTuple(0, 1, 7.2), - RateTuple(9, 2, 192), RateTuple(8, 2, 173.3), - RateTuple(7, 2, 144.4), RateTuple(6, 2, 130.3), - RateTuple(5, 2, 115.6), RateTuple(4, 2, 86.7), - RateTuple(3, 2, 57.8), RateTuple(2, 2, 43.3), - RateTuple(1, 2, 28.9), RateTuple(0, 2, 14.4)], - 'VHT40': [ - RateTuple(9, 1, 96), RateTuple(8, 1, 86.7), - RateTuple(7, 1, 72.2), RateTuple(6, 1, 65), - RateTuple(5, 1, 57.8), RateTuple(4, 1, 43.3), - RateTuple(3, 1, 28.9), RateTuple(2, 1, 21.7), - RateTuple(1, 1, 14.4), RateTuple(0, 1, 7.2), - RateTuple(9, 2, 192), RateTuple(8, 2, 173.3), - RateTuple(7, 2, 144.4), RateTuple(6, 2, 130.3), - RateTuple(5, 2, 115.6), RateTuple(4, 2, 86.7), - RateTuple(3, 2, 57.8), RateTuple(2, 2, 43.3), - RateTuple(1, 2, 28.9), RateTuple(0, 2, 14.4)], - 'VHT80': [ - RateTuple(9, 1, 96), RateTuple(8, 1, 86.7), - RateTuple(7, 1, 72.2), RateTuple(6, 1, 65), - RateTuple(5, 1, 57.8), RateTuple(4, 1, 43.3), - RateTuple(3, 1, 28.9), RateTuple(2, 1, 21.7), - RateTuple(1, 1, 14.4), RateTuple(0, 1, 7.2), - RateTuple(9, 2, 192), RateTuple(8, 2, 173.3), - RateTuple(7, 2, 144.4), RateTuple(6, 2, 130.3), - RateTuple(5, 2, 115.6), RateTuple(4, 2, 86.7), - RateTuple(3, 2, 57.8), RateTuple(2, 2, 43.3), - RateTuple(1, 2, 28.9), RateTuple(0, 2, 14.4)], - } - #yapf:enable - - def __init__(self, controllers): - base_test.BaseTestClass.__init__(self, controllers) - self.testcase_metric_logger = ( - BlackboxMappedMetricLogger.for_test_case()) - self.testclass_metric_logger = ( - BlackboxMappedMetricLogger.for_test_class()) - self.publish_testcase_metrics = True - - def setup_class(self): - """Initializes common test hardware and parameters. - - This function initializes hardwares and compiles parameters that are - common to all tests in this class. - """ - self.dut = self.android_devices[-1] - req_params = [ - 'RetailAccessPoints', 'sensitivity_test_params', 'testbed_params', - 'RemoteServer' - ] - opt_params = ['main_network'] - self.unpack_userparams(req_params, opt_params) - self.testclass_params = self.sensitivity_test_params - self.num_atten = self.attenuators[0].instrument.num_atten - self.ping_server = ssh.connection.SshConnection( - ssh.settings.from_config(self.RemoteServer[0]['ssh_config'])) - self.iperf_server = self.iperf_servers[0] - self.iperf_client = self.iperf_clients[0] - self.access_point = retail_ap.create(self.RetailAccessPoints)[0] - self.log.info('Access Point Configuration: {}'.format( - self.access_point.ap_settings)) - self.log_path = os.path.join(logging.log_path, 'results') - os.makedirs(self.log_path, exist_ok=True) - self.atten_dut_chain_map = {} - self.testclass_results = [] - - # Turn WiFi ON - if self.testclass_params.get('airplane_mode', 1): - self.log.info('Turning on airplane mode.') - asserts.assert_true(utils.force_airplane_mode(self.dut, True), - "Can not turn on airplane mode.") - wutils.wifi_toggle_state(self.dut, True) - - # Configure test retries - self.user_params['retry_tests'] = [self.__class__.__name__] - - def teardown_class(self): - # Turn WiFi OFF - for dev in self.android_devices: - wutils.wifi_toggle_state(dev, False) - self.process_testclass_results() - - def setup_test(self): - self.retry_flag = False - - def teardown_test(self): - self.retry_flag = False - - def on_retry(self): - """Function to control test logic on retried tests. - - This function is automatically executed on tests that are being - retried. In this case the function resets wifi, toggles it off and on - and sets a retry_flag to enable further tweaking the test logic on - second attempts. - """ - self.retry_flag = True - for dev in self.android_devices: - wutils.reset_wifi(dev) - wutils.toggle_wifi_off_and_on(dev) - - def pass_fail_check(self, result): - """Checks sensitivity results and decides on pass/fail. - - Args: - result: dict containing attenuation, throughput and other meta - data - """ - result_string = ('Throughput = {}%, Sensitivity = {}.'.format( - result['peak_throughput_pct'], result['sensitivity'])) - if result['peak_throughput_pct'] < 95: - asserts.fail('Result unreliable. {}'.format(result_string)) - else: - asserts.explicit_pass('Test Passed. {}'.format(result_string)) - - def process_testclass_results(self): - """Saves and plots test results from all executed test cases.""" - # write json output - testclass_results_dict = collections.OrderedDict() - id_fields = ['mode', 'rate', 'num_streams', 'chain_mask'] - channels_tested = [] - for result in self.testclass_results: - testcase_params = result['testcase_params'] - test_id = self.extract_test_id(testcase_params, id_fields) - test_id = tuple(test_id.items()) - if test_id not in testclass_results_dict: - testclass_results_dict[test_id] = collections.OrderedDict() - channel = testcase_params['channel'] - if channel not in channels_tested: - channels_tested.append(channel) - if result['peak_throughput_pct'] >= 95: - testclass_results_dict[test_id][channel] = result[ - 'sensitivity'] - else: - testclass_results_dict[test_id][channel] = '' - - # calculate average metrics - metrics_dict = collections.OrderedDict() - id_fields = ['channel', 'mode', 'num_streams', 'chain_mask'] - for test_id in testclass_results_dict.keys(): - for channel in testclass_results_dict[test_id].keys(): - metric_tag = collections.OrderedDict(test_id, channel=channel) - metric_tag = self.extract_test_id(metric_tag, id_fields) - metric_tag = tuple(metric_tag.items()) - metrics_dict.setdefault(metric_tag, []) - sensitivity_result = testclass_results_dict[test_id][channel] - if sensitivity_result != '': - metrics_dict[metric_tag].append(sensitivity_result) - for metric_tag_tuple, metric_data in metrics_dict.items(): - metric_tag_dict = collections.OrderedDict(metric_tag_tuple) - metric_tag = 'ch{}_{}_nss{}_chain{}'.format( - metric_tag_dict['channel'], metric_tag_dict['mode'], - metric_tag_dict['num_streams'], metric_tag_dict['chain_mask']) - metric_key = "{}.avg_sensitivity".format(metric_tag) - metric_value = numpy.nanmean(metric_data) - self.testclass_metric_logger.add_metric(metric_key, metric_value) - - # write csv - csv_header = ['Mode', 'MCS', 'Streams', 'Chain', 'Rate (Mbps)'] - for channel in channels_tested: - csv_header.append('Ch. ' + str(channel)) - results_file_path = os.path.join(self.log_path, 'results.csv') - with open(results_file_path, mode='w') as csv_file: - writer = csv.DictWriter(csv_file, fieldnames=csv_header) - writer.writeheader() - for test_id, test_results in testclass_results_dict.items(): - test_id_dict = dict(test_id) - if 'legacy' in test_id_dict['mode']: - rate_list = self.VALID_RATES['legacy_2GHz'] - else: - rate_list = self.VALID_RATES[test_id_dict['mode']] - data_rate = next(rate.data_rate for rate in rate_list - if rate[:-1] == (test_id_dict['rate'], - test_id_dict['num_streams'])) - row_value = { - 'Mode': test_id_dict['mode'], - 'MCS': test_id_dict['rate'], - 'Streams': test_id_dict['num_streams'], - 'Chain': test_id_dict['chain_mask'], - 'Rate (Mbps)': data_rate, - } - for channel in channels_tested: - row_value['Ch. ' + str(channel)] = test_results.pop( - channel, ' ') - writer.writerow(row_value) - - if not self.testclass_params['traffic_type'].lower() == 'ping': - WifiRvrTest.process_testclass_results(self) - - def process_rvr_test_results(self, testcase_params, rvr_result): - """Post processes RvR results to compute sensitivity. - - Takes in the results of the RvR tests and computes the sensitivity of - the current rate by looking at the point at which throughput drops - below the percentage specified in the config file. The function then - calls on its parent class process_test_results to plot the result. - - Args: - rvr_result: dict containing attenuation, throughput and other meta - data - """ - rvr_result['peak_throughput'] = max(rvr_result['throughput_receive']) - rvr_result['peak_throughput_pct'] = 100 - throughput_check = [ - throughput < rvr_result['peak_throughput'] * - (self.testclass_params['throughput_pct_at_sensitivity'] / 100) - for throughput in rvr_result['throughput_receive'] - ] - consistency_check = [ - idx for idx in range(len(throughput_check)) - if all(throughput_check[idx:]) - ] - rvr_result['atten_at_range'] = rvr_result['attenuation'][ - consistency_check[0] - 1] - rvr_result['range'] = rvr_result['fixed_attenuation'] + ( - rvr_result['atten_at_range']) - rvr_result['sensitivity'] = self.testclass_params['ap_tx_power'] + ( - self.testbed_params['ap_tx_power_offset'][str( - testcase_params['channel'])] - rvr_result['range']) - WifiRvrTest.process_test_results(self, rvr_result) - - def process_ping_test_results(self, testcase_params, ping_result): - """Post processes RvR results to compute sensitivity. - - Takes in the results of the RvR tests and computes the sensitivity of - the current rate by looking at the point at which throughput drops - below the percentage specified in the config file. The function then - calls on its parent class process_test_results to plot the result. - - Args: - rvr_result: dict containing attenuation, throughput and other meta - data - """ - WifiPingTest.process_ping_results(self, testcase_params, ping_result) - ping_result['sensitivity'] = self.testclass_params['ap_tx_power'] + ( - self.testbed_params['ap_tx_power_offset'][str( - testcase_params['channel'])] - ping_result['range']) - - def setup_sensitivity_test(self, testcase_params): - if testcase_params['traffic_type'].lower() == 'ping': - self.setup_ping_test(testcase_params) - self.run_sensitivity_test = self.run_ping_test - self.process_sensitivity_test_results = ( - self.process_ping_test_results) - else: - self.setup_rvr_test(testcase_params) - self.run_sensitivity_test = self.run_rvr_test - self.process_sensitivity_test_results = ( - self.process_rvr_test_results) - - def setup_ap(self, testcase_params): - """Sets up the AP and attenuator to compensate for AP chain imbalance. - - Args: - testcase_params: dict containing AP and other test params - """ - band = self.access_point.band_lookup_by_channel( - testcase_params['channel']) - if '2G' in band: - frequency = wutils.WifiEnums.channel_2G_to_freq[ - testcase_params['channel']] - else: - frequency = wutils.WifiEnums.channel_5G_to_freq[ - testcase_params['channel']] - if frequency in wutils.WifiEnums.DFS_5G_FREQUENCIES: - self.access_point.set_region(self.testbed_params['DFS_region']) - else: - self.access_point.set_region(self.testbed_params['default_region']) - self.access_point.set_channel(band, testcase_params['channel']) - self.access_point.set_bandwidth(band, testcase_params['mode']) - self.access_point.set_power(band, testcase_params['ap_tx_power']) - self.access_point.set_rate(band, testcase_params['mode'], - testcase_params['num_streams'], - testcase_params['rate'], - testcase_params['short_gi']) - # Set attenuator offsets and set attenuators to initial condition - atten_offsets = self.testbed_params['chain_offset'][str( - testcase_params['channel'])] - for atten in self.attenuators: - if 'AP-Chain-0' in atten.path: - atten.offset = atten_offsets[0] - elif 'AP-Chain-1' in atten.path: - atten.offset = atten_offsets[1] - else: - atten.offset = 0 - self.log.info('Access Point Configuration: {}'.format( - self.access_point.ap_settings)) - - def setup_dut(self, testcase_params): - """Sets up the DUT in the configuration required by the test. - - Args: - testcase_params: dict containing AP and other test params - """ - # Check battery level before test - if not wputils.health_check(self.dut, 10): - asserts.skip('Battery level too low. Skipping test.') - # Turn screen off to preserve battery - self.dut.go_to_sleep() - if wputils.validate_network(self.dut, - testcase_params['test_network']['SSID']): - self.log.info('Already connected to desired network') - else: - wutils.reset_wifi(self.dut) - wutils.set_wifi_country_code(self.dut, - self.testclass_params['country_code']) - testcase_params['test_network']['channel'] = testcase_params[ - 'channel'] - wutils.wifi_connect(self.dut, - testcase_params['test_network'], - num_of_tries=5, - check_connectivity=False) - self.dut_ip = self.dut.droid.connectivityGetIPv4Addresses('wlan0')[0] - # Activate/attenuate the correct chains - if testcase_params['channel'] not in self.atten_dut_chain_map.keys(): - self.atten_dut_chain_map[testcase_params[ - 'channel']] = wputils.get_current_atten_dut_chain_map( - self.attenuators, self.dut, self.ping_server) - self.log.info("Current Attenuator-DUT Chain Map: {}".format( - self.atten_dut_chain_map[testcase_params['channel']])) - for idx, atten in enumerate(self.attenuators): - if self.atten_dut_chain_map[testcase_params['channel']][ - idx] == testcase_params['attenuated_chain']: - atten.offset = atten.instrument.max_atten - - def extract_test_id(self, testcase_params, id_fields): - test_id = collections.OrderedDict( - (param, testcase_params[param]) for param in id_fields) - return test_id - - def get_start_atten(self, testcase_params): - """Gets the starting attenuation for this sensitivity test. - - The function gets the starting attenuation by checking whether a test - as the next higher MCS has been executed. If so it sets the starting - point a configurable number of dBs below the next MCS's sensitivity. - - Returns: - start_atten: starting attenuation for current test - """ - # If the test is being retried, start from the beginning - if self.retry_flag: - self.log.info('Retry flag set. Setting attenuation to minimum.') - return self.testclass_params['atten_start'] - # Get the current and reference test config. The reference test is the - # one performed at the current MCS+1 - current_rate = testcase_params['rate'] - ref_test_params = self.extract_test_id( - testcase_params, - ['channel', 'mode', 'rate', 'num_streams', 'chain_mask']) - if 'legacy' in testcase_params['mode']: - if testcase_params['channel'] <= 13: - rate_list = self.VALID_RATES['legacy_2GHz'] - else: - rate_list = self.VALID_RATES['legacy_5GHz'] - ref_index = max( - 0, - rate_list.index(self.RateTuple(current_rate, 1, current_rate)) - - 1) - ref_test_params['rate'] = rate_list[ref_index].mcs - else: - ref_test_params['rate'] = current_rate + 1 - - # Check if reference test has been run and set attenuation accordingly - previous_params = [ - self.extract_test_id( - result['testcase_params'], - ['channel', 'mode', 'rate', 'num_streams', 'chain_mask']) - for result in self.testclass_results - ] - - try: - ref_index = previous_params.index(ref_test_params) - start_atten = self.testclass_results[ref_index][ - 'atten_at_range'] - ( - self.testclass_params['adjacent_mcs_range_gap']) - except ValueError: - self.log.warning( - 'Reference test not found. Starting from {} dB'.format( - self.testclass_params['atten_start'])) - start_atten = self.testclass_params['atten_start'] - start_atten = max(start_atten, 0) - return start_atten - - def compile_test_params(self, testcase_params): - """Function that generates test params based on the test name.""" - band = self.access_point.band_lookup_by_channel( - testcase_params['channel']) - testcase_params['test_network'] = self.main_network[band] - if testcase_params['chain_mask'] in ['0', '1']: - testcase_params['attenuated_chain'] = 'DUT-Chain-{}'.format( - 1 if testcase_params['chain_mask'] == '0' else 0) - else: - # Set attenuated chain to -1. Do not set to None as this will be - # compared to RF chain map which may include None - testcase_params['attenuated_chain'] = -1 - - self.testclass_params[ - 'range_ping_loss_threshold'] = 100 - self.testclass_params[ - 'throughput_pct_at_sensitivity'] - if self.testclass_params['traffic_type'] == 'UDP': - testcase_params['iperf_args'] = '-i 1 -t {} -J -u -b {}'.format( - self.testclass_params['iperf_duration'], - self.testclass_params['UDP_rates'][testcase_params['mode']]) - elif self.testclass_params['traffic_type'] == 'TCP': - testcase_params['iperf_args'] = '-i 1 -t {} -J'.format( - self.testclass_params['iperf_duration']) - - if self.testclass_params['traffic_type'] != 'ping' and isinstance( - self.iperf_client, iperf_client.IPerfClientOverAdb): - testcase_params['iperf_args'] += ' -R' - testcase_params['use_client_output'] = True - else: - testcase_params['use_client_output'] = False - - return testcase_params - - def _test_sensitivity(self, testcase_params): - """ Function that gets called for each test case - - The function gets called in each rvr test case. The function customizes - the rvr test based on the test name of the test that called it - """ - # Compile test parameters from config and test name - testcase_params = self.compile_test_params(testcase_params) - testcase_params.update(self.testclass_params) - testcase_params['atten_start'] = self.get_start_atten(testcase_params) - num_atten_steps = int( - (testcase_params['atten_stop'] - testcase_params['atten_start']) / - testcase_params['atten_step']) - testcase_params['atten_range'] = [ - testcase_params['atten_start'] + x * testcase_params['atten_step'] - for x in range(0, num_atten_steps) - ] - - # Prepare devices and run test - self.setup_sensitivity_test(testcase_params) - result = self.run_sensitivity_test(testcase_params) - self.process_sensitivity_test_results(testcase_params, result) - - # Post-process results - self.testclass_results.append(result) - self.pass_fail_check(result) - - def generate_test_cases(self, channels, modes, chain_mask): - """Function that auto-generates test cases for a test class.""" - test_cases = [] - for channel in channels: - requested_modes = [ - mode for mode in modes - if mode in self.VALID_TEST_CONFIGS[channel] - ] - for mode in requested_modes: - if 'VHT' in mode: - rates = self.VALID_RATES[mode] - elif 'HT' in mode: - rates = self.VALID_RATES[mode] - elif 'legacy' in mode and channel < 14: - rates = self.VALID_RATES['legacy_2GHz'] - elif 'legacy' in mode and channel > 14: - rates = self.VALID_RATES['legacy_5GHz'] - else: - raise ValueError('Invalid test mode.') - for chain, rate in itertools.product(chain_mask, rates): - testcase_params = collections.OrderedDict( - channel=channel, - mode=mode, - rate=rate.mcs, - num_streams=rate.streams, - short_gi=1, - chain_mask=chain) - if chain in ['0', '1'] and rate[1] == 2: - # Do not test 2-stream rates in single chain mode - continue - if 'legacy' in mode: - testcase_name = ('test_sensitivity_ch{}_{}_{}_nss{}' - '_ch{}'.format( - channel, mode, - str(rate.mcs).replace('.', 'p'), - rate.streams, chain)) - else: - testcase_name = ('test_sensitivity_ch{}_{}_mcs{}_nss{}' - '_ch{}'.format( - channel, mode, rate.mcs, - rate.streams, chain)) - setattr(self, testcase_name, - partial(self._test_sensitivity, testcase_params)) - test_cases.append(testcase_name) - return test_cases - - -class WifiSensitivity_AllChannels_Test(WifiSensitivityTest): - def __init__(self, controllers): - super().__init__(controllers) - self.tests = self.generate_test_cases( - [6, 36, 40, 44, 48, 149, 153, 157, 161], - ['VHT20', 'VHT40', 'VHT80'], ['0', '1', '2x2']) - - -class WifiSensitivity_SampleChannels_Test(WifiSensitivityTest): - def __init__(self, controllers): - super().__init__(controllers) - self.tests = self.generate_test_cases([6, 36, 149], - ['VHT20', 'VHT40', 'VHT80'], - ['0', '1', '2x2']) - - -class WifiSensitivity_2GHz_Test(WifiSensitivityTest): - def __init__(self, controllers): - super().__init__(controllers) - self.tests = self.generate_test_cases([1, 2, 6, 10, 11], ['VHT20'], - ['0', '1', '2x2']) - - -class WifiSensitivity_5GHz_Test(WifiSensitivityTest): - def __init__(self, controllers): - super().__init__(controllers) - self.tests = self.generate_test_cases( - [36, 40, 44, 48, 149, 153, 157, 161], ['VHT20', 'VHT40', 'VHT80'], - ['0', '1', '2x2']) - - -class WifiSensitivity_UNII1_Test(WifiSensitivityTest): - def __init__(self, controllers): - super().__init__(controllers) - self.tests = self.generate_test_cases([36, 40, 44, 48], - ['VHT20', 'VHT40', 'VHT80'], - ['0', '1', '2x2']) - - -class WifiSensitivity_UNII3_Test(WifiSensitivityTest): - def __init__(self, controllers): - super().__init__(controllers) - self.tests = self.generate_test_cases([149, 153, 157, 161], - ['VHT20', 'VHT40', 'VHT80'], - ['0', '1', '2x2']) - - -# Over-the air version of senstivity tests -class WifiOtaSensitivityTest(WifiSensitivityTest): - """Class to test over-the-air senstivity. - - This class implements measures WiFi sensitivity tests in an OTA chamber. - It allows setting orientation and other chamber parameters to study - performance in varying channel conditions - """ - def __init__(self, controllers): - base_test.BaseTestClass.__init__(self, controllers) - self.testcase_metric_logger = ( - BlackboxMappedMetricLogger.for_test_case()) - self.testclass_metric_logger = ( - BlackboxMappedMetricLogger.for_test_class()) - self.publish_testcase_metrics = False - - def setup_class(self): - WifiSensitivityTest.setup_class(self) - self.current_chain_mask = '2x2' - self.ota_chamber = ota_chamber.create( - self.user_params['OTAChamber'])[0] - - def teardown_class(self): - WifiSensitivityTest.teardown_class(self) - self.ota_chamber.reset_chamber() - - def setup_sensitivity_test(self, testcase_params): - # Setup turntable - self.ota_chamber.set_orientation(testcase_params['orientation']) - # Continue test setup - WifiSensitivityTest.setup_sensitivity_test(self, testcase_params) - - def setup_dut(self, testcase_params): - """Sets up the DUT in the configuration required by the test. - - Args: - testcase_params: dict containing AP and other test params - """ - # Configure the right INI settings - if testcase_params['chain_mask'] != self.current_chain_mask: - self.log.info('Updating WiFi chain mask to: {}'.format( - testcase_params['chain_mask'])) - self.current_chain_mask = testcase_params['chain_mask'] - if testcase_params['chain_mask'] in ['0', '1']: - wputils.set_ini_single_chain_mode( - self.dut, int(testcase_params['chain_mask'])) - else: - wputils.set_ini_two_chain_mode(self.dut) - # Check battery level before test - if not wputils.health_check(self.dut, 10): - asserts.skip('Battery level too low. Skipping test.') - # Turn screen off to preserve battery - self.dut.go_to_sleep() - if wputils.validate_network(self.dut, - testcase_params['test_network']['SSID']): - self.log.info('Already connected to desired network') - else: - wutils.reset_wifi(self.dut) - wutils.set_wifi_country_code(self.dut, - self.testclass_params['country_code']) - testcase_params['test_network']['channel'] = testcase_params[ - 'channel'] - wutils.wifi_connect(self.dut, - testcase_params['test_network'], - num_of_tries=5, - check_connectivity=False) - self.dut_ip = self.dut.droid.connectivityGetIPv4Addresses('wlan0')[0] - - def process_testclass_results(self): - """Saves and plots test results from all executed test cases.""" - testclass_results_dict = collections.OrderedDict() - id_fields = ['channel', 'mode', 'rate'] - plots = [] - for result in self.testclass_results: - test_id = self.extract_test_id(result['testcase_params'], - id_fields) - test_id = tuple(test_id.items()) - chain_mask = result['testcase_params']['chain_mask'] - num_streams = result['testcase_params']['num_streams'] - line_id = (chain_mask, num_streams) - if test_id not in testclass_results_dict: - testclass_results_dict[test_id] = collections.OrderedDict() - if line_id not in testclass_results_dict[test_id]: - testclass_results_dict[test_id][line_id] = { - 'orientation': [], - 'sensitivity': [] - } - orientation = result['testcase_params']['orientation'] - if result['peak_throughput_pct'] >= 95: - sensitivity = result['sensitivity'] - else: - sensitivity = float('nan') - if orientation not in testclass_results_dict[test_id][line_id][ - 'orientation']: - testclass_results_dict[test_id][line_id]['orientation'].append( - orientation) - testclass_results_dict[test_id][line_id]['sensitivity'].append( - sensitivity) - else: - testclass_results_dict[test_id][line_id]['sensitivity'][ - -1] = sensitivity - - for test_id, test_data in testclass_results_dict.items(): - test_id_dict = dict(test_id) - if 'legacy' in test_id_dict['mode']: - test_id_str = 'Channel {} - {} {}Mbps'.format( - test_id_dict['channel'], test_id_dict['mode'], - test_id_dict['rate']) - else: - test_id_str = 'Channel {} - {} MCS{}'.format( - test_id_dict['channel'], test_id_dict['mode'], - test_id_dict['rate']) - curr_plot = wputils.BokehFigure( - title=str(test_id_str), - x_label='Orientation (deg)', - primary_y_label='Sensitivity (dBm)') - for line_id, line_results in test_data.items(): - curr_plot.add_line(line_results['orientation'], - line_results['sensitivity'], - legend='Nss{} - Chain Mask {}'.format( - line_id[1], line_id[0]), - marker='circle') - if 'legacy' in test_id_dict['mode']: - metric_tag = 'ota_summary_ch{}_{}_{}_ch{}'.format( - test_id_dict['channel'], test_id_dict['mode'], - test_id_dict['rate'], line_id[0]) - else: - metric_tag = 'ota_summary_ch{}_{}_mcs{}_nss{}_ch{}'.format( - test_id_dict['channel'], test_id_dict['mode'], - test_id_dict['rate'], line_id[1], line_id[0]) - - metric_name = metric_tag + '.avg_sensitivity' - metric_value = numpy.nanmean(line_results['sensitivity']) - self.testclass_metric_logger.add_metric( - metric_name, metric_value) - self.log.info(("Average Sensitivity for {}: {:.1f}").format( - metric_tag, metric_value)) - current_context = ( - context.get_current_context().get_full_output_path()) - output_file_path = os.path.join(current_context, - str(test_id_str) + '.html') - curr_plot.generate_figure(output_file_path) - plots.append(curr_plot) - output_file_path = os.path.join(current_context, 'results.html') - wputils.BokehFigure.save_figures(plots, output_file_path) - - def get_start_atten(self, testcase_params): - """Gets the starting attenuation for this sensitivity test. - - The function gets the starting attenuation by checking whether a test - at the same rate configuration has executed. If so it sets the starting - point a configurable number of dBs below the reference test. - - Returns: - start_atten: starting attenuation for current test - """ - # If the test is being retried, start from the beginning - if self.retry_flag: - self.log.info('Retry flag set. Setting attenuation to minimum.') - return self.testclass_params['atten_start'] - # Get the current and reference test config. The reference test is the - # one performed at the current MCS+1 - ref_test_params = self.extract_test_id( - testcase_params, - ['channel', 'mode', 'rate', 'num_streams', 'chain_mask']) - # Check if reference test has been run and set attenuation accordingly - previous_params = [ - self.extract_test_id( - result['testcase_params'], - ['channel', 'mode', 'rate', 'num_streams', 'chain_mask']) - for result in self.testclass_results - ] - try: - ref_index = previous_params[::-1].index(ref_test_params) - ref_index = len(previous_params) - 1 - ref_index - start_atten = self.testclass_results[ref_index][ - 'atten_at_range'] - ( - self.testclass_params['adjacent_mcs_range_gap']) - except ValueError: - print('Reference test not found. Starting from {} dB'.format( - self.testclass_params['atten_start'])) - start_atten = self.testclass_params['atten_start'] - start_atten = max(start_atten, 0) - return start_atten - - def generate_test_cases(self, channels, modes, requested_rates, chain_mask, - angles): - """Function that auto-generates test cases for a test class.""" - test_cases = [] - for channel in channels: - requested_modes = [ - mode for mode in modes - if mode in self.VALID_TEST_CONFIGS[channel] - ] - for chain, mode in itertools.product(chain_mask, requested_modes): - if 'VHT' in mode: - valid_rates = self.VALID_RATES[mode] - elif 'HT' in mode: - valid_rates = self.VALID_RATES[mode] - elif 'legacy' in mode and channel < 14: - valid_rates = self.VALID_RATES['legacy_2GHz'] - elif 'legacy' in mode and channel > 14: - valid_rates = self.VALID_RATES['legacy_5GHz'] - else: - raise ValueError('Invalid test mode.') - for rate, angle in itertools.product(valid_rates, angles): - testcase_params = collections.OrderedDict( - channel=channel, - mode=mode, - rate=rate.mcs, - num_streams=rate.streams, - short_gi=1, - chain_mask=chain, - orientation=angle) - if rate not in requested_rates: - continue - if str(chain) in ['0', '1'] and rate[1] == 2: - # Do not test 2-stream rates in single chain mode - continue - if 'legacy' in mode: - testcase_name = ('test_sensitivity_ch{}_{}_{}_nss{}' - '_ch{}_{}deg'.format( - channel, mode, - str(rate.mcs).replace('.', 'p'), - rate.streams, chain, angle)) - else: - testcase_name = ('test_sensitivity_ch{}_{}_mcs{}_nss{}' - '_ch{}_{}deg'.format( - channel, mode, rate.mcs, - rate.streams, chain, angle)) - setattr(self, testcase_name, - partial(self._test_sensitivity, testcase_params)) - test_cases.append(testcase_name) - return test_cases - - -class WifiOtaSensitivity_TenDegree_Test(WifiOtaSensitivityTest): - def __init__(self, controllers): - WifiOtaSensitivityTest.__init__(self, controllers) - requested_channels = [6, 36, 149] - requested_rates = [ - self.RateTuple(8, 1, 86.7), - self.RateTuple(2, 1, 21.7), - self.RateTuple(8, 2, 173.3), - self.RateTuple(2, 2, 43.3) - ] - self.tests = self.generate_test_cases(requested_channels, - ['VHT20', 'VHT80'], - requested_rates, ['2x2'], - list(range(0, 360, 10))) - - -class WifiOtaSensitivity_PerChain_TenDegree_Test(WifiOtaSensitivityTest): - def __init__(self, controllers): - WifiOtaSensitivityTest.__init__(self, controllers) - requested_channels = [6, 36, 149] - requested_rates = [ - self.RateTuple(2, 1, 21.7), - self.RateTuple(2, 2, 43.3) - ] - self.tests = self.generate_test_cases(requested_channels, ['VHT20'], - requested_rates, - ['0', '1', '2x2'], - list(range(0, 360, 10))) - - -class WifiOtaSensitivity_ThirtyDegree_Test(WifiOtaSensitivityTest): - def __init__(self, controllers): - WifiOtaSensitivityTest.__init__(self, controllers) - requested_channels = [6, 36, 149] - requested_rates = [ - self.RateTuple(9, 1, 96), - self.RateTuple(8, 1, 86.7), - self.RateTuple(7, 1, 72.2), - self.RateTuple(4, 1, 43.3), - self.RateTuple(2, 1, 21.7), - self.RateTuple(0, 1, 7.2), - self.RateTuple(9, 2, 192), - self.RateTuple(8, 2, 173.3), - self.RateTuple(7, 2, 144.4), - self.RateTuple(4, 2, 86.7), - self.RateTuple(2, 2, 43.3), - self.RateTuple(0, 2, 14.4) - ] - self.tests = self.generate_test_cases(requested_channels, - ['VHT20', 'VHT80'], - requested_rates, ['2x2'], - list(range(0, 360, 30))) - - -class WifiOtaSensitivity_45Degree_Test(WifiOtaSensitivityTest): - def __init__(self, controllers): - WifiOtaSensitivityTest.__init__(self, controllers) - requested_rates = [ - self.RateTuple(8, 1, 86.7), - self.RateTuple(2, 1, 21.7), - self.RateTuple(8, 2, 173.3), - self.RateTuple(2, 2, 43.3) - ] - self.tests = self.generate_test_cases( - [1, 6, 11, 36, 40, 44, 48, 149, 153, 157, 161], ['VHT20', 'VHT80'], - requested_rates, ['2x2'], list(range(0, 360, 45))) diff --git a/acts/tests/google/wifi/WifiServiceApiTest.py b/acts/tests/google/wifi/WifiServiceApiTest.py deleted file mode 100644 index b5eed89b90..0000000000 --- a/acts/tests/google/wifi/WifiServiceApiTest.py +++ /dev/null @@ -1,211 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2016 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import logging -import queue -import sys -import time - -from acts import base_test -from acts import signals -from acts import utils -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi import wifi_constants -from acts.test_utils.wifi import wifi_test_utils as wutils - - -class WifiServiceApiTest(base_test.BaseTestClass): - """This class tests the API surface of WifiManager in different wifi states. - - Attributes: - The tests in this class only require one DUT. - The tests in this class do not require a SIM (but it is ok if one is - present). - """ - - - TEST_SSID_PREFIX = "test_config_" - CONFIG_ELEMENT = 'config' - NETWORK_ID_ELEMENT = 'network_id' - - def setup_class(self): - """ Sets up the required dependencies from the config file and - configures the device for WifiService API tests. - - Returns: - True is successfully configured the requirements for testig. - """ - self.dut = self.android_devices[0] - # Do a simple version of init - mainly just sync the time and enable - # verbose logging. We would also like to test with phones in less - # constrained states (or add variations where we specifically - # constrain). - utils.require_sl4a((self.dut, )) - utils.sync_device_time(self.dut) - - # Enable verbose logging on the dut - self.dut.droid.wifiEnableVerboseLogging(1) - if self.dut.droid.wifiGetVerboseLoggingLevel() != 1: - raise signals.TestFailure( - "Failed to enable WiFi verbose logging on the dut.") - - def teardown_class(self): - wutils.reset_wifi(self.dut) - - def on_fail(self, test_name, begin_time): - self.dut.take_bug_report(test_name, begin_time) - - def create_and_save_wifi_network_config(self): - """ Create a config with random SSID and password. - - Returns: - A tuple with the config and networkId for the newly created and saved network. - """ - config_ssid = self.TEST_SSID_PREFIX + utils.rand_ascii_str(8) - config_password = utils.rand_ascii_str(8) - self.dut.log.info("creating config: %s %s", config_ssid, config_password) - config = {wutils.WifiEnums.SSID_KEY: config_ssid} - config[wutils.WifiEnums.PWD_KEY] = config_password - - # Now save the config. - network_id = self.dut.droid.wifiAddNetwork(config) - self.dut.log.info("saved config: network_id = %s", network_id) - return {self.NETWORK_ID_ELEMENT: network_id, self.CONFIG_ELEMENT: config} - - def check_network_config_saved(self, config): - """ Get the configured networks and check of the provided config - is present. This method only checks if the SSID is the same. - TODO: should do a deeper check to make sure this is the - correct config. - - Args: - config: WifiConfig for a network. - - Returns: - True if the WifiConfig is present. - """ - networks = self.dut.droid.wifiGetConfiguredNetworks() - if not networks: - return False - ssid_key = wutils.WifiEnums.SSID_KEY - for network in networks: - if config[ssid_key] == network[ssid_key]: - return True - return False - - def forget_network(self, network_id): - """ Simple method to call wifiForgetNetwork and wait for confirmation - callback. The method returns False if it was not removed. - - Returns: - True if network was successfully deleted. - """ - self.dut.log.info("deleting config: networkId = %s", network_id) - self.dut.droid.wifiForgetNetwork(network_id) - try: - event = self.dut.ed.pop_event(wifi_constants.WIFI_FORGET_NW_SUCCESS, 10) - return True - except queue.Empty: - self.dut.log.error("Failed to forget network") - return False - - - """ Tests Begin """ - @test_tracker_info(uuid="f4df08c2-d3d5-4032-a433-c15f55130d4a") - def test_remove_config_wifi_enabled(self): - """ Test if config can be deleted when wifi is enabled. - - 1. Enable wifi, if needed - 2. Create and save a random config. - 3. Confirm the config is present. - 4. Remove the config. - 5. Confirm the config is not listed. - """ - wutils.wifi_toggle_state(self.dut, True) - test_network = self.create_and_save_wifi_network_config() - if not self.check_network_config_saved(test_network[self.CONFIG_ELEMENT]): - raise signals.TestFailure( - "Test network not found in list of configured networks.") - if not self.forget_network(test_network[self.NETWORK_ID_ELEMENT]): - raise signals.TestFailure( - "Test network not deleted from configured networks.") - if self.check_network_config_saved(test_network[self.CONFIG_ELEMENT]): - raise signals.TestFailure( - "Deleted network was in configured networks list.") - - @test_tracker_info(uuid="9af96c7d-a316-4d57-ba5f-c992427c237b") - def test_remove_config_wifi_disabled(self): - """ Test if config can be deleted when wifi is disabled. - - 1. Enable wifi, if needed - 2. Create and save a random config. - 3. Confirm the config is present. - 4. Disable wifi. - 5. Remove the config. - 6. Confirm the config is not listed. - """ - wutils.wifi_toggle_state(self.dut, True) - test_network = self.create_and_save_wifi_network_config() - if not self.check_network_config_saved(test_network[self.CONFIG_ELEMENT]): - raise signals.TestFailure( - "Test network not found in list of configured networks.") - wutils.wifi_toggle_state(self.dut, False) - if not self.forget_network(test_network[self.NETWORK_ID_ELEMENT]): - raise signals.TestFailure("Failed to delete network.") - if self.check_network_config_saved(test_network[self.CONFIG_ELEMENT]): - raise signals.TestFailure( - "Test network was found in list of configured networks.") - - @test_tracker_info(uuid="79204ae6-323b-4257-a2cb-2225d44199d4") - def test_retrieve_config_wifi_enabled(self): - """ Test if config can be retrieved when wifi is enabled. - - 1. Enable wifi - 2. Create and save a random config - 3. Retrieve the config - 4. Remove the config (clean up from the test) - """ - wutils.wifi_toggle_state(self.dut, True) - test_network = self.create_and_save_wifi_network_config() - - if not self.check_network_config_saved(test_network[self.CONFIG_ELEMENT]): - raise signals.TestFailure( - "Test network not found in list of configured networks.") - if not self.forget_network(test_network[self.NETWORK_ID_ELEMENT]): - raise signals.TestFailure("Failed to delete network.") - - @test_tracker_info(uuid="58fb4f81-bc19-43e1-b0af-89dbd17f45b2") - def test_retrieve_config_wifi_disabled(self): - """ Test if config can be retrieved when wifi is disabled. - - 1. Disable wifi - 2. Create and save a random config - 3. Retrieve the config - 4. Remove the config (clean up from the test) - """ - wutils.wifi_toggle_state(self.dut, False) - test_network = self.create_and_save_wifi_network_config() - if not self.check_network_config_saved(test_network[self.CONFIG_ELEMENT]): - raise signals.TestFailure( - "Test network not found in list of configured networks.") - if not self.forget_network(test_network[self.NETWORK_ID_ELEMENT]): - raise signals.TestFailure("Failed to delete network.") - - """ Tests End """ - - -if __name__ == "__main__": - pass diff --git a/acts/tests/google/wifi/WifiSoftApAcsTest.py b/acts/tests/google/wifi/WifiSoftApAcsTest.py deleted file mode 100644 index edd76368ee..0000000000 --- a/acts/tests/google/wifi/WifiSoftApAcsTest.py +++ /dev/null @@ -1,611 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2018 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import itertools -import pprint -import queue -import sys -import time - -import acts.base_test -import acts.signals as signals -import acts.test_utils.wifi.wifi_test_utils as wutils -import acts.utils as utils - -from acts import asserts -from acts.controllers.ap_lib import hostapd_constants -from acts.test_decorators import test_tracker_info -from acts.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_2G -from acts.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_5G -from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest -from threading import Thread - -WifiEnums = wutils.WifiEnums -WIFI_CONFIG_APBAND_AUTO = -1 - -class WifiSoftApAcsTest(WifiBaseTest): - """Tests for Automatic Channel Selection. - - Test Bed Requirement: - * Two Android devices and an AP. - * 2GHz and 5GHz Wi-Fi network visible to the device. - """ - - def setup_class(self): - super().setup_class() - - self.dut = self.android_devices[0] - self.dut_client = self.android_devices[1] - wutils.wifi_test_device_init(self.dut) - wutils.wifi_test_device_init(self.dut_client) - utils.require_sl4a((self.dut, self.dut_client)) - utils.sync_device_time(self.dut) - utils.sync_device_time(self.dut_client) - # Set country code explicitly to "US". - wutils.set_wifi_country_code(self.dut, wutils.WifiEnums.CountryCode.US) - wutils.set_wifi_country_code(self.dut_client, wutils.WifiEnums.CountryCode.US) - # Enable verbose logging on the duts - self.dut.droid.wifiEnableVerboseLogging(1) - asserts.assert_equal(self.dut.droid.wifiGetVerboseLoggingLevel(), 1, - "Failed to enable WiFi verbose logging on the softap dut.") - self.dut_client.droid.wifiEnableVerboseLogging(1) - asserts.assert_equal(self.dut_client.droid.wifiGetVerboseLoggingLevel(), 1, - "Failed to enable WiFi verbose logging on the client dut.") - req_params = [] - opt_param = ["iperf_server_address", "reference_networks", - "iperf_server_port"] - self.unpack_userparams( - req_param_names=req_params, opt_param_names=opt_param) - self.chan_map = {v: k for k, v in hostapd_constants.CHANNEL_MAP.items()} - self.pcap_procs = None - - def setup_test(self): - if hasattr(self, 'packet_capture'): - chan = self.test_name.split('_')[-1] - if chan.isnumeric(): - band = '2G' if self.chan_map[int(chan)] < 5000 else '5G' - self.packet_capture[0].configure_monitor_mode(band, int(chan)) - self.pcap_procs = wutils.start_pcap( - self.packet_capture[0], band, self.test_name) - wutils.start_cnss_diags(self.android_devices) - self.dut.droid.wakeLockAcquireBright() - self.dut.droid.wakeUpNow() - - def teardown_test(self): - self.dut.droid.wakeLockRelease() - self.dut.droid.goToSleepNow() - wutils.stop_wifi_tethering(self.dut) - wutils.reset_wifi(self.dut) - wutils.reset_wifi(self.dut_client) - wutils.stop_cnss_diags(self.android_devices) - if hasattr(self, 'packet_capture') and self.pcap_procs: - wutils.stop_pcap(self.packet_capture[0], self.pcap_procs, False) - self.pcap_procs = None - try: - if "AccessPoint" in self.user_params: - del self.user_params["reference_networks"] - del self.user_params["open_network"] - except: - pass - self.access_points[0].close() - - def on_fail(self, test_name, begin_time): - self.dut.take_bug_report(test_name, begin_time) - self.dut.cat_adb_log(test_name, begin_time) - for ad in self.android_devices: - wutils.get_cnss_diag_log(ad, test_name) - - """Helper Functions""" - - def run_iperf_client(self, params): - """Run iperf traffic after connection. - - Args: - params: A tuple of network info and AndroidDevice object. - - """ - if "iperf_server_address" in self.user_params: - network, ad = params - SSID = network[WifiEnums.SSID_KEY] - self.log.info("Starting iperf traffic through {}".format(SSID)) - port_arg = "-p {} -t {}".format(self.iperf_server_port, 3) - success, data = ad.run_iperf_client(self.iperf_server_address, - port_arg) - self.log.debug(pprint.pformat(data)) - asserts.assert_true(success, "Error occurred in iPerf traffic.") - self.log.info("Finished iperf traffic through {}".format(SSID)) - - def start_softap_and_verify(self, band): - """Bring-up softap and verify AP mode and in scan results. - - Args: - band: The band to use for softAP. - - """ - config = wutils.create_softap_config() - wutils.start_wifi_tethering(self.dut, - config[wutils.WifiEnums.SSID_KEY], - config[wutils.WifiEnums.PWD_KEY], band=band) - asserts.assert_true(self.dut.droid.wifiIsApEnabled(), - "SoftAp is not reported as running") - wutils.start_wifi_connection_scan_and_ensure_network_found( - self.dut_client, config[wutils.WifiEnums.SSID_KEY]) - return config - - def get_softap_acs(self, softap): - """Connect to the softap on client-dut and get the softap channel - information. - - Args: - softap: The softap network configuration information. - - """ - wutils.connect_to_wifi_network(self.dut_client, softap, - check_connectivity=False) - softap_info = self.dut_client.droid.wifiGetConnectionInfo() - self.log.debug("DUT is connected to softAP %s with details: %s" % - (softap[wutils.WifiEnums.SSID_KEY], softap_info)) - frequency = softap_info['frequency'] - return hostapd_constants.CHANNEL_MAP[frequency] - - def configure_ap(self, channel_2g=None, channel_5g=None): - """Configure and bring up AP on required channel. - - Args: - channel_2g: The channel number to use for 2GHz network. - channel_5g: The channel number to use for 5GHz network. - - """ - if "AccessPoint" in self.user_params: - if not channel_2g: - channel_2g = hostapd_constants.AP_DEFAULT_CHANNEL_2G - if not channel_5g: - channel_5g = hostapd_constants.AP_DEFAULT_CHANNEL_5G - self.legacy_configure_ap_and_start(wpa_network=True, - wep_network=True, - channel_2g=channel_2g, - channel_5g=channel_5g) - - def start_traffic_and_softap(self, network, softap_band): - """Start iPerf traffic on client dut, during softAP bring-up on dut. - - Args: - network: Network information of the network to connect to. - softap_band: The band to use for softAP. - - """ - if not network: - # For a clean environment just bring up softap and return channel. - softap = self.start_softap_and_verify(softap_band) - channel = self.get_softap_acs(softap) - return channel - # Connect to the AP and start IPerf traffic, while we bring up softap. - wutils.connect_to_wifi_network(self.dut_client, network) - t = Thread(target=self.run_iperf_client,args=((network,self.dut_client),)) - t.setDaemon(True) - t.start() - time.sleep(1) - softap = self.start_softap_and_verify(softap_band) - t.join() - channel = self.get_softap_acs(softap) - return channel - - def verify_acs_channel(self, chan, avoid_chan): - """Verify ACS algorithm by ensuring that softAP came up on a channel, - different than the active channels. - - Args: - chan: The channel number softap came-up on. - avoid_chan: The channel to avoid during this test. - - """ - if avoid_chan in range(1,12): - avoid_chan2 = hostapd_constants.AP_DEFAULT_CHANNEL_5G - elif avoid_chan in range(36, 166): - avoid_chan2 = hostapd_constants.AP_DEFAULT_CHANNEL_2G - if chan == avoid_chan or chan == avoid_chan2: - raise signals.TestFailure("ACS chose the same channel that the " - "AP was beaconing on. Channel = %d" % chan) - - """Tests""" - @test_tracker_info(uuid="3507bd18-e787-4380-8725-1872916d4267") - def test_softap_2G_clean_env(self): - """Test to bring up SoftAp on 2GHz in clean environment.""" - network = None - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_2G) - if not chan in range(1, 12): - raise signals.TestFailure("ACS chose incorrect channel %d for 2GHz " - "band" % chan) - - @test_tracker_info(uuid="3d18da8b-d29a-45f9-8018-5348e10099e9") - def test_softap_5G_clean_env(self): - """Test to bring up SoftAp on 5GHz in clean environment.""" - network = None - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_5G) - if not chan in range(36, 166): - # Note: This does not treat DFS channel separately. - raise signals.TestFailure("ACS chose incorrect channel %d for 5GHz " - "band" % chan) - - @test_tracker_info(uuid="cc353bda-3831-4d6e-b990-e501b8e4eafe") - def test_softap_auto_clean_env(self): - """Test to bring up SoftAp on AUTO-band in clean environment.""" - network = None - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_AUTO) - if not chan in range(36, 166): - # Note: This does not treat DFS channel separately. - raise signals.TestFailure("ACS chose incorrect channel %d for 5GHz " - "band" % chan) - - @test_tracker_info(uuid="a5f6a926-76d2-46a7-8136-426e35b5a5a8") - def test_softap_2G_avoid_channel_1(self): - """Test to configure AP and bring up SoftAp on 2G.""" - self.configure_ap(channel_2g=1) - network = self.reference_networks[0]["2g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_2G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="757e2019-b027-40bf-a562-2b01f3e5957e") - def test_softap_5G_avoid_channel_1(self): - """Test to configure AP and bring up SoftAp on 5G.""" - self.configure_ap(channel_2g=1) - network = self.reference_networks[0]["2g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_5G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="b96e39d1-9041-4662-a55f-22641c2e2b02") - def test_softap_2G_avoid_channel_2(self): - """Test to configure AP and bring up SoftAp on 2G.""" - self.configure_ap(channel_2g=2) - network = self.reference_networks[0]["2g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_2G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="941c4e2b-ae35-4b49-aa81-13d3dc44b5b6") - def test_softap_5G_avoid_channel_2(self): - """Test to configure AP and bring up SoftAp on 5G.""" - self.configure_ap(channel_2g=2) - network = self.reference_networks[0]["2g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_5G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="444c4a34-7f6b-4f02-9802-2e896e7d1796") - def test_softap_2G_avoid_channel_3(self): - """Test to configure AP and bring up SoftAp on 2G.""" - self.configure_ap(channel_2g=3) - network = self.reference_networks[0]["2g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_2G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="eccd06b1-6df5-4144-8fda-1504cb822375") - def test_softap_5G_avoid_channel_3(self): - """Test to configure AP and bring up SoftAp on 5G.""" - self.configure_ap(channel_2g=3) - network = self.reference_networks[0]["2g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_5G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="fb257644-2081-4c3d-8394-7a308dde0047") - def test_softap_2G_avoid_channel_4(self): - """Test to configure AP and bring up SoftAp on 2G.""" - self.configure_ap(channel_2g=4) - network = self.reference_networks[0]["2g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_2G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="88b9cd16-4541-408a-8607-415fe60001f2") - def test_softap_5G_avoid_channel_4(self): - """Test to configure AP and bring up SoftAp on 5G.""" - self.configure_ap(channel_2g=4) - network = self.reference_networks[0]["2g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_5G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="b3626ec8-50e8-412c-bdbe-5c5ade647d7b") - def test_softap_2G_avoid_channel_5(self): - """Test to configure AP and bring up SoftAp on 2G.""" - self.configure_ap(channel_2g=5) - network = self.reference_networks[0]["2g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_2G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="45c4396b-9b0c-44f3-adf2-ea9c86fcab1d") - def test_softap_5G_avoid_channel_5(self): - """Test to configure AP and bring up SoftAp on 5G.""" - self.configure_ap(channel_2g=5) - network = self.reference_networks[0]["2g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_5G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="f70634e7-c6fd-403d-8cd7-439fbbda6af0") - def test_softap_2G_avoid_channel_6(self): - """Test to configure AP and bring up SoftAp on 2G.""" - self.configure_ap(channel_2g=6) - network = self.reference_networks[0]["2g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_2G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="f3341136-10bc-44e2-b9a8-2d27d3284b73") - def test_softap_5G_avoid_channel_6(self): - """Test to configure AP and bring up SoftAp on 5G.""" - self.configure_ap(channel_2g=6) - network = self.reference_networks[0]["2g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_5G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="8129594d-1608-448b-8548-5a8c4022f2a1") - def test_softap_2G_avoid_channel_7(self): - """Test to configure AP and bring up SoftAp on 2G.""" - self.configure_ap(channel_2g=7) - network = self.reference_networks[0]["2g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_2G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="7b470b82-d19b-438c-8f98-ce697e0eb474") - def test_softap_5G_avoid_channel_7(self): - """Test to configure AP and bring up SoftAp on 5G.""" - self.configure_ap(channel_2g=7) - network = self.reference_networks[0]["2g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_5G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="11540182-d471-4bf0-8f8b-add89443c329") - def test_softap_2G_avoid_channel_8(self): - """Test to configure AP and bring up SoftAp on 2G.""" - self.configure_ap(channel_2g=8) - network = self.reference_networks[0]["2g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_2G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="1280067c-389e-42e9-aa75-6bfbd61340f3") - def test_softap_5G_avoid_channel_8(self): - """Test to configure AP and bring up SoftAp on 5G.""" - self.configure_ap(channel_2g=8) - network = self.reference_networks[0]["2g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_5G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="6feeb83c-2723-49cb-93c1-6297d4a3d853") - def test_softap_2G_avoid_channel_9(self): - """Test to configure AP and bring up SoftAp on 2G.""" - self.configure_ap(channel_2g=9) - network = self.reference_networks[0]["2g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_2G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="49a110cd-03e8-4e99-9327-5123eab40902") - def test_softap_5G_avoid_channel_9(self): - """Test to configure AP and bring up SoftAp on 5G.""" - self.configure_ap(channel_2g=9) - network = self.reference_networks[0]["2g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_5G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="a03c9e45-8763-4b5c-bead-e574fb9899a2") - def test_softap_2G_avoid_channel_10(self): - """Test to configure AP and bring up SoftAp on 2G.""" - self.configure_ap(channel_2g=10) - network = self.reference_networks[0]["2g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_2G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="c1a1d272-a646-4c2d-8425-09d2ae6ae8e6") - def test_softap_5G_avoid_channel_10(self): - """Test to configure AP and bring up SoftAp on 5G.""" - self.configure_ap(channel_2g=10) - network = self.reference_networks[0]["2g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_5G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="f38d8911-92d4-4dcd-ba23-1e1667fa1f5a") - def test_softap_2G_avoid_channel_11(self): - """Test to configure AP and bring up SoftAp on 2G.""" - self.configure_ap(channel_2g=11) - network = self.reference_networks[0]["2g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_2G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="24cc35ba-45e3-4b7a-9bc9-25b7abe92fa9") - def test_softap_5G_avoid_channel_11(self): - """Test to configure AP and bring up SoftAp on 5G.""" - self.configure_ap(channel_2g=11) - network = self.reference_networks[0]["2g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_5G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="85aef720-4f3c-43bb-9de0-615b88c2bfe0") - def test_softap_2G_avoid_channel_36(self): - """Test to configure AP and bring up SoftAp on 2G.""" - self.configure_ap(channel_5g=36) - network = self.reference_networks[0]["5g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_2G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="433e8db3-93b5-463e-a83c-0d4b9b9a8700") - def test_softap_5G_avoid_channel_36(self): - """Test to configure AP and bring up SoftAp on 5G.""" - self.configure_ap(channel_5g=36) - network = self.reference_networks[0]["5g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_5G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="326e0e42-3219-4e63-a18d-5dc32c58e7d8") - def test_softap_2G_avoid_channel_40(self): - """Test to configure AP and bring up SoftAp on 2G.""" - self.configure_ap(channel_5g=40) - network = self.reference_networks[0]["5g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_2G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="45953c03-c978-4775-a39b-fb7e70c8990a") - def test_softap_5G_avoid_channel_40(self): - """Test to configure AP and bring up SoftAp on 5G.""" - self.configure_ap(channel_5g=40) - network = self.reference_networks[0]["5g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_5G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="e8e89cec-aa27-4780-8ff8-546d5af820f7") - def test_softap_2G_avoid_channel_44(self): - """Test to configure AP and bring up SoftAp on 2G.""" - self.configure_ap(channel_5g=44) - network = self.reference_networks[0]["5g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_2G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="5e386d7d-d4c9-40cf-9333-06da55e11ba1") - def test_softap_5G_avoid_channel_44(self): - """Test to configure AP and bring up SoftAp on 5G.""" - self.configure_ap(channel_5g=44) - network = self.reference_networks[0]["5g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_5G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="cb51dfca-f8de-4dfc-b513-e590c838c766") - def test_softap_2G_avoid_channel_48(self): - """Test to configure AP and bring up SoftAp on 2G.""" - self.configure_ap(channel_5g=48) - network = self.reference_networks[0]["5g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_2G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="490b8ed1-196c-4941-b06b-5f0721ca440b") - def test_softap_5G_avoid_channel_48(self): - """Test to configure AP and bring up SoftAp on 5G.""" - self.configure_ap(channel_5g=48) - network = self.reference_networks[0]["5g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_5G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="c5ab141b-e145-4cc1-b0d7-dd610cbfb462") - def test_softap_2G_avoid_channel_149(self): - """Test to configure AP and bring up SoftAp on 2G.""" - self.configure_ap(channel_5g=149) - network = self.reference_networks[0]["5g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_2G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="108d7ef8-6fe7-49ba-b684-3820e881fcf0") - def test_softap_5G_avoid_channel_149(self): - """Test to configure AP and bring up SoftAp on 5G.""" - self.configure_ap(channel_5g=149) - network = self.reference_networks[0]["5g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_5G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="f6926f40-0afc-41c5-9b38-c95a99788ff5") - def test_softap_2G_avoid_channel_153(self): - """Test to configure AP and bring up SoftAp on 2G.""" - self.configure_ap(channel_5g=153) - network = self.reference_networks[0]["5g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_2G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="3d7b653b-c094-4c57-8e6a-047629b05216") - def test_softap_5G_avoid_channel_153(self): - """Test to configure AP and bring up SoftAp on 5G.""" - self.configure_ap(channel_5g=153) - network = self.reference_networks[0]["5g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_5G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="b866ceea-d3ca-45d4-964a-4edea96026e6") - def test_softap_2G_avoid_channel_157(self): - """Test to configure AP and bring up SoftAp on 2G.""" - self.configure_ap(channel_5g=157) - network = self.reference_networks[0]["5g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_2G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="03cb9163-bca3-442e-9691-6df82f8c51c7") - def test_softap_5G_avoid_channel_157(self): - """Test to configure AP and bring up SoftAp on 5G.""" - self.configure_ap(channel_5g=157) - network = self.reference_networks[0]["5g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_5G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="ae10f23a-da70-43c8-9991-2c2f4a602724") - def test_softap_2G_avoid_channel_161(self): - """Test to configure AP and bring up SoftAp on 2G.""" - self.configure_ap(channel_5g=161) - network = self.reference_networks[0]["5g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_2G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="521686c2-acfa-42d1-861b-aa10ac4dad34") - def test_softap_5G_avoid_channel_161(self): - """Test to configure AP and bring up SoftAp on 5G.""" - self.configure_ap(channel_5g=161) - network = self.reference_networks[0]["5g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_5G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="77ebecd7-c036-463f-b77d-2cd70d89bc81") - def test_softap_2G_avoid_channel_165(self): - """Test to configure AP and bring up SoftAp on 2G.""" - self.configure_ap(channel_5g=165) - network = self.reference_networks[0]["5g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_2G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) - - @test_tracker_info(uuid="85d9386d-fe60-4708-9f91-75bbf8bec54f") - def test_softap_5G_avoid_channel_165(self): - """Test to configure AP and bring up SoftAp on 5G.""" - self.configure_ap(channel_5g=165) - network = self.reference_networks[0]["5g"] - chan = self.start_traffic_and_softap(network, WIFI_CONFIG_APBAND_5G) - avoid_chan = int(sys._getframe().f_code.co_name.split('_')[-1]) - self.verify_acs_channel(chan, avoid_chan) diff --git a/acts/tests/google/wifi/WifiSoftApPerformanceTest.py b/acts/tests/google/wifi/WifiSoftApPerformanceTest.py deleted file mode 100644 index 489ab61b66..0000000000 --- a/acts/tests/google/wifi/WifiSoftApPerformanceTest.py +++ /dev/null @@ -1,237 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2018 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the 'License'); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an 'AS IS' BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import collections -import logging -import os -from acts import asserts -from acts import base_test -from acts.controllers import iperf_server as ipf -from acts.controllers import iperf_client as ipc -from acts.metrics.loggers.blackbox import BlackboxMappedMetricLogger -from acts.test_utils.wifi import ota_sniffer -from acts.test_utils.wifi import wifi_test_utils as wutils -from acts.test_utils.wifi import wifi_performance_test_utils as wputils -from WifiRvrTest import WifiRvrTest - -AccessPointTuple = collections.namedtuple(('AccessPointTuple'), - ['ap_settings']) - - -class WifiSoftApRvrTest(WifiRvrTest): - def __init__(self, controllers): - base_test.BaseTestClass.__init__(self, controllers) - self.tests = ('test_rvr_TCP_DL_2GHz', 'test_rvr_TCP_UL_2GHz', - 'test_rvr_TCP_DL_5GHz', 'test_rvr_TCP_UL_5GHz') - self.testcase_metric_logger = ( - BlackboxMappedMetricLogger.for_test_case()) - self.testclass_metric_logger = ( - BlackboxMappedMetricLogger.for_test_class()) - self.publish_testcase_metrics = True - - def setup_class(self): - """Initializes common test hardware and parameters. - - This function initializes hardwares and compiles parameters that are - common to all tests in this class. - """ - self.dut = self.android_devices[-1] - req_params = ['sap_test_params', 'testbed_params'] - opt_params = ['golden_files_list', 'OTASniffer'] - self.unpack_userparams(req_params, opt_params) - self.testclass_params = self.sap_test_params - self.num_atten = self.attenuators[0].instrument.num_atten - self.iperf_server = ipf.create([{ - 'AndroidDevice': - self.android_devices[0].serial, - 'port': - '5201' - }])[0] - self.iperf_client = ipc.create([{ - 'AndroidDevice': - self.android_devices[1].serial, - 'port': - '5201' - }])[0] - if hasattr(self, - 'OTASniffer') and self.testbed_params['sniffer_enable']: - self.sniffer = ota_sniffer.create(self.OTASniffer)[0] - - self.log_path = os.path.join(logging.log_path, 'results') - os.makedirs(self.log_path, exist_ok=True) - if not hasattr(self, 'golden_files_list'): - if 'golden_results_path' in self.testbed_params: - self.golden_files_list = [ - os.path.join(self.testbed_params['golden_results_path'], - file) for file in - os.listdir(self.testbed_params['golden_results_path']) - ] - else: - self.log.warning('No golden files found.') - self.golden_files_list = [] - self.testclass_results = [] - - # Turn WiFi ON - for dev in self.android_devices: - wutils.wifi_toggle_state(dev, True) - - def teardown_class(self): - # Turn WiFi OFF - wutils.stop_wifi_tethering(self.android_devices[0]) - for dev in self.android_devices: - wutils.wifi_toggle_state(dev, False) - self.process_testclass_results() - - def teardown_test(self): - self.iperf_server.stop() - wutils.stop_wifi_tethering(self.android_devices[0]) - - def get_sap_connection_info(self): - info = {} - info['client_ip_address'] = self.android_devices[ - 1].droid.connectivityGetIPv4Addresses('wlan0')[0] - info['ap_ip_address'] = self.android_devices[ - 0].droid.connectivityGetIPv4Addresses('wlan1')[0] - info['frequency'] = self.android_devices[1].adb.shell( - 'wpa_cli status | grep freq').split('=')[1] - info['channel'] = wutils.WifiEnums.freq_to_channel[int( - info['frequency'])] - return info - - def setup_sap_rvr_test(self, testcase_params): - """Function that gets devices ready for the test. - - Args: - testcase_params: dict containing test-specific parameters - """ - for dev in self.android_devices: - if not wputils.health_check(dev, 20): - asserts.skip('DUT health check failed. Skipping test.') - # Reset WiFi on all devices - for dev in self.android_devices: - self.dut.go_to_sleep() - wutils.reset_wifi(dev) - wutils.set_wifi_country_code(dev, wutils.WifiEnums.CountryCode.US) - - # Setup Soft AP - sap_config = wutils.create_softap_config() - self.log.info('SoftAP Config: {}'.format(sap_config)) - wutils.start_wifi_tethering(self.android_devices[0], - sap_config[wutils.WifiEnums.SSID_KEY], - sap_config[wutils.WifiEnums.PWD_KEY], - testcase_params['sap_band_enum']) - # Set attenuator to 0 dB - for attenuator in self.attenuators: - attenuator.set_atten(0, strict=False) - # Connect DUT to Network - testcase_params['test_network'] = { - 'SSID': sap_config[wutils.WifiEnums.SSID_KEY], - 'password': sap_config[wutils.WifiEnums.PWD_KEY] - } - wutils.wifi_connect(self.android_devices[1], - testcase_params['test_network'], - num_of_tries=5, - check_connectivity=False) - # Compile meta data - self.access_point = AccessPointTuple(sap_config) - testcase_params['connection_info'] = self.get_sap_connection_info() - testcase_params['channel'] = testcase_params['connection_info'][ - 'channel'] - testcase_params['test_network']['channel'] = testcase_params[ - 'connection_info']['channel'] - if testcase_params['channel'] < 13: - testcase_params['mode'] = 'VHT20' - else: - testcase_params['mode'] = 'VHT80' - testcase_params['iperf_server_address'] = testcase_params[ - 'connection_info']['ap_ip_address'] - - def compile_test_params(self, testcase_params): - """Function that completes all test params based on the test name. - - Args: - testcase_params: dict containing test-specific parameters - """ - num_atten_steps = int((self.testclass_params['atten_stop'] - - self.testclass_params['atten_start']) / - self.testclass_params['atten_step']) - testcase_params['atten_range'] = [ - self.testclass_params['atten_start'] + - x * self.testclass_params['atten_step'] - for x in range(0, num_atten_steps) - ] - - if testcase_params['traffic_direction'] == 'DL': - testcase_params['iperf_args'] = wputils.get_iperf_arg_string( - duration=self.testclass_params['iperf_duration'], - reverse_direction=1, - traffic_type=testcase_params['traffic_type']) - testcase_params['use_client_output'] = True - else: - testcase_params['iperf_args'] = wputils.get_iperf_arg_string( - duration=self.testclass_params['iperf_duration'], - reverse_direction=0, - traffic_type=testcase_params['traffic_type']) - testcase_params['use_client_output'] = False - return testcase_params - - def _test_sap_rvr(self, testcase_params): - """ Function that gets called for each test case - - Args: - testcase_params: dict containing test-specific parameters - """ - # Compile test parameters from config and test name - testcase_params = self.compile_test_params(testcase_params) - - self.setup_sap_rvr_test(testcase_params) - result = self.run_rvr_test(testcase_params) - self.testclass_results.append(result) - self.process_test_results(result) - self.pass_fail_check(result) - - #Test cases - def test_rvr_TCP_DL_2GHz(self): - testcase_params = collections.OrderedDict( - sap_band='2GHz', - sap_band_enum=wutils.WifiEnums.WIFI_CONFIG_APBAND_2G, - traffic_type='TCP', - traffic_direction='DL') - self._test_sap_rvr(testcase_params) - - def test_rvr_TCP_UL_2GHz(self): - testcase_params = collections.OrderedDict( - sap_band='2GHz', - sap_band_enum=wutils.WifiEnums.WIFI_CONFIG_APBAND_2G, - traffic_type='TCP', - traffic_direction='UL') - self._test_sap_rvr(testcase_params) - - def test_rvr_TCP_DL_5GHz(self): - testcase_params = collections.OrderedDict( - sap_band='5GHz', - sap_band_enum=wutils.WifiEnums.WIFI_CONFIG_APBAND_5G, - traffic_type='TCP', - traffic_direction='DL') - self._test_sap_rvr(testcase_params) - - def test_rvr_TCP_UL_5GHz(self): - testcase_params = collections.OrderedDict( - sap_band='5GHz', - sap_band_enum=wutils.WifiEnums.WIFI_CONFIG_APBAND_5G, - traffic_type='TCP', - traffic_direction='UL') - self._test_sap_rvr(testcase_params) diff --git a/acts/tests/google/wifi/WifiSoftApTest.py b/acts/tests/google/wifi/WifiSoftApTest.py deleted file mode 100644 index de14eb3938..0000000000 --- a/acts/tests/google/wifi/WifiSoftApTest.py +++ /dev/null @@ -1,627 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2016 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import logging -import queue -import random -import time - -from acts import asserts -from acts import utils -from acts.test_decorators import test_tracker_info -from acts.test_utils.net import arduino_test_utils as dutils -from acts.test_utils.net import socket_test_utils as sutils -from acts.test_utils.tel import tel_defines -from acts.test_utils.tel import tel_test_utils as tel_utils -from acts.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_2G -from acts.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_5G -from acts.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_AUTO -from acts.test_utils.wifi import wifi_constants -from acts.test_utils.wifi import wifi_test_utils as wutils -from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest - -class WifiSoftApTest(WifiBaseTest): - - def setup_class(self): - """It will setup the required dependencies from config file and configure - the devices for softap mode testing. - - Returns: - True if successfully configured the requirements for testing. - """ - self.dut = self.android_devices[0] - self.dut_client = self.android_devices[1] - req_params = ["dbs_supported_models"] - opt_param = ["open_network"] - self.unpack_userparams( - req_param_names=req_params, opt_param_names=opt_param) - if "AccessPoint" in self.user_params: - self.legacy_configure_ap_and_start() - self.open_network = self.open_network[0]["2g"] - # Do a simple version of init - mainly just sync the time and enable - # verbose logging. This test will fail if the DUT has a sim and cell - # data is disabled. We would also like to test with phones in less - # constrained states (or add variations where we specifically - # constrain). - utils.require_sl4a((self.dut, self.dut_client)) - utils.sync_device_time(self.dut) - utils.sync_device_time(self.dut_client) - # Set country code explicitly to "US". - wutils.set_wifi_country_code(self.dut, wutils.WifiEnums.CountryCode.US) - wutils.set_wifi_country_code(self.dut_client, wutils.WifiEnums.CountryCode.US) - # Enable verbose logging on the duts - self.dut.droid.wifiEnableVerboseLogging(1) - asserts.assert_equal(self.dut.droid.wifiGetVerboseLoggingLevel(), 1, - "Failed to enable WiFi verbose logging on the softap dut.") - self.dut_client.droid.wifiEnableVerboseLogging(1) - asserts.assert_equal(self.dut_client.droid.wifiGetVerboseLoggingLevel(), 1, - "Failed to enable WiFi verbose logging on the client dut.") - wutils.wifi_toggle_state(self.dut, True) - wutils.wifi_toggle_state(self.dut_client, True) - self.AP_IFACE = 'wlan0' - if self.dut.model in self.dbs_supported_models: - self.AP_IFACE = 'wlan1' - if len(self.android_devices) > 2: - utils.sync_device_time(self.android_devices[2]) - wutils.set_wifi_country_code(self.android_devices[2], wutils.WifiEnums.CountryCode.US) - self.android_devices[2].droid.wifiEnableVerboseLogging(1) - asserts.assert_equal(self.android_devices[2].droid.wifiGetVerboseLoggingLevel(), 1, - "Failed to enable WiFi verbose logging on the client dut.") - - def teardown_class(self): - wutils.stop_wifi_tethering(self.dut) - wutils.reset_wifi(self.dut) - wutils.reset_wifi(self.dut_client) - if "AccessPoint" in self.user_params: - del self.user_params["reference_networks"] - del self.user_params["open_network"] - - def setup_test(self): - for ad in self.android_devices: - wutils.wifi_toggle_state(ad, True) - - def teardown_test(self): - self.dut.log.debug("Toggling Airplane mode OFF.") - asserts.assert_true(utils.force_airplane_mode(self.dut, False), - "Can not turn off airplane mode: %s" % self.dut.serial) - if self.dut.droid.wifiIsApEnabled(): - wutils.stop_wifi_tethering(self.dut) - - def on_fail(self, test_name, begin_time): - self.dut.take_bug_report(test_name, begin_time) - self.dut_client.take_bug_report(test_name, begin_time) - - """ Helper Functions """ - def create_softap_config(self): - """Create a softap config with ssid and password.""" - ap_ssid = "softap_" + utils.rand_ascii_str(8) - ap_password = utils.rand_ascii_str(8) - self.dut.log.info("softap setup: %s %s", ap_ssid, ap_password) - config = {wutils.WifiEnums.SSID_KEY: ap_ssid} - config[wutils.WifiEnums.PWD_KEY] = ap_password - return config - - def confirm_softap_in_scan_results(self, ap_ssid): - """Confirm the ap started by wifi tethering is seen in scan results. - - Args: - ap_ssid: SSID of the ap we are looking for. - """ - wutils.start_wifi_connection_scan_and_ensure_network_found( - self.dut_client, ap_ssid); - - def confirm_softap_not_in_scan_results(self, ap_ssid): - """Confirm the ap started by wifi tethering is not seen in scan results. - - Args: - ap_ssid: SSID of the ap we are looking for. - """ - wutils.start_wifi_connection_scan_and_ensure_network_not_found( - self.dut_client, ap_ssid); - - def validate_traffic_between_softap_clients(self, config): - """Send traffic between softAp clients. - - Connect SoftAp clients to the wifi hotspot; one android - device and the other arduino wifi controller. Send UDP traffic - between the clients and verify that expected messages are received. - - Args: - config: wifi network config with SSID, password - """ - ad = self.dut_client - wd = self.arduino_wifi_dongles[0] - wutils.wifi_connect(ad, config, check_connectivity=False) - dutils.connect_wifi(wd, config) - local_ip = ad.droid.connectivityGetIPv4Addresses('wlan0')[0] - remote_ip = wd.ip_address() - port = random.randint(8000, 9000) - self.log.info("IP addr on android device: %s" % local_ip) - self.log.info("IP addr on arduino device: %s" % remote_ip) - - socket = sutils.open_datagram_socket(ad, local_ip, port) - sutils.send_recv_data_datagram_sockets( - ad, ad, socket, socket, remote_ip, port) - sutils.close_datagram_socket(ad, socket) - - def check_cell_data_and_enable(self): - """Make sure that cell data is enabled if there is a sim present. - - If a sim is active, cell data needs to be enabled to allow provisioning - checks through (when applicable). This is done to relax hardware - requirements on DUTs - without this check, running this set of tests - after other wifi tests may cause failures. - """ - # We do have a sim. Make sure data is enabled so we can tether. - if not self.dut.droid.telephonyIsDataEnabled(): - self.dut.log.info("need to enable data") - self.dut.droid.telephonyToggleDataConnection(True) - asserts.assert_true(self.dut.droid.telephonyIsDataEnabled(), - "Failed to enable cell data for softap dut.") - - def validate_full_tether_startup(self, band=None, hidden=None, - test_ping=False, test_clients=None): - """Test full startup of wifi tethering - - 1. Report current state. - 2. Switch to AP mode. - 3. verify SoftAP active. - 4. Shutdown wifi tethering. - 5. verify back to previous mode. - """ - initial_wifi_state = self.dut.droid.wifiCheckState() - initial_cell_state = tel_utils.is_sim_ready(self.log, self.dut) - self.dut.log.info("current state: %s", initial_wifi_state) - self.dut.log.info("is sim ready? %s", initial_cell_state) - if initial_cell_state: - self.check_cell_data_and_enable() - config = self.create_softap_config() - wutils.start_wifi_tethering(self.dut, - config[wutils.WifiEnums.SSID_KEY], - config[wutils.WifiEnums.PWD_KEY], band, hidden) - if hidden: - # First ensure it's not seen in scan results. - self.confirm_softap_not_in_scan_results( - config[wutils.WifiEnums.SSID_KEY]) - # If the network is hidden, it should be saved on the client to be - # seen in scan results. - config[wutils.WifiEnums.HIDDEN_KEY] = True - ret = self.dut_client.droid.wifiAddNetwork(config) - asserts.assert_true(ret != -1, "Add network %r failed" % config) - self.dut_client.droid.wifiEnableNetwork(ret, 0) - self.confirm_softap_in_scan_results(config[wutils.WifiEnums.SSID_KEY]) - if test_ping: - self.validate_ping_between_softap_and_client(config) - if test_clients: - if hasattr(self, 'arduino_wifi_dongles'): - self.validate_traffic_between_softap_clients(config) - if len(self.android_devices) > 2: - self.validate_ping_between_two_clients(config) - wutils.stop_wifi_tethering(self.dut) - asserts.assert_false(self.dut.droid.wifiIsApEnabled(), - "SoftAp is still reported as running") - if initial_wifi_state: - wutils.wait_for_wifi_state(self.dut, True) - elif self.dut.droid.wifiCheckState(): - asserts.fail("Wifi was disabled before softap and now it is enabled") - - def validate_ping_between_softap_and_client(self, config): - """Test ping between softap and its client. - - Connect one android device to the wifi hotspot. - Verify they can ping each other. - - Args: - config: wifi network config with SSID, password - """ - wutils.wifi_connect(self.dut_client, config, check_connectivity=False) - - dut_ip = self.dut.droid.connectivityGetIPv4Addresses(self.AP_IFACE)[0] - dut_client_ip = self.dut_client.droid.connectivityGetIPv4Addresses('wlan0')[0] - - self.dut.log.info("Try to ping %s" % dut_client_ip) - asserts.assert_true( - utils.adb_shell_ping(self.dut, count=10, dest_ip=dut_client_ip, timeout=20), - "%s ping %s failed" % (self.dut.serial, dut_client_ip)) - - self.dut_client.log.info("Try to ping %s" % dut_ip) - asserts.assert_true( - utils.adb_shell_ping(self.dut_client, count=10, dest_ip=dut_ip, timeout=20), - "%s ping %s failed" % (self.dut_client.serial, dut_ip)) - - wutils.stop_wifi_tethering(self.dut) - - def validate_ping_between_two_clients(self, config): - """Test ping between softap's clients. - - Connect two android device to the wifi hotspot. - Verify the clients can ping each other. - - Args: - config: wifi network config with SSID, password - """ - # Connect DUT to Network - ad1 = self.dut_client - ad2 = self.android_devices[2] - - wutils.wifi_connect(ad1, config, check_connectivity=False) - wutils.wifi_connect(ad2, config, check_connectivity=False) - ad1_ip = ad1.droid.connectivityGetIPv4Addresses('wlan0')[0] - ad2_ip = ad2.droid.connectivityGetIPv4Addresses('wlan0')[0] - - # Ping each other - ad1.log.info("Try to ping %s" % ad2_ip) - asserts.assert_true( - utils.adb_shell_ping(ad1, count=10, dest_ip=ad2_ip, timeout=20), - "%s ping %s failed" % (ad1.serial, ad2_ip)) - - ad2.log.info("Try to ping %s" % ad1_ip) - asserts.assert_true( - utils.adb_shell_ping(ad2, count=10, dest_ip=ad1_ip, timeout=20), - "%s ping %s failed" % (ad2.serial, ad1_ip)) - - """ Tests Begin """ - - @test_tracker_info(uuid="495f1252-e440-461c-87a7-2c45f369e129") - def test_check_wifi_tethering_supported(self): - """Test check for wifi tethering support. - - 1. Call method to check if wifi hotspot is supported - """ - # TODO(silberst): wifiIsPortableHotspotSupported() is currently failing. - # Remove the extra check and logging when b/30800811 is resolved - hotspot_supported = self.dut.droid.wifiIsPortableHotspotSupported() - tethering_supported = self.dut.droid.connectivityIsTetheringSupported() - self.log.info( - "IsPortableHotspotSupported: %s, IsTetheringSupported %s." % ( - hotspot_supported, tethering_supported)) - asserts.assert_true(hotspot_supported, - "DUT should support wifi tethering but is reporting false.") - asserts.assert_true(tethering_supported, - "DUT should also support wifi tethering when called from ConnectivityManager") - - @test_tracker_info(uuid="09c19c35-c708-48a5-939b-ac2bbb403d54") - def test_full_tether_startup(self): - """Test full startup of wifi tethering in default band. - - 1. Report current state. - 2. Switch to AP mode. - 3. verify SoftAP active. - 4. Shutdown wifi tethering. - 5. verify back to previous mode. - """ - self.validate_full_tether_startup() - - @test_tracker_info(uuid="6437727d-7db1-4f69-963e-f26a7797e47f") - def test_full_tether_startup_2G(self): - """Test full startup of wifi tethering in 2G band. - - 1. Report current state. - 2. Switch to AP mode. - 3. verify SoftAP active. - 4. Shutdown wifi tethering. - 5. verify back to previous mode. - """ - self.validate_full_tether_startup(WIFI_CONFIG_APBAND_2G) - - @test_tracker_info(uuid="970272fa-1302-429b-b261-51efb4dad779") - def test_full_tether_startup_5G(self): - """Test full startup of wifi tethering in 5G band. - - 1. Report current state. - 2. Switch to AP mode. - 3. verify SoftAP active. - 4. Shutdown wifi tethering. - 5. verify back to previous mode. - """ - self.validate_full_tether_startup(WIFI_CONFIG_APBAND_5G) - - @test_tracker_info(uuid="f76ed37a-519a-48b4-b260-ee3fc5a9cae0") - def test_full_tether_startup_auto(self): - """Test full startup of wifi tethering in auto-band. - - 1. Report current state. - 2. Switch to AP mode. - 3. verify SoftAP active. - 4. Shutdown wifi tethering. - 5. verify back to previous mode. - """ - self.validate_full_tether_startup(WIFI_CONFIG_APBAND_AUTO) - - @test_tracker_info(uuid="d26ee4df-5dcb-4191-829f-05a10b1218a7") - def test_full_tether_startup_2G_hidden(self): - """Test full startup of wifi tethering in 2G band using hidden AP. - - 1. Report current state. - 2. Switch to AP mode. - 3. verify SoftAP active. - 4. Shutdown wifi tethering. - 5. verify back to previous mode. - """ - self.validate_full_tether_startup(WIFI_CONFIG_APBAND_2G, True) - - @test_tracker_info(uuid="229cd585-a789-4c9a-8948-89fa72de9dd5") - def test_full_tether_startup_5G_hidden(self): - """Test full startup of wifi tethering in 5G band using hidden AP. - - 1. Report current state. - 2. Switch to AP mode. - 3. verify SoftAP active. - 4. Shutdown wifi tethering. - 5. verify back to previous mode. - """ - self.validate_full_tether_startup(WIFI_CONFIG_APBAND_5G, True) - - @test_tracker_info(uuid="d546a143-6047-4ffd-b3c6-5ec81a38001f") - def test_full_tether_startup_auto_hidden(self): - """Test full startup of wifi tethering in auto-band using hidden AP. - - 1. Report current state. - 2. Switch to AP mode. - 3. verify SoftAP active. - 4. Shutdown wifi tethering. - 5. verify back to previous mode. - """ - self.validate_full_tether_startup(WIFI_CONFIG_APBAND_AUTO, True) - - @test_tracker_info(uuid="b2f75330-bf33-4cdd-851a-de390f891ef7") - def test_tether_startup_while_connected_to_a_network(self): - """Test full startup of wifi tethering in auto-band while the device - is connected to a network. - - 1. Connect to an open network. - 2. Turn on AP mode (in auto band). - 3. Verify SoftAP active. - 4. Make a client connect to the AP. - 5. Shutdown wifi tethering. - 6. Ensure that the client disconnected. - """ - wutils.wifi_toggle_state(self.dut, True) - wutils.wifi_connect(self.dut, self.open_network) - config = self.create_softap_config() - wutils.start_wifi_tethering(self.dut, - config[wutils.WifiEnums.SSID_KEY], - config[wutils.WifiEnums.PWD_KEY], - WIFI_CONFIG_APBAND_AUTO) - asserts.assert_true(self.dut.droid.wifiIsApEnabled(), - "SoftAp is not reported as running") - # local hotspot may not have internet connectivity - self.confirm_softap_in_scan_results(config[wutils.WifiEnums.SSID_KEY]) - wutils.wifi_connect(self.dut_client, config, check_connectivity=False) - wutils.stop_wifi_tethering(self.dut) - wutils.wait_for_disconnect(self.dut_client) - - @test_tracker_info(uuid="f2cf56ad-b8b9-43b6-ab15-a47b1d96b92e") - def test_full_tether_startup_2G_with_airplane_mode_on(self): - """Test full startup of wifi tethering in 2G band with - airplane mode on. - - 1. Turn on airplane mode. - 2. Report current state. - 3. Switch to AP mode. - 4. verify SoftAP active. - 5. Shutdown wifi tethering. - 6. verify back to previous mode. - 7. Turn off airplane mode. - """ - self.dut.log.debug("Toggling Airplane mode ON.") - asserts.assert_true(utils.force_airplane_mode(self.dut, True), - "Can not turn on airplane mode: %s" % self.dut.serial) - wutils.wifi_toggle_state(self.dut, True) - self.validate_full_tether_startup(WIFI_CONFIG_APBAND_2G) - - @test_tracker_info(uuid="05c6f929-7754-477f-a9cd-f77e850b818b") - def test_full_tether_startup_2G_multiple_clients(self): - """Test full startup of wifi tethering in 2G band, connect clients - to softAp and send traffic between them. - - 1. Report current state. - 2. Switch to AP mode. - 3. verify SoftAP active. - 4. Connect clients to softAp. - 5. Send and recv UDP traffic between them. - 6. Shutdown wifi tethering. - 7. verify back to previous mode. - """ - asserts.skip_if(not hasattr(self, 'arduino_wifi_dongles'), - "No wifi dongles connected. Skipping test") - self.validate_full_tether_startup(WIFI_CONFIG_APBAND_2G, - test_clients=True) - - @test_tracker_info(uuid="883dd5b1-50c6-4958-a50f-bb4bea77ccaf") - def test_full_tether_startup_2G_one_client_ping_softap(self): - """(AP) 1 Device can connect to 2G hotspot - - Steps: - 1. Turn on DUT's 2G softap - 2. Client connects to the softap - 3. Client and DUT ping each other - """ - self.validate_full_tether_startup(WIFI_CONFIG_APBAND_2G, test_ping=True) - - @test_tracker_info(uuid="6604e848-99d6-422c-9fdc-2882642438b6") - def test_full_tether_startup_5G_one_client_ping_softap(self): - """(AP) 1 Device can connect to 5G hotspot - - Steps: - 1. Turn on DUT's 5G softap - 2. Client connects to the softap - 3. Client and DUT ping each other - """ - self.validate_full_tether_startup(WIFI_CONFIG_APBAND_5G, test_ping=True) - - @test_tracker_info(uuid="17725ecd-f900-4cf7-8b2d-d7515b0a595c") - def test_softap_2G_two_clients_ping_each_other(self): - """Test for 2G hotspot with 2 clients - - 1. Turn on 2G hotspot - 2. Two clients connect to the hotspot - 3. Two clients ping each other - """ - asserts.skip_if(len(self.android_devices) < 3, - "No extra android devices. Skip test") - self.validate_full_tether_startup(WIFI_CONFIG_APBAND_2G, test_clients=True) - - @test_tracker_info(uuid="98c09888-1021-4f79-9065-b3cf9b132146") - def test_softap_5G_two_clients_ping_each_other(self): - """Test for 5G hotspot with 2 clients - - 1. Turn on 5G hotspot - 2. Two clients connect to the hotspot - 3. Two clients ping each other - """ - asserts.skip_if(len(self.android_devices) < 3, - "No extra android devices. Skip test") - self.validate_full_tether_startup(WIFI_CONFIG_APBAND_5G, test_clients=True) - - @test_tracker_info(uuid="b991129e-030a-4998-9b08-0687270bec24") - def test_number_of_softap_clients(self): - """Test for number of softap clients to be updated correctly - - 1. Turn of hotspot - 2. Register softap callback - 3. Let client connect to the hotspot - 4. Register second softap callback - 5. Force client connect/disconnect to hotspot - 6. Unregister second softap callback - 7. Force second client connect to hotspot (if supported) - 8. Turn off hotspot - 9. Verify second softap callback doesn't respond after unresister - """ - config = wutils.start_softap_and_verify(self, WIFI_CONFIG_APBAND_AUTO) - # Register callback after softap enabled to avoid unnecessary callback - # impact the test - callbackId = self.dut.droid.registerSoftApCallback() - # Verify clients will update immediately after register callback - wutils.wait_for_expected_number_of_softap_clients( - self.dut, callbackId, 0) - wutils.wait_for_expected_softap_state(self.dut, callbackId, - wifi_constants.WIFI_AP_ENABLED_STATE) - - # Force DUTs connect to Network - wutils.wifi_connect(self.dut_client, config, - check_connectivity=False) - wutils.wait_for_expected_number_of_softap_clients( - self.dut, callbackId, 1) - - # Register another callback to verify multi callback clients case - callbackId_2 = self.dut.droid.registerSoftApCallback() - # Verify clients will update immediately after register callback - wutils.wait_for_expected_number_of_softap_clients( - self.dut, callbackId_2, 1) - wutils.wait_for_expected_softap_state(self.dut, callbackId_2, - wifi_constants.WIFI_AP_ENABLED_STATE) - - # Client Off/On Wifi to verify number of softap clients will be updated - wutils.toggle_wifi_and_wait_for_reconnection(self.dut_client, config) - - wutils.wait_for_expected_number_of_softap_clients(self.dut, - callbackId, 0) - wutils.wait_for_expected_number_of_softap_clients(self.dut, - callbackId_2, 0) - wutils.wait_for_expected_number_of_softap_clients(self.dut, - callbackId, 1) - wutils.wait_for_expected_number_of_softap_clients(self.dut, - callbackId_2, 1) - - # Unregister callbackId_2 to verify multi callback clients case - self.dut.droid.unregisterSoftApCallback(callbackId_2) - - if len(self.android_devices) > 2: - wutils.wifi_connect(self.android_devices[2], config, - check_connectivity=False) - wutils.wait_for_expected_number_of_softap_clients( - self.dut, callbackId, 2) - - # Turn off softap when clients connected - wutils.stop_wifi_tethering(self.dut) - wutils.wait_for_disconnect(self.dut_client) - if len(self.android_devices) > 2: - wutils.wait_for_disconnect(self.android_devices[2]) - - # Verify client number change back to 0 after softap stop if client - # doesn't disconnect before softap stop - wutils.wait_for_expected_softap_state(self.dut, callbackId, - wifi_constants.WIFI_AP_DISABLING_STATE) - wutils.wait_for_expected_softap_state(self.dut, callbackId, - wifi_constants.WIFI_AP_DISABLED_STATE) - wutils.wait_for_expected_number_of_softap_clients( - self.dut, callbackId, 0) - # Unregister callback - self.dut.droid.unregisterSoftApCallback(callbackId) - - # Check no any callbackId_2 event after unregister - asserts.assert_equal( - wutils.get_current_number_of_softap_clients( - self.dut, callbackId_2), None) - - @test_tracker_info(uuid="35bc4ba1-bade-42ee-a563-0c73afb2402a") - def test_softap_auto_shut_off(self): - """Test for softap auto shut off - - 1. Turn off hotspot - 2. Register softap callback - 3. Let client connect to the hotspot - 4. Start wait [wifi_constants.DEFAULT_SOFTAP_TIMEOUT_S] seconds - 5. Check hotspot doesn't shut off - 6. Let client disconnect to the hotspot - 7. Start wait [wifi_constants.DEFAULT_SOFTAP_TIMEOUT_S] seconds - 8. Check hotspot auto shut off - """ - config = wutils.start_softap_and_verify(self, WIFI_CONFIG_APBAND_AUTO) - # Register callback after softap enabled to avoid unnecessary callback - # impact the test - callbackId = self.dut.droid.registerSoftApCallback() - # Verify clients will update immediately after register callback - wutils.wait_for_expected_number_of_softap_clients(self.dut, - callbackId, 0) - wutils.wait_for_expected_softap_state(self.dut, callbackId, - wifi_constants.WIFI_AP_ENABLED_STATE) - - # Force DUTs connect to Network - wutils.wifi_connect(self.dut_client, config, check_connectivity=False) - wutils.wait_for_expected_number_of_softap_clients( - self.dut, callbackId, 1) - - self.dut.log.info("Start waiting %s seconds with 1 clients ", - wifi_constants.DEFAULT_SOFTAP_TIMEOUT_S*1.1) - time.sleep(wifi_constants.DEFAULT_SOFTAP_TIMEOUT_S*1.1) - - # When client connected, softap should keep as enabled - asserts.assert_true(self.dut.droid.wifiIsApEnabled(), - "SoftAp is not reported as running") - - wutils.wifi_toggle_state(self.dut_client, False) - wutils.wait_for_expected_number_of_softap_clients(self.dut, - callbackId, 0) - self.dut.log.info("Start waiting %s seconds with 0 client", - wifi_constants.DEFAULT_SOFTAP_TIMEOUT_S*1.1) - time.sleep(wifi_constants.DEFAULT_SOFTAP_TIMEOUT_S*1.1) - # Softap should stop since no client connected - # doesn't disconnect before softap stop - wutils.wait_for_expected_softap_state(self.dut, callbackId, - wifi_constants.WIFI_AP_DISABLING_STATE) - wutils.wait_for_expected_softap_state(self.dut, callbackId, - wifi_constants.WIFI_AP_DISABLED_STATE) - asserts.assert_false(self.dut.droid.wifiIsApEnabled(), - "SoftAp is not reported as running") - self.dut.droid.unregisterSoftApCallback(callbackId) - - """ Tests End """ - - -if __name__ == "__main__": - pass diff --git a/acts/tests/google/wifi/WifiStaApConcurrencyStressTest.py b/acts/tests/google/wifi/WifiStaApConcurrencyStressTest.py deleted file mode 100755 index 6dda5ddae5..0000000000 --- a/acts/tests/google/wifi/WifiStaApConcurrencyStressTest.py +++ /dev/null @@ -1,322 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2018 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import time -import pprint - -from acts import asserts -from acts import signals -from acts import utils -from acts.test_decorators import test_tracker_info -from acts.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_2G -from acts.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_5G -from WifiStaApConcurrencyTest import WifiStaApConcurrencyTest -import acts.test_utils.wifi.wifi_test_utils as wutils - -WifiEnums = wutils.WifiEnums - -# Channels to configure the AP for various test scenarios. -WIFI_NETWORK_AP_CHANNEL_2G = 1 -WIFI_NETWORK_AP_CHANNEL_5G = 36 -WIFI_NETWORK_AP_CHANNEL_5G_DFS = 132 - -class WifiStaApConcurrencyStressTest(WifiStaApConcurrencyTest): - """Stress tests for STA + AP concurrency scenarios. - - Test Bed Requirement: - * At least two Android devices (For AP) - * One Wi-Fi network visible to the device (for STA). - """ - - def __init__(self, controllers): - WifiStaApConcurrencyTest.__init__(self, controllers) - self.tests = ("test_stress_wifi_connection_2G_softap_2G", - "test_stress_wifi_connection_5G_softap_5G", - "test_stress_wifi_connection_5G_DFS_softap_5G", - "test_stress_wifi_connection_5G_softap_2G", - "test_stress_wifi_connection_5G_DFS_softap_2G", - "test_stress_wifi_connection_2G_softap_5G", - "test_stress_wifi_connection_5G_softap_2G_with_location_scan_on", - "test_stress_softap_2G_wifi_connection_2G", - "test_stress_softap_5G_wifi_connection_5G", - "test_stress_softap_5G_wifi_connection_5G_DFS", - "test_stress_softap_5G_wifi_connection_2G", - "test_stress_softap_2G_wifi_connection_5G", - "test_stress_softap_2G_wifi_connection_5G_DFS", - "test_stress_softap_5G_wifi_connection_2G_with_location_scan_on") - - def setup_class(self): - self.dut = self.android_devices[0] - self.dut_client = self.android_devices[1] - wutils.wifi_test_device_init(self.dut) - wutils.wifi_test_device_init(self.dut_client) - # Do a simple version of init - mainly just sync the time and enable - # verbose logging. This test will fail if the DUT has a sim and cell - # data is disabled. We would also like to test with phones in less - # constrained states (or add variations where we specifically - # constrain). - utils.require_sl4a((self.dut, self.dut_client)) - utils.sync_device_time(self.dut) - utils.sync_device_time(self.dut_client) - # Set country code explicitly to "US". - wutils.set_wifi_country_code(self.dut, wutils.WifiEnums.CountryCode.US) - wutils.set_wifi_country_code(self.dut_client, wutils.WifiEnums.CountryCode.US) - # Enable verbose logging on the duts - self.dut.droid.wifiEnableVerboseLogging(1) - asserts.assert_equal(self.dut.droid.wifiGetVerboseLoggingLevel(), 1, - "Failed to enable WiFi verbose logging on the softap dut.") - self.dut_client.droid.wifiEnableVerboseLogging(1) - asserts.assert_equal(self.dut_client.droid.wifiGetVerboseLoggingLevel(), 1, - "Failed to enable WiFi verbose logging on the client dut.") - - req_params = ["AccessPoint", "dbs_supported_models", "stress_count"] - opt_param = ["iperf_server_address"] - self.unpack_userparams( - req_param_names=req_params, opt_param_names=opt_param) - - if self.dut.model not in self.dbs_supported_models: - asserts.skip( - ("Device %s does not support dual interfaces.") - % self.dut.model) - - if "iperf_server_address" in self.user_params: - self.iperf_server = self.iperf_servers[0] - if hasattr(self, 'iperf_server'): - self.iperf_server.start() - - # Set the client wifi state to on before the test begins. - wutils.wifi_toggle_state(self.dut_client, True) - - # Init extra devices - if len(self.android_devices) > 2: - wutils.wifi_test_device_init(self.android_devices[2]) - utils.sync_device_time(self.android_devices[2]) - wutils.set_wifi_country_code(self.android_devices[2], wutils.WifiEnums.CountryCode.US) - self.android_devices[2].droid.wifiEnableVerboseLogging(1) - asserts.assert_equal(self.android_devices[2].droid.wifiGetVerboseLoggingLevel(), 1, - "Failed to enable WiFi verbose logging on the client dut.") - - """Helper Functions""" - - def verify_wifi_full_on_off(self, network, softap_config): - wutils.wifi_toggle_state(self.dut, True) - self.connect_to_wifi_network_and_verify((network, self.dut)) - self.run_iperf_client((network, self.dut)) - self.run_iperf_client((softap_config, self.dut_client)) - if len(self.android_devices) > 2: - self.log.info("Testbed has extra android devices, do more validation") - self.verify_traffic_between_ap_clients( - self.dut, self.android_devices[2]) - wutils.wifi_toggle_state(self.dut, False) - - def verify_softap_full_on_off(self, network, softap_band): - softap_config = self.start_softap_and_verify(softap_band) - self.run_iperf_client((network, self.dut)) - self.run_iperf_client((softap_config, self.dut_client)) - if len(self.android_devices) > 2: - self.log.info("Testbed has extra android devices, do more validation") - self.verify_traffic_between_softap_clients( - self.dut_client, self.android_devices[2]) - wutils.reset_wifi(self.dut_client) - if len(self.android_devices) > 2: - wutils.reset_wifi(self.android_devices[2]) - wutils.stop_wifi_tethering(self.dut) - - """Tests""" - @test_tracker_info(uuid="615997cc-8290-4af3-b3ac-1f5bd5af6ed1") - def test_stress_wifi_connection_2G_softap_2G(self): - """Tests connection to 2G network the enable/disable SoftAp on 2G N times. - """ - self.configure_ap(channel_2g=WIFI_NETWORK_AP_CHANNEL_2G) - wutils.wifi_toggle_state(self.dut, True) - self.connect_to_wifi_network_and_verify((self.wpapsk_2g, self.dut)) - for count in range(self.stress_count): - self.log.info("Iteration %d", count+1) - self.verify_softap_full_on_off(self.wpapsk_2g, WIFI_CONFIG_APBAND_2G) - raise signals.TestPass(details="", extras={"Iterations":"%d" % - self.stress_count, "Pass":"%d" %(count+1)}) - - @test_tracker_info(uuid="03362d54-a624-4fb8-ad97-7abb9e6f655c") - def test_stress_wifi_connection_5G_softap_5G(self): - """Tests connection to 5G network followed by bringing up SoftAp on 5G. - """ - self.configure_ap(channel_5g=WIFI_NETWORK_AP_CHANNEL_5G) - wutils.wifi_toggle_state(self.dut, True) - self.connect_to_wifi_network_and_verify((self.wpapsk_5g, self.dut)) - for count in range(self.stress_count): - self.log.info("Iteration %d", count+1) - self.verify_softap_full_on_off(self.wpapsk_5g, WIFI_CONFIG_APBAND_5G) - raise signals.TestPass(details="", extras={"Iterations":"%d" % - self.stress_count, "Pass":"%d" %(count+1)}) - - @test_tracker_info(uuid="fdda4ff2-38d5-4398-9a59-c7cee407a2b3") - def test_stress_wifi_connection_5G_DFS_softap_5G(self): - """Tests connection to 5G DFS network followed by bringing up SoftAp on 5G. - """ - self.configure_ap(channel_5g=WIFI_NETWORK_AP_CHANNEL_5G_DFS) - wutils.wifi_toggle_state(self.dut, True) - self.connect_to_wifi_network_and_verify((self.wpapsk_5g, self.dut)) - for count in range(self.stress_count): - self.log.info("Iteration %d", count+1) - self.verify_softap_full_on_off(self.wpapsk_5g, WIFI_CONFIG_APBAND_5G) - raise signals.TestPass(details="", extras={"Iterations":"%d" % - self.stress_count, "Pass":"%d" %(count+1)}) - - @test_tracker_info(uuid="b3621721-7714-43eb-8438-b578164b9194") - def test_stress_wifi_connection_5G_softap_2G(self): - """Tests connection to 5G network followed by bringing up SoftAp on 2G. - """ - self.configure_ap(channel_5g=WIFI_NETWORK_AP_CHANNEL_5G) - wutils.wifi_toggle_state(self.dut, True) - self.connect_to_wifi_network_and_verify((self.wpapsk_5g, self.dut)) - for count in range(self.stress_count): - self.log.info("Iteration %d", count+1) - self.verify_softap_full_on_off(self.wpapsk_5g, WIFI_CONFIG_APBAND_2G) - raise signals.TestPass(details="", extras={"Iterations":"%d" % - self.stress_count, "Pass":"%d" %(count+1)}) - - @test_tracker_info(uuid="bde1443f-f912-408e-b01a-537548dd023c") - def test_stress_wifi_connection_5G_DFS_softap_2G(self): - """Tests connection to 5G DFS network followed by bringing up SoftAp on 2G. - """ - self.configure_ap(channel_5g=WIFI_NETWORK_AP_CHANNEL_5G_DFS) - wutils.wifi_toggle_state(self.dut, True) - self.connect_to_wifi_network_and_verify((self.wpapsk_5g, self.dut)) - for count in range(self.stress_count): - self.verify_softap_full_on_off(self.wpapsk_5g, WIFI_CONFIG_APBAND_2G) - raise signals.TestPass(details="", extras={"Iterations":"%d" % - self.stress_count, "Pass":"%d" %(count+1)}) - - @test_tracker_info(uuid="2b6a891a-e0d6-4660-abf6-579099ce6924") - def test_stress_wifi_connection_2G_softap_5G(self): - """Tests connection to 2G network followed by bringing up SoftAp on 5G. - """ - self.configure_ap(channel_2g=WIFI_NETWORK_AP_CHANNEL_2G) - wutils.wifi_toggle_state(self.dut, True) - self.connect_to_wifi_network_and_verify((self.wpapsk_2g, self.dut)) - for count in range(self.stress_count): - self.log.info("Iteration %d", count+1) - self.verify_softap_full_on_off(self.wpapsk_2g, WIFI_CONFIG_APBAND_5G) - raise signals.TestPass(details="", extras={"Iterations":"%d" % - self.stress_count, "Pass":"%d" %(count+1)}) - - @test_tracker_info(uuid="f28abf22-9df0-4500-b342-6682ca305e60") - def test_stress_wifi_connection_5G_softap_2G_with_location_scan_on(self): - """Tests connection to 5G network followed by bringing up SoftAp on 2G - with location scans turned on. - """ - self.configure_ap(channel_5g=WIFI_NETWORK_AP_CHANNEL_5G) - self.turn_location_on_and_scan_toggle_on() - wutils.wifi_toggle_state(self.dut, True) - self.connect_to_wifi_network_and_verify((self.wpapsk_5g, self.dut)) - for count in range(self.stress_count): - self.log.info("Iteration %d", count+1) - self.verify_softap_full_on_off(self.wpapsk_5g, WIFI_CONFIG_APBAND_2G) - raise signals.TestPass(details="", extras={"Iterations":"%d" % - self.stress_count, "Pass":"%d" %(count+1)}) - - @test_tracker_info(uuid="0edb1500-6c60-442e-9268-a2ad9ee2b55c") - def test_stress_softap_2G_wifi_connection_2G(self): - """Tests enable SoftAp on 2G then connection/disconnection to 2G network for N times. - """ - self.configure_ap(channel_2g=WIFI_NETWORK_AP_CHANNEL_2G) - softap_config = self.start_softap_and_verify( - WIFI_CONFIG_APBAND_2G, check_connectivity=False) - for count in range(self.stress_count): - self.log.info("Iteration %d", count+1) - self.verify_wifi_full_on_off(self.wpapsk_2g, softap_config) - raise signals.TestPass(details="", extras={"Iterations":"%d" % - self.stress_count, "Pass":"%d" %(count+1)}) - - @test_tracker_info(uuid="162a6679-edd5-4daa-9f25-75d79cf4bb4a") - def test_stress_softap_5G_wifi_connection_5G(self): - """Tests enable SoftAp on 5G then connection/disconnection to 5G network for N times. - """ - self.configure_ap(channel_5g=WIFI_NETWORK_AP_CHANNEL_5G) - softap_config = self.start_softap_and_verify( - WIFI_CONFIG_APBAND_5G, check_connectivity=False) - for count in range(self.stress_count): - self.log.info("Iteration %d", count+1) - self.verify_wifi_full_on_off(self.wpapsk_5g, softap_config) - raise signals.TestPass(details="", extras={"Iterations":"%d" % - self.stress_count, "Pass":"%d" %(count+1)}) - - @test_tracker_info(uuid="ee98f2dd-c4f9-4f48-ab59-f577267760d5") - def test_stress_softap_5G_wifi_connection_5G_DFS(self): - """Tests enable SoftAp on 5G then connection/disconnection to 5G DFS network for N times. - """ - self.configure_ap(channel_5g=WIFI_NETWORK_AP_CHANNEL_5G_DFS) - softap_config = self.start_softap_and_verify( - WIFI_CONFIG_APBAND_5G, check_connectivity=False) - for count in range(self.stress_count): - self.log.info("Iteration %d", count+1) - self.verify_wifi_full_on_off(self.wpapsk_5g, softap_config) - raise signals.TestPass(details="", extras={"Iterations":"%d" % - self.stress_count, "Pass":"%d" %(count+1)}) - - @test_tracker_info(uuid="b50750b5-d5b9-4687-b9e7-9fb15f54b428") - def test_stress_softap_5G_wifi_connection_2G(self): - """Tests enable SoftAp on 5G then connection/disconnection to 2G network for N times. - """ - self.configure_ap(channel_2g=WIFI_NETWORK_AP_CHANNEL_2G) - softap_config = self.start_softap_and_verify( - WIFI_CONFIG_APBAND_5G, check_connectivity=False) - for count in range(self.stress_count): - self.log.info("Iteration %d", count+1) - self.verify_wifi_full_on_off(self.wpapsk_2g, softap_config) - raise signals.TestPass(details="", extras={"Iterations":"%d" % - self.stress_count, "Pass":"%d" %(count+1)}) - - @test_tracker_info(uuid="9a2865db-8e4b-4339-9999-000ce9b6970b") - def test_stress_softap_2G_wifi_connection_5G(self): - """Tests enable SoftAp on 2G then connection/disconnection to 5G network for N times. - """ - self.configure_ap(channel_5g=WIFI_NETWORK_AP_CHANNEL_5G) - softap_config = self.start_softap_and_verify( - WIFI_CONFIG_APBAND_2G, check_connectivity=False) - for count in range(self.stress_count): - self.log.info("Iteration %d", count+1) - self.verify_wifi_full_on_off(self.wpapsk_5g, softap_config) - raise signals.TestPass(details="", extras={"Iterations":"%d" % - self.stress_count, "Pass":"%d" %(count+1)}) - - @test_tracker_info(uuid="add6609d-91d6-4b89-94c5-0ad8b941e3d1") - def test_stress_softap_2G_wifi_connection_5G_DFS(self): - """Tests enable SoftAp on 2G then connection/disconnection to 5G DFS network for N times. - """ - self.configure_ap(channel_5g=WIFI_NETWORK_AP_CHANNEL_5G_DFS) - softap_config = self.start_softap_and_verify( - WIFI_CONFIG_APBAND_2G, check_connectivity=False) - for count in range(self.stress_count): - self.log.info("Iteration %d", count+1) - self.verify_wifi_full_on_off(self.wpapsk_5g, softap_config) - raise signals.TestPass(details="", extras={"Iterations":"%d" % - self.stress_count, "Pass":"%d" %(count+1)}) - - @test_tracker_info(uuid="ee42afb6-99d0-4330-933f-d4dd8c3626c6") - def test_stress_softap_5G_wifi_connection_2G_with_location_scan_on(self): - """Tests enable SoftAp on 5G then connection/disconnection to 2G network for N times - with location scans turned on. - """ - self.configure_ap(channel_2g=WIFI_NETWORK_AP_CHANNEL_2G) - self.turn_location_on_and_scan_toggle_on() - softap_config = self.start_softap_and_verify( - WIFI_CONFIG_APBAND_5G, check_connectivity=False) - for count in range(self.stress_count): - self.log.info("Iteration %d", count+1) - self.verify_wifi_full_on_off(self.wpapsk_2g, softap_config) - raise signals.TestPass(details="", extras={"Iterations":"%d" % - self.stress_count, "Pass":"%d" %(count+1)}) diff --git a/acts/tests/google/wifi/WifiStaApConcurrencyTest.py b/acts/tests/google/wifi/WifiStaApConcurrencyTest.py deleted file mode 100644 index c5d74249f1..0000000000 --- a/acts/tests/google/wifi/WifiStaApConcurrencyTest.py +++ /dev/null @@ -1,373 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2018 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import pprint -import time - -from acts import asserts -from acts import base_test -from acts.controllers.ap_lib import hostapd_constants -import acts.signals as signals -from acts.test_decorators import test_tracker_info -from acts.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_2G -from acts.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_5G -import acts.test_utils.wifi.wifi_test_utils as wutils -from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest -import acts.utils as utils - -WifiEnums = wutils.WifiEnums -WLAN = "wlan0" -# Channels to configure the AP for various test scenarios. -WIFI_NETWORK_AP_CHANNEL_2G = 1 -WIFI_NETWORK_AP_CHANNEL_5G = 36 -WIFI_NETWORK_AP_CHANNEL_5G_DFS = 132 - - -class WifiStaApConcurrencyTest(WifiBaseTest): - """Tests for STA + AP concurrency scenarios. - - Test Bed Requirement: - * Two Android devices (For AP) - * One Wi-Fi network visible to the device (for STA). - """ - - def setup_class(self): - super().setup_class() - - self.dut = self.android_devices[0] - self.dut_client = self.android_devices[1] - - # Do a simple version of init - mainly just sync the time and enable - # verbose logging. This test will fail if the DUT has a sim and cell - # data is disabled. We would also like to test with phones in less - # constrained states (or add variations where we specifically - # constrain). - utils.require_sl4a(self.android_devices) - - for ad in self.android_devices: - wutils.wifi_test_device_init(ad) - utils.sync_device_time(ad) - # Set country code explicitly to "US". - wutils.set_wifi_country_code(ad, WifiEnums.CountryCode.US) - # Enable verbose logging on the duts. - ad.droid.wifiEnableVerboseLogging(1) - - req_params = ["dbs_supported_models", - "iperf_server_address", - "iperf_server_port"] - self.unpack_userparams(req_param_names=req_params,) - asserts.abort_class_if( - self.dut.model not in self.dbs_supported_models, - "Device %s does not support dual interfaces." % self.dut.model) - - def setup_test(self): - for ad in self.android_devices: - ad.droid.wakeLockAcquireBright() - ad.droid.wakeUpNow() - self.turn_location_off_and_scan_toggle_off() - - def teardown_test(self): - # Prevent the stop wifi tethering failure to block ap close - try: - wutils.stop_wifi_tethering(self.dut) - except signals.TestFailure: - pass - for ad in self.android_devices: - ad.droid.wakeLockRelease() - ad.droid.goToSleepNow() - wutils.reset_wifi(ad) - self.turn_location_on_and_scan_toggle_on() - wutils.wifi_toggle_state(self.dut, True) - self.access_points[0].close() - del self.user_params["reference_networks"] - del self.user_params["open_network"] - - 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) - - ### Helper Functions ### - - def configure_ap(self, channel_2g=None, channel_5g=None): - """Configure and bring up AP on required channel. - - Args: - channel_2g: The channel number to use for 2GHz network. - channel_5g: The channel number to use for 5GHz network. - - """ - if not channel_2g: - channel_2g = hostapd_constants.AP_DEFAULT_CHANNEL_2G - if not channel_5g: - channel_5g = hostapd_constants.AP_DEFAULT_CHANNEL_5G - self.legacy_configure_ap_and_start(channel_2g=channel_2g, - channel_5g=channel_5g) - self.open_2g = self.open_network[0]["2g"] - self.open_5g = self.open_network[0]["5g"] - - def turn_location_on_and_scan_toggle_on(self): - """Turns on wifi location scans.""" - utils.set_location_service(self.dut, True) - self.dut.droid.wifiScannerToggleAlwaysAvailable(True) - msg = "Failed to turn on location service's scan." - asserts.assert_true(self.dut.droid.wifiScannerIsAlwaysAvailable(), msg) - - def turn_location_off_and_scan_toggle_off(self): - """Turns off wifi location scans.""" - utils.set_location_service(self.dut, False) - self.dut.droid.wifiScannerToggleAlwaysAvailable(False) - msg = "Failed to turn off location service's scan." - asserts.assert_false(self.dut.droid.wifiScannerIsAlwaysAvailable(), msg) - - def run_iperf_client(self, params): - """Run iperf traffic after connection. - - Args: - params: A tuple of network info and AndroidDevice object. - """ - if "iperf_server_address" in self.user_params: - wait_time = 5 - network, ad = params - ssid = network[WifiEnums.SSID_KEY] - self.log.info("Starting iperf traffic through {}".format(ssid)) - time.sleep(wait_time) - port_arg = "-p {}".format(self.iperf_server_port) - success, data = ad.run_iperf_client(self.iperf_server_address, - port_arg) - self.log.debug(pprint.pformat(data)) - asserts.assert_true(success, "Error occurred in iPerf traffic.") - - def create_softap_config(self): - """Create a softap config with ssid and password.""" - ap_ssid = "softap_" + utils.rand_ascii_str(8) - ap_password = utils.rand_ascii_str(8) - self.dut.log.info("softap setup: %s %s", ap_ssid, ap_password) - config = {wutils.WifiEnums.SSID_KEY: ap_ssid} - config[wutils.WifiEnums.PWD_KEY] = ap_password - return config - - def start_softap_and_verify(self, band, check_connectivity=True): - """Test startup of softap. - - 1. Bring up AP mode. - 2. Verify SoftAP active using the client device. - - Args: - band: wifi band to start soft ap on - check_connectivity: If set, verify internet connectivity - - Returns: - Softap config - """ - config = self.create_softap_config() - wutils.start_wifi_tethering(self.dut, - config[WifiEnums.SSID_KEY], - config[WifiEnums.PWD_KEY], - band) - for ad in self.android_devices[1:]: - wutils.connect_to_wifi_network( - ad, config, check_connectivity=check_connectivity) - return config - - def connect_to_wifi_network_and_start_softap(self, nw_params, softap_band): - """Test concurrent wifi connection and softap. - - This helper method first makes a wifi connection and then starts SoftAp. - 1. Bring up wifi. - 2. Establish connection to a network. - 3. Bring up softap and verify AP can be connected by a client device. - 4. Run iperf on the wifi/softap connection to the network. - - Args: - nw_params: Params for network STA connection. - softap_band: Band for the AP. - """ - wutils.connect_to_wifi_network(self.dut, nw_params) - softap_config = self.start_softap_and_verify(softap_band) - self.run_iperf_client((nw_params, self.dut)) - self.run_iperf_client((softap_config, self.dut_client)) - - if len(self.android_devices) > 2: - self.log.info("Testbed has extra devices, do more validation") - self.verify_traffic_between_dut_clients( - self.dut_client, self.android_devices[2]) - - asserts.assert_true(self.dut.droid.wifiCheckState(), - "Wifi is not reported as running") - asserts.assert_true(self.dut.droid.wifiIsApEnabled(), - "SoftAp is not reported as running") - - def start_softap_and_connect_to_wifi_network(self, nw_params, softap_band): - """Test concurrent wifi connection and softap. - - This helper method first starts SoftAp and then makes a wifi connection. - 1. Bring up softap and verify AP can be connected by a client device. - 2. Bring up wifi. - 3. Establish connection to a network. - 4. Run iperf on the wifi/softap connection to the network. - 5. Verify wifi state and softap state. - - Args: - nw_params: Params for network STA connection. - softap_band: Band for the AP. - """ - softap_config = self.start_softap_and_verify(softap_band, False) - wutils.connect_to_wifi_network(self.dut, nw_params) - self.run_iperf_client((nw_params, self.dut)) - self.run_iperf_client((softap_config, self.dut_client)) - - if len(self.android_devices) > 2: - self.log.info("Testbed has extra devices, do more validation") - self.verify_traffic_between_dut_clients( - self.dut, self.android_devices[2]) - - asserts.assert_true(self.dut.droid.wifiCheckState(), - "Wifi is not reported as running") - asserts.assert_true(self.dut.droid.wifiIsApEnabled(), - "SoftAp is not reported as running") - - def verify_traffic_between_dut_clients(self, ad1, ad2, num_of_tries=2): - """Test the clients that connect to DUT's softap can ping each other. - - Args: - ad1: DUT 1 - ad2: DUT 2 - num_of_tries: the retry times of ping test. - """ - ad1_ip = ad1.droid.connectivityGetIPv4Addresses(WLAN)[0] - ad2_ip = ad2.droid.connectivityGetIPv4Addresses(WLAN)[0] - # Ping each other - for _ in range(num_of_tries): - if utils.adb_shell_ping(ad1, count=10, dest_ip=ad2_ip, timeout=20): - break - else: - asserts.fail("%s ping %s failed" % (ad1.serial, ad2_ip)) - for _ in range(num_of_tries): - if utils.adb_shell_ping(ad2, count=10, dest_ip=ad1_ip, timeout=20): - break - else: - asserts.fail("%s ping %s failed" % (ad2.serial, ad1_ip)) - - ### Tests ### - - @test_tracker_info(uuid="c396e7ac-cf22-4736-a623-aa6d3c50193a") - def test_wifi_connection_2G_softap_2G(self): - """Test connection to 2G network followed by SoftAp on 2G.""" - self.configure_ap(channel_2g=WIFI_NETWORK_AP_CHANNEL_2G) - self.connect_to_wifi_network_and_start_softap( - self.open_2g, WIFI_CONFIG_APBAND_2G) - - @test_tracker_info(uuid="1cd6120d-3db4-4624-9bae-55c976533a48") - def test_wifi_connection_5G_softap_5G(self): - """Test connection to 5G network followed by SoftAp on 5G.""" - self.configure_ap(channel_5g=WIFI_NETWORK_AP_CHANNEL_5G) - self.connect_to_wifi_network_and_start_softap( - self.open_5g, WIFI_CONFIG_APBAND_5G) - - @test_tracker_info(uuid="5f980007-3490-413e-b94e-7700ffab8534") - def test_wifi_connection_5G_DFS_softap_5G(self): - """Test connection to 5G DFS network followed by SoftAp on 5G.""" - self.configure_ap(channel_5g=WIFI_NETWORK_AP_CHANNEL_5G_DFS) - self.connect_to_wifi_network_and_start_softap( - self.open_5g, WIFI_CONFIG_APBAND_5G) - - @test_tracker_info(uuid="d05d5d44-c738-4372-9f01-ce2a640a2f25") - def test_wifi_connection_5G_softap_2G(self): - """Test connection to 5G network followed by SoftAp on 2G.""" - self.configure_ap(channel_5g=WIFI_NETWORK_AP_CHANNEL_5G) - self.connect_to_wifi_network_and_start_softap( - self.open_5g, WIFI_CONFIG_APBAND_2G) - - @test_tracker_info(uuid="909ac713-1ad3-4dad-9be3-ad60f00ed25e") - def test_wifi_connection_5G_DFS_softap_2G(self): - """Test connection to 5G DFS network followed by SoftAp on 2G.""" - self.configure_ap(channel_5g=WIFI_NETWORK_AP_CHANNEL_5G_DFS) - self.connect_to_wifi_network_and_start_softap( - self.open_5g, WIFI_CONFIG_APBAND_2G) - - @test_tracker_info(uuid="e8de724a-25d3-4801-94cc-22e9e0ecc8d1") - def test_wifi_connection_2G_softap_5G(self): - """Test connection to 2G network followed by SoftAp on 5G.""" - self.configure_ap(channel_2g=WIFI_NETWORK_AP_CHANNEL_2G) - self.connect_to_wifi_network_and_start_softap( - self.open_2g, WIFI_CONFIG_APBAND_5G) - - @test_tracker_info(uuid="647f4e17-5c7a-4249-98af-f791d163a39f") - def test_wifi_connection_5G_softap_2G_with_location_scan_on(self): - """Test connection to 5G network, SoftAp on 2G with location scan on.""" - self.configure_ap(channel_5g=WIFI_NETWORK_AP_CHANNEL_5G) - self.turn_location_on_and_scan_toggle_on() - self.connect_to_wifi_network_and_start_softap( - self.open_5g, WIFI_CONFIG_APBAND_2G) - # Now toggle wifi off & ensure we can still scan. - wutils.wifi_toggle_state(self.dut, False) - wutils.start_wifi_connection_scan_and_ensure_network_found( - self.dut, self.open_5g[WifiEnums.SSID_KEY]) - - @test_tracker_info(uuid="4aa56c11-e5bc-480b-bd61-4b4ee577a5da") - def test_softap_2G_wifi_connection_2G(self): - """Test SoftAp on 2G followed by connection to 2G network.""" - self.configure_ap(channel_2g=WIFI_NETWORK_AP_CHANNEL_2G) - self.start_softap_and_connect_to_wifi_network( - self.open_2g, WIFI_CONFIG_APBAND_2G) - - @test_tracker_info(uuid="5f954957-ad20-4de1-b20c-6c97d0463bdd") - def test_softap_5G_wifi_connection_5G(self): - """Test SoftAp on 5G followed by connection to 5G network.""" - self.configure_ap(channel_5g=WIFI_NETWORK_AP_CHANNEL_5G) - self.start_softap_and_connect_to_wifi_network( - self.open_5g, WIFI_CONFIG_APBAND_5G) - - @test_tracker_info(uuid="1306aafc-a07e-4654-ba78-674f90cf748e") - def test_softap_5G_wifi_connection_5G_DFS(self): - """Test SoftAp on 5G followed by connection to 5G DFS network.""" - self.configure_ap(channel_5g=WIFI_NETWORK_AP_CHANNEL_5G_DFS) - self.start_softap_and_connect_to_wifi_network( - self.open_5g, WIFI_CONFIG_APBAND_5G) - - @test_tracker_info(uuid="5e28e8b5-3faa-4cff-a782-13a796d7f572") - def test_softap_5G_wifi_connection_2G(self): - """Test SoftAp on 5G followed by connection to 2G network.""" - self.configure_ap(channel_2g=WIFI_NETWORK_AP_CHANNEL_2G) - self.start_softap_and_connect_to_wifi_network( - self.open_2g, WIFI_CONFIG_APBAND_5G) - - @test_tracker_info(uuid="a2c62bc6-9ccd-4bc4-8a23-9a1b5d0b4b5c") - def test_softap_2G_wifi_connection_5G(self): - """Test SoftAp on 2G followed by connection to 5G network.""" - self.configure_ap(channel_5g=WIFI_NETWORK_AP_CHANNEL_5G) - self.start_softap_and_connect_to_wifi_network( - self.open_5g, WIFI_CONFIG_APBAND_2G) - - @test_tracker_info(uuid="75400685-a9d9-4091-8af3-97bd539c246a") - def test_softap_2G_wifi_connection_5G_DFS(self): - """Test SoftAp on 2G followed by connection to 5G DFS network.""" - self.configure_ap(channel_5g=WIFI_NETWORK_AP_CHANNEL_5G_DFS) - self.start_softap_and_connect_to_wifi_network( - self.open_5g, WIFI_CONFIG_APBAND_2G) - - @test_tracker_info(uuid="aa23a3fc-31a1-4d5c-8cf5-2eb9fdf9e7ce") - def test_softap_5G_wifi_connection_2G_with_location_scan_on(self): - """Test SoftAp on 5G, connection to 2G network with location scan on.""" - self.configure_ap(channel_2g=WIFI_NETWORK_AP_CHANNEL_2G) - self.turn_location_on_and_scan_toggle_on() - self.start_softap_and_connect_to_wifi_network( - self.open_2g, WIFI_CONFIG_APBAND_5G) - # Now toggle wifi off & ensure we can still scan. - wutils.wifi_toggle_state(self.dut, False) - wutils.start_wifi_connection_scan_and_ensure_network_found( - self.dut, self.open_2g[WifiEnums.SSID_KEY]) diff --git a/acts/tests/google/wifi/WifiStressTest.py b/acts/tests/google/wifi/WifiStressTest.py deleted file mode 100644 index e31adbb792..0000000000 --- a/acts/tests/google/wifi/WifiStressTest.py +++ /dev/null @@ -1,532 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2018 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import pprint -import queue -import threading -import time - -import acts.base_test -import acts.test_utils.wifi.wifi_test_utils as wutils -import acts.test_utils.tel.tel_test_utils as tutils - -from acts import asserts -from acts import signals -from acts import utils -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 - -WAIT_FOR_AUTO_CONNECT = 40 -WAIT_BEFORE_CONNECTION = 30 - -TIMEOUT = 5 -PING_ADDR = 'www.google.com' - -class WifiStressTest(WifiBaseTest): - """WiFi Stress test class. - - Test Bed Requirement: - * Two Android device - * Several Wi-Fi networks visible to the device, including an open Wi-Fi - network. - """ - - def setup_class(self): - super().setup_class() - - self.dut = self.android_devices[0] - # Note that test_stress_softAP_startup_and_stop_5g will always fail - # when testing with a single device. - if len(self.android_devices) > 1: - self.dut_client = self.android_devices[1] - else: - self.dut_client = None - wutils.wifi_test_device_init(self.dut) - req_params = [] - opt_param = [ - "open_network", "reference_networks", "iperf_server_address", - "stress_count", "stress_hours", "attn_vals", "pno_interval", - "iperf_server_port"] - self.unpack_userparams( - req_param_names=req_params, opt_param_names=opt_param) - - if "AccessPoint" in self.user_params: - self.legacy_configure_ap_and_start(ap_count=2) - - asserts.assert_true( - len(self.reference_networks) > 0, - "Need at least one reference network with psk.") - self.wpa_2g = self.reference_networks[0]["2g"] - self.wpa_5g = self.reference_networks[0]["5g"] - self.open_2g = self.open_network[0]["2g"] - self.open_5g = self.open_network[0]["5g"] - self.networks = [self.wpa_2g, self.wpa_5g, self.open_2g, self.open_5g] - - def setup_test(self): - self.dut.droid.wakeLockAcquireBright() - self.dut.droid.wakeUpNow() - - def teardown_test(self): - if self.dut.droid.wifiIsApEnabled(): - wutils.stop_wifi_tethering(self.dut) - self.dut.droid.wakeLockRelease() - self.dut.droid.goToSleepNow() - wutils.reset_wifi(self.dut) - - def on_fail(self, test_name, begin_time): - self.dut.take_bug_report(test_name, begin_time) - self.dut.cat_adb_log(test_name, begin_time) - - def teardown_class(self): - wutils.reset_wifi(self.dut) - 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, ad, network): - """Scan for network and connect using network information. - - Args: - network: A dictionary representing the network to connect to. - - """ - ssid = network[WifiEnums.SSID_KEY] - 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. - - Args: - net_id: Integer specifying the network id of the network. - - """ - ssid = network[WifiEnums.SSID_KEY] - wutils.start_wifi_connection_scan_and_ensure_network_found(self.dut, - ssid) - wutils.wifi_connect_by_id(self.dut, net_id) - - def run_ping(self, sec): - """Run ping for given number of seconds. - - Args: - sec: Time in seconds to run teh ping traffic. - - """ - self.log.info("Running ping for %d seconds" % sec) - result = self.dut.adb.shell("ping -w %d %s" %(sec, PING_ADDR), - timeout=sec+1) - self.log.debug("Ping Result = %s" % result) - if "100% packet loss" in result: - raise signals.TestFailure("100% packet loss during ping") - - def start_youtube_video(self, url=None, secs=60): - """Start a youtube video and check if it's playing. - - Args: - url: The URL of the youtube video to play. - secs: Time to play video in seconds. - - """ - ad = self.dut - ad.log.info("Start a youtube video") - ad.ensure_screen_on() - video_played = False - for count in range(2): - ad.unlock_screen() - ad.adb.shell('am start -a android.intent.action.VIEW -d "%s"' % url) - if tutils.wait_for_state(ad.droid.audioIsMusicActive, True, 15, 1): - ad.log.info("Started a video in youtube.") - # Play video for given seconds. - time.sleep(secs) - video_played = True - break - if not video_played: - raise signals.TestFailure("Youtube video did not start. Current WiFi " - "state is %d" % self.dut.droid.wifiCheckState()) - - def add_networks(self, ad, networks): - """Add Wi-Fi networks to an Android device and verify the networks were - added correctly. - - Args: - ad: the AndroidDevice object to add networks to. - networks: a list of dicts, each dict represents a Wi-Fi network. - """ - for network in networks: - ret = ad.droid.wifiAddNetwork(network) - asserts.assert_true(ret != -1, "Failed to add network %s" % - network) - ad.droid.wifiEnableNetwork(ret, 0) - configured_networks = ad.droid.wifiGetConfiguredNetworks() - self.log.debug("Configured networks: %s", configured_networks) - - 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 SSID. - - Args: - 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 network selection from %s to %s", - connection_info[WifiEnums.SSID_KEY], - expected_con[WifiEnums.SSID_KEY]) - 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_and_return_status(self.dut) - self.log.info("Wait 60s for network selection.") - time.sleep(60) - try: - 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 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) - - """Tests""" - - @test_tracker_info(uuid="cd0016c6-58cf-4361-b551-821c0b8d2554") - def test_stress_toggle_wifi_state(self): - """Toggle WiFi state ON and OFF for N times.""" - for count in range(self.stress_count): - """Test toggling wifi""" - try: - self.log.debug("Going from on to off.") - wutils.wifi_toggle_state(self.dut, False) - self.log.debug("Going from off to on.") - startTime = time.time() - wutils.wifi_toggle_state(self.dut, True) - startup_time = time.time() - startTime - self.log.debug("WiFi was enabled on the device in %s s." % - startup_time) - except: - signals.TestFailure(details="", extras={"Iterations":"%d" % - self.stress_count, "Pass":"%d" %count}) - raise signals.TestPass(details="", extras={"Iterations":"%d" % - self.stress_count, "Pass":"%d" %(count+1)}) - - @test_tracker_info(uuid="4e591cec-9251-4d52-bc6e-6621507524dc") - def test_stress_toggle_wifi_state_bluetooth_on(self): - """Toggle WiFi state ON and OFF for N times when bluetooth ON.""" - enable_bluetooth(self.dut.droid, self.dut.ed) - for count in range(self.stress_count): - """Test toggling wifi""" - try: - self.log.debug("Going from on to off.") - wutils.wifi_toggle_state(self.dut, False) - self.log.debug("Going from off to on.") - startTime = time.time() - wutils.wifi_toggle_state(self.dut, True) - startup_time = time.time() - startTime - self.log.debug("WiFi was enabled on the device in %s s." % - startup_time) - except: - signals.TestFailure(details="", extras={"Iterations":"%d" % - self.stress_count, "Pass":"%d" %count}) - disable_bluetooth(self.dut.droid) - raise signals.TestPass(details="", extras={"Iterations":"%d" % - self.stress_count, "Pass":"%d" %(count+1)}) - - @test_tracker_info(uuid="49e3916a-9580-4bf7-a60d-a0f2545dcdde") - def test_stress_connect_traffic_disconnect_5g(self): - """Test to connect and disconnect from a network for N times. - - Steps: - 1. Scan and connect to a network. - 2. Run IPerf to upload data for few seconds. - 3. Disconnect. - 4. Repeat 1-3. - - """ - for count in range(self.stress_count): - try: - net_id = self.dut.droid.wifiAddNetwork(self.wpa_5g) - asserts.assert_true(net_id != -1, "Add network %r failed" % self.wpa_5g) - self.scan_and_connect_by_id(self.wpa_5g, net_id) - # Start IPerf traffic from phone to server. - # Upload data for 10s. - args = "-p {} -t {}".format(self.iperf_server_port, 10) - self.log.info("Running iperf client {}".format(args)) - result, data = self.dut.run_iperf_client(self.iperf_server_address, args) - if not result: - self.log.debug("Error occurred in iPerf traffic.") - self.run_ping(10) - wutils.wifi_forget_network(self.dut,self.wpa_5g[WifiEnums.SSID_KEY]) - time.sleep(WAIT_BEFORE_CONNECTION) - except: - raise signals.TestFailure("Network connect-disconnect failed." - "Look at logs", extras={"Iterations":"%d" % - self.stress_count, "Pass":"%d" %count}) - raise signals.TestPass(details="", extras={"Iterations":"%d" % - self.stress_count, "Pass":"%d" %(count+1)}) - - @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. - - 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.scan_and_connect_by_ssid(self.dut, self.wpa_5g) - self.scan_and_connect_by_ssid(self.dut_client, self.wpa_5g) - - 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() - dl.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_youtube_5g(self): - """Test to connect to 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. - - """ - # 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=RK1K2bCg4J8"] - try: - self.scan_and_connect_by_ssid(self.dut, 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}) - - @test_tracker_info(uuid="d367c83e-5b00-4028-9ed8-f7b875997d13") - def test_stress_wifi_failover(self): - """This test does aggressive failover to several networks in list. - - Steps: - 1. Add and enable few networks. - 2. Let device auto-connect. - 3. Remove the connected network. - 4. Repeat 2-3. - 5. Device should connect to a network until all networks are - exhausted. - - """ - for count in range(int(self.stress_count/4)): - wutils.reset_wifi(self.dut) - ssids = list() - for network in self.networks: - ssids.append(network[WifiEnums.SSID_KEY]) - ret = self.dut.droid.wifiAddNetwork(network) - asserts.assert_true(ret != -1, "Add network %r failed" % network) - self.dut.droid.wifiEnableNetwork(ret, 0) - self.dut.droid.wifiStartScan() - time.sleep(WAIT_FOR_AUTO_CONNECT) - cur_network = self.dut.droid.wifiGetConnectionInfo() - cur_ssid = cur_network[WifiEnums.SSID_KEY] - self.log.info("Cur_ssid = %s" % cur_ssid) - for i in range(0,len(self.networks)): - self.log.debug("Forget network %s" % cur_ssid) - wutils.wifi_forget_network(self.dut, cur_ssid) - time.sleep(WAIT_FOR_AUTO_CONNECT) - cur_network = self.dut.droid.wifiGetConnectionInfo() - cur_ssid = cur_network[WifiEnums.SSID_KEY] - self.log.info("Cur_ssid = %s" % cur_ssid) - if i == len(self.networks) - 1: - break - if cur_ssid not in ssids: - raise signals.TestFailure("Device did not failover to the " - "expected network. SSID = %s" % cur_ssid) - network_config = self.dut.droid.wifiGetConfiguredNetworks() - self.log.info("Network Config = %s" % network_config) - if len(network_config): - raise signals.TestFailure("All the network configurations were not " - "removed. Configured networks = %s" % network_config, - extras={"Iterations":"%d" % self.stress_count, - "Pass":"%d" %(count*4)}) - raise signals.TestPass(details="", extras={"Iterations":"%d" % - self.stress_count, "Pass":"%d" %((count+1)*4)}) - - @test_tracker_info(uuid="2c19e8d1-ac16-4d7e-b309-795144e6b956") - def test_stress_softAP_startup_and_stop_5g(self): - """Test to bring up softAP and down for N times. - - Steps: - 1. Bring up softAP on 5G. - 2. Check for softAP on teh client device. - 3. Turn ON WiFi. - 4. Verify softAP is turned down and WiFi is up. - - """ - ap_ssid = "softap_" + utils.rand_ascii_str(8) - ap_password = utils.rand_ascii_str(8) - self.dut.log.info("softap setup: %s %s", ap_ssid, ap_password) - config = {wutils.WifiEnums.SSID_KEY: ap_ssid} - config[wutils.WifiEnums.PWD_KEY] = ap_password - # Set country code explicitly to "US". - wutils.set_wifi_country_code(self.dut, wutils.WifiEnums.CountryCode.US) - wutils.set_wifi_country_code(self.dut_client, wutils.WifiEnums.CountryCode.US) - for count in range(self.stress_count): - initial_wifi_state = self.dut.droid.wifiCheckState() - wutils.start_wifi_tethering(self.dut, - ap_ssid, - ap_password, - WifiEnums.WIFI_CONFIG_APBAND_5G) - wutils.start_wifi_connection_scan_and_ensure_network_found( - self.dut_client, ap_ssid) - wutils.stop_wifi_tethering(self.dut) - asserts.assert_false(self.dut.droid.wifiIsApEnabled(), - "SoftAp failed to shutdown!") - # Give some time for WiFi to come back to previous state. - time.sleep(2) - cur_wifi_state = self.dut.droid.wifiCheckState() - if initial_wifi_state != cur_wifi_state: - raise signals.TestFailure("Wifi state was %d before softAP and %d now!" % - (initial_wifi_state, cur_wifi_state), - extras={"Iterations":"%d" % self.stress_count, - "Pass":"%d" %count}) - raise signals.TestPass(details="", extras={"Iterations":"%d" % - self.stress_count, "Pass":"%d" %(count+1)}) - - @test_tracker_info(uuid="eb22e26b-95d1-4580-8c76-85dfe6a42a0f") - def test_stress_wifi_roaming(self): - 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(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, - AP1_network, AP2_network) - try: - wutils.trigger_roaming_and_validate(self.dut, self.attenuators, - "AP1_off_AP2_on", AP2_network) - self.log.info("Roaming iteration %d, from %s to %s", count, - AP2_network, AP1_network) - wutils.trigger_roaming_and_validate(self.dut, self.attenuators, - "AP1_on_AP2_off", AP1_network) - except: - raise signals.TestFailure("Roaming failed. Look at logs", - extras={"Iterations":"%d" %self.stress_count, "Pass":"%d" % - (count*2)}) - raise signals.TestPass(details="", extras={"Iterations":"%d" % - self.stress_count, "Pass":"%d" %((count+1)*2)}) - - @test_tracker_info(uuid="e8ae8cd2-c315-4c08-9eb3-83db65b78a58") - def test_stress_network_selector_2G_connection(self): - """ - 1. Add one saved 2G network to DUT. - 2. Move the DUT in range. - 3. Verify the DUT is connected to the network. - 4. Move the DUT out of range - 5. Repeat step 2-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) - for count in range(self.stress_count): - 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)}) - - @test_tracker_info(uuid="5d5d14cb-3cd1-4b3d-8c04-0d6f4b764b6b") - def test_stress_pno_connection_to_2g(self): - """Test PNO triggered autoconnect to a network for N times - - Steps: - 1. Save 2Ghz valid network configuration in the device. - 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.connect_and_verify_connected_ssid(self.reference_networks[0]['2g'], is_pno=True) - wutils.wifi_forget_network( - self.dut, networks[0][WifiEnums.SSID_KEY]) - # move the DUT out of range - self.attenuators[0].set_atten(95) - time.sleep(10) - self.add_networks(self.dut, networks) - wutils.set_attns(self.attenuators, "default") - raise signals.TestPass(details="", extras={"Iterations":"%d" % - self.stress_count, "Pass":"%d" %(count+1)}) diff --git a/acts/tests/google/wifi/WifiTeleCoexTest.py b/acts/tests/google/wifi/WifiTeleCoexTest.py deleted file mode 100644 index 6d5fef8708..0000000000 --- a/acts/tests/google/wifi/WifiTeleCoexTest.py +++ /dev/null @@ -1,310 +0,0 @@ -#!/usr/bin/env python3.4 - -import queue -import time - -import acts.base_test -import acts.test_utils.wifi.wifi_test_utils as wifi_utils -import acts.test_utils.tel.tel_test_utils as tele_utils -import acts.utils - -from acts import asserts -from acts import signals -from acts.test_decorators import test_tracker_info -from acts.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest -from acts.test_utils.tel.tel_voice_utils import phone_setup_voice_general -from acts.test_utils.tel.tel_voice_utils import two_phone_call_short_seq - -WifiEnums = wifi_utils.WifiEnums - -ATTENUATORS = "attenuators" -WIFI_SSID = "wifi_network_ssid" -WIFI_PWD = "wifi_network_pass" -STRESS_COUNT = "stress_iteration" - -class WifiTeleCoexTest(TelephonyBaseTest): - """Tests for WiFi, Celular Co-existance.""" - - - def setup_class(self): - TelephonyBaseTest.setup_class(self) - - self.dut = self.android_devices[0] - wifi_utils.wifi_test_device_init(self.dut) - # Set attenuation to 0 on all channels. - if getattr(self, ATTENUATORS, []): - for a in self.attenuators: - a.set_atten(0) - self.ads = self.android_devices - self.dut = self.android_devices[0] - self.wifi_network_ssid = self.user_params.get(WIFI_SSID) - self.wifi_network_pass = self.user_params.get(WIFI_PWD) - self.network = { WifiEnums.SSID_KEY : self.wifi_network_ssid, - WifiEnums.PWD_KEY : self.wifi_network_pass - } - self.stress_count = self.user_params.get(STRESS_COUNT) - - - def setup_test(self): - wifi_utils.wifi_toggle_state(self.dut, True) - - - def teardown_test(self): - wifi_utils.reset_wifi(self.dut) - - - """Helper Functions""" - - - def connect_to_wifi(self, ad, network): - """Connection logic for open and psk wifi networks. - - Args: - ad: Android device object. - network: A JSON dict of the WiFi network configuration. - - """ - ad.ed.clear_all_events() - wifi_utils.start_wifi_connection_scan(ad) - scan_results = ad.droid.wifiGetScanResults() - wifi_utils.assert_network_in_list({WifiEnums.SSID_KEY: - self.wifi_network_ssid}, scan_results) - wifi_utils.wifi_connect(ad, network) - self.log.debug("Connected to %s network on %s device" % ( - network[WifiEnums.SSID_KEY], ad.serial)) - - - def stress_toggle_wifi(self, stress_count): - """Toggle WiFi in a loop. - - Args: - stress_count: Number of times to toggle WiFi OFF and ON. - - """ - for count in range(stress_count): - self.log.debug("stress_toggle_wifi: Iteration %d" % count) - wifi_utils.toggle_wifi_off_and_on(self.dut) - - if not self.dut.droid.wifiGetisWifiEnabled(): - raise signals.TestFailure("WiFi did not turn on after toggling it" - " %d times" % self.stress_count) - - - def stress_toggle_airplane(self, stress_count): - """Toggle Airplane mode in a loop. - - Args: - stress_count: Number of times to toggle Airplane mode OFF and ON. - - """ - for count in range(stress_count): - self.log.debug("stress_toggle_airplane: Iteration %d" % count) - wifi_utils.toggle_airplane_mode_on_and_off(self.dut) - - if not self.dut.droid.wifiGetisWifiEnabled(): - raise signals.TestFailure("WiFi did not turn on after toggling it" - " %d times" % self.stress_count) - - - def stress_toggle_airplane_and_wifi(self, stress_count): - """Toggle Airplane and WiFi modes in a loop. - - Args: - stress_count: Number of times to perform Airplane mode ON, WiFi ON, - Airplane mode OFF, in a sequence. - - """ - for count in range(stress_count): - self.log.debug("stress_toggle_airplane_and_wifi: Iteration %d" % count) - self.log.debug("Toggling Airplane mode ON") - asserts.assert_true( - acts.utils.force_airplane_mode(self.dut, True), - "Can not turn on airplane mode on: %s" % self.dut.serial) - # Sleep for atleast 500ms so that, call to enable wifi is not deferred. - time.sleep(1) - self.log.debug("Toggling wifi ON") - wifi_utils.wifi_toggle_state(self.dut, True) - # Sleep for 1s before getting new WiFi state. - time.sleep(1) - if not self.dut.droid.wifiGetisWifiEnabled(): - raise signals.TestFailure("WiFi did not turn on after turning ON" - " Airplane mode") - asserts.assert_true( - acts.utils.force_airplane_mode(self.dut, False), - "Can not turn on airplane mode on: %s" % self.dut.serial) - - if not self.dut.droid.wifiGetisWifiEnabled(): - raise signals.TestFailure("WiFi did not turn on after toggling it" - " %d times" % self.stress_count) - - - def setup_cellular_voice_calling(self): - """Setup phone for voice general calling and make sure phone is - attached to voice.""" - # Make sure Phone A and B are attached to voice network. - for ad in self.ads: - if not phone_setup_voice_general(self.log, ad): - raise signals.TestFailure("Phone failed to setup for voice" - " calling serial:%s" % ad.serial) - self.log.debug("Finished setting up phones for voice calling") - - - def validate_cellular_and_wifi(self): - """Validate WiFi, make some cellular calls. - - Steps: - 1. Check if device is still connected to the WiFi network. - 2. If WiFi looks good, check if deivce is attached to voice. - 3. Make a short sequence voice call between Phone A and B. - - """ - # Sleep for 30s before getting new WiFi state. - time.sleep(30) - wifi_info = self.dut.droid.wifiGetConnectionInfo() - if wifi_info[WifiEnums.SSID_KEY] != self.wifi_network_ssid: - raise signals.TestFailure("Phone failed to connect to %s network on" - " %s" % (self.wifi_network_ssid, - self.dut.serial)) - - # Make short call sequence between Phone A and Phone B. - two_phone_call_short_seq(self.log, self.ads[0], None, None, self.ads[1], - None, None) - - """Tests""" - - - @test_tracker_info(uuid="8b9b6fb9-964b-43e7-b75f-675774ee346f") - @TelephonyBaseTest.tel_test_wrap - def test_toggle_wifi_call(self): - """Test to toggle WiFi and then perform WiFi connection and - cellular calls. - - Steps: - 1. Attach device to voice subscription network. - 2. Connect to a WiFi network. - 3. Toggle WiFi OFF and ON. - 4. Verify device auto-connects to the WiFi network. - 5. Verify device is attached to voice network. - 6. Make short sequence voice calls. - - """ - self.setup_cellular_voice_calling() - self.connect_to_wifi(self.dut, self.network) - wifi_utils.toggle_wifi_off_and_on(self.dut) - self.validate_cellular_and_wifi() - return True - - - @test_tracker_info(uuid="caf22447-6354-4a2e-99e5-0ff235fc8f20") - @TelephonyBaseTest.tel_test_wrap - def test_toggle_airplane_call(self): - """Test to toggle Airplane mode and perform WiFi connection and - cellular calls. - - Steps: - 1. Attach device to voice subscription network. - 2. Connect to a WiFi network. - 3. Toggle Airplane mode OFF and ON. - 4. Verify device auto-connects to the WiFi network. - 5. Verify device is attached to voice network. - 6. Make short sequence voice calls. - - """ - self.setup_cellular_voice_calling() - self.connect_to_wifi(self.dut, self.network) - wifi_utils.toggle_airplane_mode_on_and_off(self.dut) - self.validate_cellular_and_wifi() - return True - - - @test_tracker_info(uuid="dd888b35-f820-409a-89af-4b0f6551e4d6") - @TelephonyBaseTest.tel_test_wrap - def test_toggle_airplane_and_wifi_call(self): - """Test to toggle WiFi in a loop and perform WiFi connection and - cellular calls. - - Steps: - 1. Attach device to voice subscription network. - 2. Connect to a WiFi network. - 3. Toggle Airplane mode ON. - 4. Turn WiFi ON. - 5. Toggle Airplane mode OFF. - 3. Verify device auto-connects to the WiFi network. - 4. Verify device is attached to voice network. - 5. Make short sequence voice calls. - - """ - self.setup_cellular_voice_calling() - self.connect_to_wifi(self.dut, self.network) - self.stress_toggle_airplane_and_wifi(1) - self.validate_cellular_and_wifi() - return True - - - @test_tracker_info(uuid="15db5b7e-827e-4bc8-8e77-7fcce343a323") - @TelephonyBaseTest.tel_test_wrap - def test_stress_toggle_wifi_call(self): - """Stress test to toggle WiFi in a loop, then perform WiFi connection - and cellular calls. - - Steps: - 1. Attach device to voice subscription network. - 2. Connect to a WiFi network. - 3. Toggle WiFi OFF and ON in a loop. - 4. Verify device auto-connects to the WiFi network. - 5. Verify device is attached to voice network. - 6. Make short sequence voice calls. - - """ - self.setup_cellular_voice_calling() - self.connect_to_wifi(self.dut, self.network) - self.stress_toggle_wifi(self.stress_count) - self.validate_cellular_and_wifi() - return True - - - @test_tracker_info(uuid="80a2f1bf-5e41-453a-9b8e-be3b41d4d313") - @TelephonyBaseTest.tel_test_wrap - def test_stress_toggle_airplane_call(self): - """Stress test to toggle Airplane mode in a loop, then perform WiFi and - cellular calls. - - Steps: - 1. Attach device to voice subscription network. - 2. Connect to a WiFi network. - 3. Toggle Airplane mode OFF and ON in a loop. - 4. Verify device auto-connects to the WiFi network. - 5. Verify device is attached to voice network. - 6. Make short sequence voice calls. - - """ - self.setup_cellular_voice_calling() - self.connect_to_wifi(self.dut, self.network) - self.stress_toggle_airplane(self.stress_count) - self.validate_cellular_and_wifi() - return True - - - @test_tracker_info(uuid="b88ad3e7-6462-4280-ad57-22d0ac91fdd8") - @TelephonyBaseTest.tel_test_wrap - def test_stress_toggle_airplane_and_wifi_call(self): - """Stress test to toggle Airplane and WiFi mode in a loop, then perform - WiFi connection and cellular calls. - - Steps: - 1. Attach device to voice subscription network. - 2. Connect to a WiFi network. - 3. Toggle Airplane mode ON. - 4. Turn WiFi ON. - 5. Toggle Airplane mode OFF. - 6. Repeat 3, 4 & 5, in a loop. - 7. Verify device auto-connects to the WiFi network. - 8. Verify device is attached to voice network. - 9. Make short sequence voice calls. - - """ - self.setup_cellular_voice_calling() - self.connect_to_wifi(self.dut, self.network) - self.stress_toggle_airplane_and_wifi(self.stress_count) - self.validate_cellular_and_wifi() - return True diff --git a/acts/tests/google/wifi/WifiTethering2GOpenOTATest.py b/acts/tests/google/wifi/WifiTethering2GOpenOTATest.py deleted file mode 100755 index 0716158327..0000000000 --- a/acts/tests/google/wifi/WifiTethering2GOpenOTATest.py +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2018 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import acts.signals as signals - -from acts import asserts -from acts.base_test import BaseTestClass -from acts.libs.ota import ota_updater -from acts.test_decorators import test_tracker_info -from acts.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_2G - -import acts.test_utils.net.net_test_utils as nutils -import acts.test_utils.wifi.wifi_test_utils as wutils - - -class WifiTethering2GOpenOTATest(BaseTestClass): - """Wifi Tethering 2G Open OTA tests""" - - def setup_class(self): - - super(WifiTethering2GOpenOTATest, self).setup_class() - ota_updater.initialize(self.user_params, self.android_devices) - - self.hotspot_device = self.android_devices[0] - self.tethered_device = self.android_devices[1] - req_params = ("wifi_hotspot_open", ) - self.unpack_userparams(req_params) - - # verify hotspot device has lte data and supports tethering - nutils.verify_lte_data_and_tethering_supported(self.hotspot_device) - - # Save a wifi soft ap configuration and verify that it works - wutils.save_wifi_soft_ap_config(self.hotspot_device, - self.wifi_hotspot_open, - WIFI_CONFIG_APBAND_2G) - self._verify_wifi_tethering() - - # Run OTA below, if ota fails then abort all tests. - try: - ota_updater.update(self.hotspot_device) - except Exception as err: - raise signals.TestAbortClass( - "Failed up apply OTA update. Aborting tests") - - def on_fail(self, test_name, begin_time): - for ad in self.android_devices: - ad.take_bug_report(test_name, begin_time) - - def teardown_class(self): - wutils.wifi_toggle_state(self.hotspot_device, True) - - """Helper Functions""" - - def _verify_wifi_tethering(self): - """Verify wifi tethering""" - wutils.start_wifi_tethering_saved_config(self.hotspot_device) - wutils.wifi_connect(self.tethered_device, self.wifi_hotspot_open) - # (TODO: @gmoturu) Change to stop_wifi_tethering. See b/109876061 - wutils.wifi_toggle_state(self.hotspot_device, True) - - """Tests""" - - @test_tracker_info(uuid="fe502bc3-f9c6-4bed-98ad-acaa7e166521") - def test_wifi_tethering_ota_2g_open(self): - """ Verify wifi hotspot after ota upgrade - - Steps: - 1. Save a wifi hotspot config with 2g band and open auth - 2. Do a OTA update - 3. Verify that wifi hotspot works with teh saved config - """ - self._verify_wifi_tethering() diff --git a/acts/tests/google/wifi/WifiTethering2GPskOTATest.py b/acts/tests/google/wifi/WifiTethering2GPskOTATest.py deleted file mode 100755 index 7399e32879..0000000000 --- a/acts/tests/google/wifi/WifiTethering2GPskOTATest.py +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2018 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import acts.signals as signals - -from acts import asserts -from acts.base_test import BaseTestClass -from acts.libs.ota import ota_updater -from acts.test_decorators import test_tracker_info -from acts.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_2G - -import acts.test_utils.net.net_test_utils as nutils -import acts.test_utils.wifi.wifi_test_utils as wutils - - -class WifiTethering2GPskOTATest(BaseTestClass): - """Wifi Tethering 2G Psk OTA tests""" - - def setup_class(self): - - super(WifiTethering2GPskOTATest, self).setup_class() - ota_updater.initialize(self.user_params, self.android_devices) - - self.hotspot_device = self.android_devices[0] - self.tethered_device = self.android_devices[1] - req_params = ("wifi_hotspot_psk", ) - self.unpack_userparams(req_params) - - # verify hotspot device has lte data and supports tethering - nutils.verify_lte_data_and_tethering_supported(self.hotspot_device) - - # Save a wifi soft ap configuration and verify that it works - wutils.save_wifi_soft_ap_config(self.hotspot_device, - self.wifi_hotspot_psk, - WIFI_CONFIG_APBAND_2G) - self._verify_wifi_tethering() - - # Run OTA below, if ota fails then abort all tests. - try: - ota_updater.update(self.hotspot_device) - except Exception as err: - raise signals.TestAbortClass( - "Failed up apply OTA update. Aborting tests") - - def on_fail(self, test_name, begin_time): - for ad in self.android_devices: - ad.take_bug_report(test_name, begin_time) - - def teardown_class(self): - wutils.wifi_toggle_state(self.hotspot_device, True) - - """Helper Functions""" - - def _verify_wifi_tethering(self): - """Verify wifi tethering""" - wutils.start_wifi_tethering_saved_config(self.hotspot_device) - wutils.wifi_connect(self.tethered_device, self.wifi_hotspot_psk) - # (TODO: @gmoturu) Change to stop_wifi_tethering. See b/109876061 - wutils.wifi_toggle_state(self.hotspot_device, True) - - """Tests""" - - @test_tracker_info(uuid="4b1cec63-d1d2-4046-84e9-e806bb08ce41") - def test_wifi_tethering_ota_2g_psk(self): - """ Verify wifi hotspot after ota upgrade - - Steps: - 1. Save a wifi hotspot config with 2g band and psk auth - 2. Do a OTA update - 3. Verify that wifi hotspot works with teh saved config - """ - self._verify_wifi_tethering() diff --git a/acts/tests/google/wifi/WifiTethering5GOpenOTATest.py b/acts/tests/google/wifi/WifiTethering5GOpenOTATest.py deleted file mode 100755 index 985e7a759a..0000000000 --- a/acts/tests/google/wifi/WifiTethering5GOpenOTATest.py +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2018 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import acts.signals as signals - -from acts import asserts -from acts.base_test import BaseTestClass -from acts.libs.ota import ota_updater -from acts.test_decorators import test_tracker_info -from acts.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_5G - -import acts.test_utils.net.net_test_utils as nutils -import acts.test_utils.wifi.wifi_test_utils as wutils - - -class WifiTethering5GOpenOTATest(BaseTestClass): - """Wifi Tethering 5G Open OTA tests""" - - def setup_class(self): - - super(WifiTethering5GOpenOTATest, self).setup_class() - ota_updater.initialize(self.user_params, self.android_devices) - - self.hotspot_device = self.android_devices[0] - self.tethered_device = self.android_devices[1] - req_params = ("wifi_hotspot_open", ) - self.unpack_userparams(req_params) - - # verify hotspot device has lte data and supports tethering - nutils.verify_lte_data_and_tethering_supported(self.hotspot_device) - - # Save a wifi soft ap configuration and verify that it works - wutils.save_wifi_soft_ap_config(self.hotspot_device, - self.wifi_hotspot_open, - WIFI_CONFIG_APBAND_5G) - self._verify_wifi_tethering() - - # Run OTA below, if ota fails then abort all tests. - try: - ota_updater.update(self.hotspot_device) - except Exception as err: - raise signals.TestAbortClass( - "Failed up apply OTA update. Aborting tests") - - def on_fail(self, test_name, begin_time): - for ad in self.android_devices: - ad.take_bug_report(test_name, begin_time) - - def teardown_class(self): - wutils.wifi_toggle_state(self.hotspot_device, True) - - """Helper Functions""" - - def _verify_wifi_tethering(self): - """Verify wifi tethering""" - wutils.start_wifi_tethering_saved_config(self.hotspot_device) - wutils.wifi_connect(self.tethered_device, self.wifi_hotspot_open) - # (TODO: @gmoturu) Change to stop_wifi_tethering. See b/109876061 - wutils.wifi_toggle_state(self.hotspot_device, True) - - """Tests""" - - @test_tracker_info(uuid="b1a94c8f-f3ed-4755-be4a-764e205b4483") - def test_wifi_tethering_ota_5g_open(self): - """ Verify wifi hotspot after ota upgrade - - Steps: - 1. Save a wifi hotspot config with 5g band and open auth - 2. Do a OTA update - 3. Verify that wifi hotspot works with teh saved config - """ - self._verify_wifi_tethering() diff --git a/acts/tests/google/wifi/WifiTethering5GPskOTATest.py b/acts/tests/google/wifi/WifiTethering5GPskOTATest.py deleted file mode 100755 index 9e68f2200a..0000000000 --- a/acts/tests/google/wifi/WifiTethering5GPskOTATest.py +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2018 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import acts.signals as signals - -from acts import asserts -from acts.base_test import BaseTestClass -from acts.libs.ota import ota_updater -from acts.test_decorators import test_tracker_info -from acts.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_5G - -import acts.test_utils.net.net_test_utils as nutils -import acts.test_utils.wifi.wifi_test_utils as wutils - - -class WifiTethering5GPskOTATest(BaseTestClass): - """Wifi Tethering 5G Psk OTA tests""" - - def setup_class(self): - - super(WifiTethering5GPskOTATest, self).setup_class() - ota_updater.initialize(self.user_params, self.android_devices) - - self.hotspot_device = self.android_devices[0] - self.tethered_device = self.android_devices[1] - req_params = ("wifi_hotspot_psk", ) - self.unpack_userparams(req_params) - - # verify hotspot device has lte data and supports tethering - nutils.verify_lte_data_and_tethering_supported(self.hotspot_device) - - # Save a wifi soft ap configuration and verify that it works - wutils.save_wifi_soft_ap_config(self.hotspot_device, - self.wifi_hotspot_psk, - WIFI_CONFIG_APBAND_5G) - self._verify_wifi_tethering() - - # Run OTA below, if ota fails then abort all tests. - try: - ota_updater.update(self.hotspot_device) - except Exception as err: - raise signals.TestAbortClass( - "Failed up apply OTA update. Aborting tests") - - def on_fail(self, test_name, begin_time): - for ad in self.android_devices: - ad.take_bug_report(test_name, begin_time) - - def teardown_class(self): - wutils.wifi_toggle_state(self.hotspot_device, True) - - """Helper Functions""" - - def _verify_wifi_tethering(self): - """Verify wifi tethering""" - wutils.start_wifi_tethering_saved_config(self.hotspot_device) - wutils.wifi_connect(self.tethered_device, self.wifi_hotspot_psk) - # (TODO: @gmoturu) Change to stop_wifi_tethering. See b/109876061 - wutils.wifi_toggle_state(self.hotspot_device, True) - - """Tests""" - - @test_tracker_info(uuid="111d3a33-3152-4993-b1ba-307daaf2a6ff") - def test_wifi_tethering_ota_5g_psk(self): - """ Verify wifi hotspot after ota upgrade - - Steps: - 1. Save a wifi hotspot config with 5g band and psk auth - 2. Do a OTA update - 3. Verify that wifi hotspot works with teh saved config - """ - self._verify_wifi_tethering() diff --git a/acts/tests/google/wifi/WifiTetheringPowerTest.py b/acts/tests/google/wifi/WifiTetheringPowerTest.py deleted file mode 100644 index dd3cf7435f..0000000000 --- a/acts/tests/google/wifi/WifiTetheringPowerTest.py +++ /dev/null @@ -1,266 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import os -import threading -import time - -from acts import base_test -from acts import asserts -from acts.controllers import adb -from acts.controllers import monsoon -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi import wifi_test_utils as wutils -from acts.test_utils.tel import tel_data_utils as tel_utils -from acts.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_2G -from acts.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_5G -from acts.test_utils.tel.tel_test_utils import http_file_download_by_chrome -from acts.utils import force_airplane_mode -from acts.utils import set_adaptive_brightness -from acts.utils import set_ambient_display -from acts.utils import set_auto_rotate -from acts.utils import set_location_service - - -class WifiTetheringPowerTest(base_test.BaseTestClass): - - def setup_class(self): - self.hotspot_device = self.android_devices[0] - self.tethered_devices = self.android_devices[1:] - req_params = ("ssid", "password", "url") - self.unpack_userparams(req_params) - self.network = { "SSID": self.ssid, "password": self.password } - - self.offset = 1 * 60 - self.hz = 5000 - self.duration = 9 * 60 + self.offset - self.mon_data_path = os.path.join(self.log_path, "Monsoon") - self.mon = self.monsoons[0] - self.mon.set_voltage(4.2) - self.mon.set_max_current(7.8) - self.mon.attach_device(self.hotspot_device) - - asserts.assert_true(self.mon.usb("auto"), - "Failed to turn USB mode to auto on monsoon.") - set_location_service(self.hotspot_device, False) - set_adaptive_brightness(self.hotspot_device, False) - set_ambient_display(self.hotspot_device, False) - self.hotspot_device.adb.shell("settings put system screen_brightness 0") - set_auto_rotate(self.hotspot_device, False) - wutils.wifi_toggle_state(self.hotspot_device, False) - self.hotspot_device.droid.telephonyToggleDataConnection(True) - tel_utils.wait_for_cell_data_connection(self.log, self.hotspot_device, True) - asserts.assert_true( - tel_utils.verify_http_connection(self.log, self.hotspot_device), - "HTTP verification failed on cell data connection") - for ad in self.tethered_devices: - wutils.reset_wifi(ad) - - def teardown_class(self): - self.mon.usb("on") - wutils.wifi_toggle_state(self.hotspot_device, True) - - def on_fail(self, test_name, begin_time): - self.hotspot_device.take_bug_report(test_name, begin_time) - - def on_pass(self, test_name, begin_time): - self.hotspot_device.take_bug_report(test_name, begin_time) - - """ Helper functions """ - def _measure_and_process_result(self): - """ Measure the current drawn by the device for the period of - self.duration, at the frequency of self.hz. - """ - tag = self.current_test_name - result = self.mon.measure_power(self.hz, - self.duration, - tag=tag, - offset=self.offset) - asserts.assert_true(result, - "Got empty measurement data set in %s." % tag) - self.log.info(repr(result)) - data_path = os.path.join(self.mon_data_path, "%s.txt" % tag) - monsoon.MonsoonData.save_to_text_file([result], data_path) - actual_current = result.average_current - actual_current_str = "%.2fmA" % actual_current - result_extra = {"Average Current": actual_current_str} - - def _start_wifi_tethering(self, wifi_band): - """ Start wifi tethering on hotspot device - - Args: - 1. wifi_band: specifies the wifi band to start the hotspot - on. The current options are 2G and 5G - """ - wutils.start_wifi_tethering(self.hotspot_device, - self.ssid, - self.password, - wifi_band) - - def _start_traffic_on_device(self, ad): - """ Start traffic on the device by downloading data - Run the traffic continuosly for self.duration - - Args: - 1. ad device object - """ - timeout = time.time() + self.duration - while True: - if time.time() > timeout: - break - http_file_download_by_chrome(ad, self.url) - - def _start_traffic_measure_power(self, ad_list): - """ Start traffic on the tethered devices and measure power - - Args: - 1. ad_list: list of tethered devices to run traffic on - """ - threads = [] - for ad in ad_list: - t = threading.Thread(target = self._start_traffic_on_device, - args = (ad,)) - t.start() - threads.append(t) - try: - self._measure_and_process_result() - finally: - for t in threads: - t.join() - - - """ Tests begin """ - @test_tracker_info(uuid="ebb74144-e22a-46e1-b8c1-9ada22b13133") - def test_power_wifi_tethering_2ghz_no_devices_connected(self): - """ Steps: - 1. Start wifi hotspot with 2.4Ghz band - 2. No devices connected to hotspot - 3. Measure power - """ - self._start_wifi_tethering(WIFI_CONFIG_APBAND_2G) - self._measure_and_process_result() - wutils.stop_wifi_tethering(self.hotspot_device) - - @test_tracker_info(uuid="2560c088-4010-4354-ade3-6aaac83b1cfd") - def test_power_wifi_tethering_5ghz_no_devices_connected(self): - """ Steps: - 1. Start wifi hotspot with 5Ghz band - 2. No devices connected to hotspot - 3. Measure power - """ - self._start_wifi_tethering(WIFI_CONFIG_APBAND_5G) - self._measure_and_process_result() - wutils.stop_wifi_tethering(self.hotspot_device) - - @test_tracker_info(uuid="644795b0-cd30-4a8f-82ee-cc0618c41c6b") - def test_power_wifi_tethering_2ghz_connect_1device(self): - """ Steps: - 1. Start wifi hotspot with 2.4GHz band - 2. Connect 1 device to hotspot - 3. Measure power - """ - self._start_wifi_tethering(WIFI_CONFIG_APBAND_2G) - wutils.wifi_connect(self.tethered_devices[0], self.network) - self._measure_and_process_result() - wutils.stop_wifi_tethering(self.hotspot_device) - - @test_tracker_info(uuid="8fca9898-f493-44c3-810f-d2262ac72187") - def test_power_wifi_tethering_5ghz_connect_1device(self): - """ Steps: - 1. Start wifi hotspot with 5GHz band - 2. Connect 1 device to hotspot - 3. Measure power - """ - self._start_wifi_tethering(WIFI_CONFIG_APBAND_5G) - wutils.wifi_connect(self.tethered_devices[0], self.network) - self._measure_and_process_result() - wutils.stop_wifi_tethering(self.hotspot_device) - - @test_tracker_info(uuid="16ef5f63-1a7a-44ae-bf8d-c3a181c89b63") - def test_power_wifi_tethering_2ghz_connect_5devices(self): - """ Steps: - 1. Start wifi hotspot with 2GHz band - 2. Connect 5 devices to hotspot - 3. Measure power - """ - self._start_wifi_tethering(WIFI_CONFIG_APBAND_2G) - for ad in self.tethered_devices: - wutils.wifi_connect(ad, self.network) - self._measure_and_process_result() - wutils.stop_wifi_tethering(self.hotspot_device) - - @test_tracker_info(uuid="769aedfc-d309-40e0-95dd-51ff40f4e097") - def test_power_wifi_tethering_5ghz_connect_5devices(self): - """ Steps: - 1. Start wifi hotspot with 5GHz band - 2. Connect 5 devices to hotspot - 3. Measure power - """ - self._start_wifi_tethering(WIFI_CONFIG_APBAND_5G) - for ad in self.tethered_devices: - wutils.wifi_connect(ad, self.network) - self._measure_and_process_result() - wutils.stop_wifi_tethering(self.hotspot_device) - - @test_tracker_info(uuid="e5b71f34-1dc0-4045-a45e-48c1e9426ec3") - def test_power_wifi_tethering_2ghz_connect_1device_with_traffic(self): - """ Steps: - 1. Start wifi hotspot with 2GHz band - 2. Connect 1 device to hotspot device - 3. Start traffic and measure power - """ - self._start_wifi_tethering(WIFI_CONFIG_APBAND_2G) - wutils.wifi_connect(self.tethered_devices[0], self.network) - self._start_traffic_measure_power(self.tethered_devices[0:1]) - wutils.stop_wifi_tethering(self.hotspot_device) - - @test_tracker_info(uuid="29c5cd6e-8df1-46e5-a735-526dc9154f6e") - def test_power_wifi_tethering_5ghz_connect_1device_with_traffic(self): - """ Steps: - 1. Start wifi hotspot with 5GHz band - 2. Connect 1 device to hotspot device - 3. Start traffic and measure power - """ - self._start_wifi_tethering(WIFI_CONFIG_APBAND_5G) - wutils.wifi_connect(self.tethered_devices[0], self.network) - self._start_traffic_measure_power(self.tethered_devices[0:1]) - wutils.stop_wifi_tethering(self.hotspot_device) - - @test_tracker_info(uuid="da71b06f-7b98-4c14-a2e2-361f395b39a8") - def test_power_wifi_tethering_2ghz_connect_5devices_with_traffic(self): - """ Steps: - 1. Start wifi hotspot with 2GHz band - 2. Connect 5 devices to hotspot device - 3. Start traffic and measure power - """ - self._start_wifi_tethering(WIFI_CONFIG_APBAND_2G) - for ad in self.tethered_devices: - wutils.wifi_connect(ad, self.network) - self._start_traffic_measure_power(self.tethered_devices) - wutils.stop_wifi_tethering(self.hotspot_device) - - @test_tracker_info(uuid="7f3173ab-fd8f-4579-8c45-f9a8c5cd17f7") - def test_power_wifi_tethering_5ghz_connect_5devices_with_traffic(self): - """ Steps: - 1. Start wifi hotspot with 2GHz band - 2. Connect 5 devices to hotspot device - 3. Start traffic and measure power - """ - self._start_wifi_tethering(WIFI_CONFIG_APBAND_5G) - for ad in self.tethered_devices: - wutils.wifi_connect(ad, self.network) - self._start_traffic_measure_power(self.tethered_devices) - wutils.stop_wifi_tethering(self.hotspot_device) diff --git a/acts/tests/google/wifi/WifiTetheringTest.py b/acts/tests/google/wifi/WifiTetheringTest.py deleted file mode 100644 index d5d197a0a6..0000000000 --- a/acts/tests/google/wifi/WifiTetheringTest.py +++ /dev/null @@ -1,596 +0,0 @@ -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import logging -import random -import socket -import time - -from acts import asserts -from acts import base_test -from acts import test_runner -from acts import utils -from acts.controllers import adb -from acts.test_decorators import test_tracker_info -from acts.test_utils.tel import tel_defines -from acts.test_utils.tel.tel_data_utils import wait_for_cell_data_connection -from acts.test_utils.tel.tel_test_utils import get_operator_name -from acts.test_utils.tel.tel_test_utils import verify_http_connection -from acts.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_2G -from acts.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_5G -from acts.test_utils.net import socket_test_utils as sutils -from acts.test_utils.net import arduino_test_utils as dutils -from acts.test_utils.net import net_test_utils as nutils -from acts.test_utils.wifi import wifi_test_utils as wutils - -WAIT_TIME = 5 - -class WifiTetheringTest(base_test.BaseTestClass): - """ Tests for Wifi Tethering """ - - def setup_class(self): - """ Setup devices for tethering and unpack params """ - - self.hotspot_device = self.android_devices[0] - self.tethered_devices = self.android_devices[1:] - req_params = ("url", "open_network") - self.unpack_userparams(req_params) - self.network = {"SSID": "hotspot_%s" % utils.rand_ascii_str(6), - "password": "pass_%s" % utils.rand_ascii_str(6)} - self.new_ssid = "wifi_tethering_test2" - self.tcpdump_pid=[] - - nutils.verify_lte_data_and_tethering_supported(self.hotspot_device) - for ad in self.tethered_devices: - wutils.wifi_test_device_init(ad) - - def setup_test(self): - for ad in self.android_devices: - self.tcpdump_pid.append(nutils.start_tcpdump(ad, self.test_name)) - - def teardown_test(self): - if self.hotspot_device.droid.wifiIsApEnabled(): - wutils.stop_wifi_tethering(self.hotspot_device) - for ad, pid in zip(self.android_devices, self.tcpdump_pid): - nutils.stop_tcpdump(ad, pid, self.test_name) - self.tcpdump_pid = [] - - - def teardown_class(self): - """ Reset devices """ - for ad in self.tethered_devices: - wutils.reset_wifi(ad) - - def on_fail(self, test_name, begin_time): - """ Collect bug report on failure """ - for ad in self.android_devices: - ad.take_bug_report(test_name, begin_time) - - """ Helper functions """ - - def _is_ipaddress_ipv6(self, ip_address): - """ Verify if the given string is a valid IPv6 address - - Args: - 1. string which contains the IP address - - Returns: - True: if valid ipv6 address - False: if not - """ - try: - socket.inet_pton(socket.AF_INET6, ip_address) - return True - except socket.error: - return False - - def _supports_ipv6_tethering(self, dut): - """ Check if provider supports IPv6 tethering. - Currently, only Verizon supports IPv6 tethering - - Returns: - True: if provider supports IPv6 tethering - False: if not - """ - # Currently only Verizon support IPv6 tethering - carrier_supports_tethering = ["vzw", "tmo", "Far EasTone", "Chunghwa Telecom"] - operator = get_operator_name(self.log, dut) - return operator in carrier_supports_tethering - - def _carrier_supports_ipv6(self,dut): - """ Verify if carrier supports ipv6 - Currently, only verizon and t-mobile supports IPv6 - - Returns: - True: if carrier supports ipv6 - False: if not - """ - carrier_supports_ipv6 = ["vzw", "tmo", "Far EasTone", "Chunghwa Telecom"] - operator = get_operator_name(self.log, dut) - self.log.info("Carrier is %s" % operator) - return operator in carrier_supports_ipv6 - - def _verify_ipv6_tethering(self, dut): - """ Verify IPv6 tethering """ - http_response = dut.droid.httpRequestString(self.url) - self.log.info("IP address %s " % http_response) - active_link_addrs = dut.droid.connectivityGetAllAddressesOfActiveLink() - if dut==self.hotspot_device and self._carrier_supports_ipv6(dut)\ - or self._supports_ipv6_tethering(self.hotspot_device): - asserts.assert_true(self._is_ipaddress_ipv6(http_response), - "The http response did not return IPv6 address") - asserts.assert_true( - active_link_addrs and http_response in str(active_link_addrs), - "Could not find IPv6 address in link properties") - asserts.assert_true( - dut.droid.connectivityHasIPv6DefaultRoute(), - "Could not find IPv6 default route in link properties") - else: - asserts.assert_true( - not dut.droid.connectivityHasIPv6DefaultRoute(), - "Found IPv6 default route in link properties") - - def _start_wifi_tethering(self, wifi_band=WIFI_CONFIG_APBAND_2G): - """ Start wifi tethering on hotspot device - - Args: - 1. wifi_band: specifies the wifi band to start the hotspot - on. The current options are 2G and 5G - """ - wutils.start_wifi_tethering(self.hotspot_device, - self.network[wutils.WifiEnums.SSID_KEY], - self.network[wutils.WifiEnums.PWD_KEY], - wifi_band) - - def _connect_disconnect_devices(self): - """ Randomly connect and disconnect devices from the - self.tethered_devices list to hotspot device - """ - device_connected = [ False ] * len(self.tethered_devices) - for _ in range(50): - dut_id = random.randint(0, len(self.tethered_devices)-1) - dut = self.tethered_devices[dut_id] - # wait for 1 sec between connect & disconnect stress test - time.sleep(1) - if device_connected[dut_id]: - wutils.wifi_forget_network(dut, self.network["SSID"]) - else: - wutils.wifi_connect(dut, self.network) - device_connected[dut_id] = not device_connected[dut_id] - - def _connect_disconnect_android_device(self, dut_id, wifi_state): - """ Connect or disconnect wifi on android device depending on the - current wifi state - - Args: - 1. dut_id: tethered device to change the wifi state - 2. wifi_state: current wifi state - """ - ad = self.tethered_devices[dut_id] - if wifi_state: - self.log.info("Disconnecting wifi on android device") - wutils.wifi_forget_network(ad, self.network["SSID"]) - else: - self.log.info("Connecting to wifi on android device") - wutils.wifi_connect(ad, self.network) - - def _connect_disconnect_wifi_dongle(self, dut_id, wifi_state): - """ Connect or disconnect wifi on wifi dongle depending on the - current wifi state - - Args: - 1. dut_id: wifi dongle to change the wifi state - 2. wifi_state: current wifi state - """ - wd = self.arduino_wifi_dongles[dut_id] - if wifi_state: - self.log.info("Disconnecting wifi on dongle") - dutils.disconnect_wifi(wd) - else: - self.log.info("Connecting to wifi on dongle") - dutils.connect_wifi(wd, self.network) - - def _connect_disconnect_tethered_devices(self): - """ Connect disconnect tethered devices to wifi hotspot """ - num_android_devices = len(self.tethered_devices) - num_wifi_dongles = 0 - if hasattr(self, 'arduino_wifi_dongles'): - num_wifi_dongles = len(self.arduino_wifi_dongles) - total_devices = num_android_devices + num_wifi_dongles - device_connected = [False] * total_devices - for _ in range(50): - dut_id = random.randint(0, total_devices-1) - wifi_state = device_connected[dut_id] - if dut_id < num_android_devices: - self._connect_disconnect_android_device(dut_id, wifi_state) - else: - self._connect_disconnect_wifi_dongle(dut_id-num_android_devices, - wifi_state) - device_connected[dut_id] = not device_connected[dut_id] - - def _verify_ping(self, dut, ip, isIPv6=False): - """ Verify ping works from the dut to IP/hostname - - Args: - 1. dut - ad object to check ping from - 2. ip - ip/hostname to ping (IPv4 and IPv6) - - Returns: - True - if ping is successful - False - if not - """ - self.log.info("Pinging %s from dut %s" % (ip, dut.serial)) - if isIPv6 or self._is_ipaddress_ipv6(ip): - return dut.droid.pingHost(ip, 5, "ping6") - return dut.droid.pingHost(ip) - - def _return_ip_for_interface(self, dut, iface_name): - """ Return list of IP addresses for an interface - - Args: - 1. dut - ad object - 2. iface_name - interface name - - Returns: - List of IPv4 and IPv6 addresses - """ - return dut.droid.connectivityGetIPv4Addresses(iface_name) + \ - dut.droid.connectivityGetIPv6Addresses(iface_name) - - def _test_traffic_between_two_tethered_devices(self, ad, wd): - """ Verify pinging interfaces of one DUT from another - - Args: - 1. ad - android device - 2. wd - wifi dongle - """ - wutils.wifi_connect(ad, self.network) - dutils.connect_wifi(wd, self.network) - local_ip = ad.droid.connectivityGetIPv4Addresses('wlan0')[0] - remote_ip = wd.ip_address() - port = 8888 - - time.sleep(6) # wait until UDP packets method is invoked - socket = sutils.open_datagram_socket(ad, local_ip, port) - sutils.send_recv_data_datagram_sockets( - ad, ad, socket, socket, remote_ip, port) - sutils.close_datagram_socket(ad, socket) - - def _ping_hotspot_interfaces_from_tethered_device(self, dut): - """ Ping hotspot interfaces from tethered device - - Args: - 1. dut - tethered device - - Returns: - True - if all IP addresses are pingable - False - if not - """ - ifaces = self.hotspot_device.droid.connectivityGetNetworkInterfaces() - return_result = True - for interface in ifaces: - iface_name = interface.split()[0].split(':')[1] - if iface_name == "lo": - continue - ip_list = self._return_ip_for_interface( - self.hotspot_device, iface_name) - for ip in ip_list: - ping_result = self._verify_ping(dut, ip) - self.log.info("Ping result: %s %s %s" % - (iface_name, ip, ping_result)) - return_result = return_result and ping_result - - return return_result - - def _save_wifi_softap_configuration(self, ad, config): - """ Save soft AP configuration - - Args: - 1. dut - device to save configuration on - 2. config - soft ap configuration - """ - asserts.assert_true(ad.droid.wifiSetWifiApConfiguration(config), - "Failed to set WifiAp Configuration") - wifi_ap = ad.droid.wifiGetApConfiguration() - asserts.assert_true(wifi_ap[wutils.WifiEnums.SSID_KEY] == config[wutils.WifiEnums.SSID_KEY], - "Configured wifi hotspot SSID does not match with the expected SSID") - - def _turn_on_wifi_hotspot(self, ad): - """ Turn on wifi hotspot with a config that is already saved - - Args: - 1. dut - device to turn wifi hotspot on - """ - ad.droid.wifiStartTrackingTetherStateChange() - ad.droid.connectivityStartTethering(tel_defines.TETHERING_WIFI, False) - try: - ad.ed.pop_event("ConnectivityManagerOnTetheringStarted") - ad.ed.wait_for_event("TetherStateChanged", - lambda x: x["data"]["ACTIVE_TETHER"], 30) - except: - asserts.fail("Didn't receive wifi tethering starting confirmation") - ad.droid.wifiStopTrackingTetherStateChange() - - """ Test Cases """ - - @test_tracker_info(uuid="36d03295-bea3-446e-8342-b9f8f1962a32") - def test_ipv6_tethering(self): - """ IPv6 tethering test - - Steps: - 1. Start wifi tethering on hotspot device - 2. Verify IPv6 address on hotspot device (VZW & TMO only) - 3. Connect tethered device to hotspot device - 4. Verify IPv6 address on the client's link properties (VZW only) - 5. Verify ping on client using ping6 which should pass (VZW only) - 6. Disable mobile data on provider and verify that link properties - does not have IPv6 address and default route (VZW only) - """ - # Start wifi tethering on the hotspot device - wutils.toggle_wifi_off_and_on(self.hotspot_device) - self._start_wifi_tethering() - - # Verify link properties on hotspot device - self.log.info("Check IPv6 properties on the hotspot device. " - "Verizon & T-mobile should have IPv6 in link properties") - self._verify_ipv6_tethering(self.hotspot_device) - - # Connect the client to the SSID - wutils.wifi_connect(self.tethered_devices[0], self.network) - - # Need to wait atleast 2 seconds for IPv6 address to - # show up in the link properties - time.sleep(WAIT_TIME) - - # Verify link properties on tethered device - self.log.info("Check IPv6 properties on the tethered device. " - "Device should have IPv6 if carrier is Verizon") - self._verify_ipv6_tethering(self.tethered_devices[0]) - - # Verify ping6 on tethered device - ping_result = self._verify_ping(self.tethered_devices[0], - wutils.DEFAULT_PING_ADDR, True) - if self._supports_ipv6_tethering(self.hotspot_device): - asserts.assert_true(ping_result, "Ping6 failed on the client") - else: - asserts.assert_true(not ping_result, "Ping6 failed as expected") - - # Disable mobile data on hotspot device - # and verify the link properties on tethered device - self.log.info("Disabling mobile data to verify ipv6 default route") - self.hotspot_device.droid.telephonyToggleDataConnection(False) - asserts.assert_equal( - self.hotspot_device.droid.telephonyGetDataConnectionState(), - tel_defines.DATA_STATE_CONNECTED, - "Could not disable cell data") - - time.sleep(WAIT_TIME) # wait until the IPv6 is removed from link properties - - result = self.tethered_devices[0].droid.connectivityHasIPv6DefaultRoute() - self.hotspot_device.droid.telephonyToggleDataConnection(True) - if result: - asserts.fail("Found IPv6 default route in link properties:Data off") - self.log.info("Did not find IPv6 address in link properties") - - # Disable wifi tethering - wutils.stop_wifi_tethering(self.hotspot_device) - - @test_tracker_info(uuid="110b61d1-8af2-4589-8413-11beac7a3025") - def test_wifi_tethering_2ghz_traffic_between_2tethered_devices(self): - """ Steps: - - 1. Start wifi hotspot with 2G band - 2. Connect 2 tethered devices to the hotspot device - 3. Ping interfaces between the tethered devices - """ - asserts.skip_if(not hasattr(self, 'arduino_wifi_dongles'), - "No wifi dongles connected. Skipping test") - wutils.toggle_wifi_off_and_on(self.hotspot_device) - self._start_wifi_tethering(WIFI_CONFIG_APBAND_2G) - self._test_traffic_between_two_tethered_devices(self.tethered_devices[0], - self.arduino_wifi_dongles[0]) - wutils.stop_wifi_tethering(self.hotspot_device) - - @test_tracker_info(uuid="953f6e2e-27bd-4b73-85a6-d2eaa4e755d5") - def wifi_tethering_5ghz_traffic_between_2tethered_devices(self): - """ Steps: - - 1. Start wifi hotspot with 5ghz band - 2. Connect 2 tethered devices to the hotspot device - 3. Send traffic between the tethered devices - """ - wutils.toggle_wifi_off_and_on(self.hotspot_device) - self._start_wifi_tethering(WIFI_CONFIG_APBAND_5G) - self._test_traffic_between_two_tethered_devices(self.tethered_devices[0], - self.arduino_wifi_dongles[0]) - wutils.stop_wifi_tethering(self.hotspot_device) - - @test_tracker_info(uuid="d7d5aa51-682d-4882-a334-61966d93b68c") - def test_wifi_tethering_2ghz_connect_disconnect_devices(self): - """ Steps: - - 1. Start wifi hotspot with 2ghz band - 2. Connect and disconnect multiple devices randomly - 3. Verify the correct functionality - """ - wutils.toggle_wifi_off_and_on(self.hotspot_device) - self._start_wifi_tethering(WIFI_CONFIG_APBAND_2G) - self._connect_disconnect_tethered_devices() - wutils.stop_wifi_tethering(self.hotspot_device) - - @test_tracker_info(uuid="34abd6c9-c7f1-4d89-aa2b-a66aeabed9aa") - def test_wifi_tethering_5ghz_connect_disconnect_devices(self): - """ Steps: - - 1. Start wifi hotspot with 5ghz band - 2. Connect and disconnect multiple devices randomly - 3. Verify the correct functionality - """ - wutils.toggle_wifi_off_and_on(self.hotspot_device) - self._start_wifi_tethering(WIFI_CONFIG_APBAND_5G) - self._connect_disconnect_devices() - wutils.stop_wifi_tethering(self.hotspot_device) - - @test_tracker_info(uuid="7edfb220-37f8-42ea-8d7c-39712fbe9be5") - def test_wifi_tethering_2ghz_ping_hotspot_interfaces(self): - """ Steps: - - 1. Start wifi hotspot with 2ghz band - 2. Connect tethered device to hotspot device - 3. Ping 'wlan0' and 'rmnet_data' interface's IPv4 - and IPv6 interfaces on hotspot device from tethered device - """ - wutils.toggle_wifi_off_and_on(self.hotspot_device) - self._start_wifi_tethering(WIFI_CONFIG_APBAND_2G) - wutils.wifi_connect(self.tethered_devices[0], self.network) - result = self._ping_hotspot_interfaces_from_tethered_device( - self.tethered_devices[0]) - wutils.stop_wifi_tethering(self.hotspot_device) - return result - - @test_tracker_info(uuid="17e450f4-795f-4e67-adab-984940dffedc") - def test_wifi_tethering_5ghz_ping_hotspot_interfaces(self): - """ Steps: - - 1. Start wifi hotspot with 5ghz band - 2. Connect tethered device to hotspot device - 3. Ping 'wlan0' and 'rmnet_data' interface's IPv4 - and IPv6 interfaces on hotspot device from tethered device - """ - wutils.toggle_wifi_off_and_on(self.hotspot_device) - self._start_wifi_tethering(WIFI_CONFIG_APBAND_5G) - wutils.wifi_connect(self.tethered_devices[0], self.network) - result = self._ping_hotspot_interfaces_from_tethered_device( - self.tethered_devices[0]) - wutils.stop_wifi_tethering(self.hotspot_device) - return result - - @test_tracker_info(uuid="2bc344cb-0277-4f06-b6cc-65b3972086ed") - def test_change_wifi_hotspot_ssid_when_hotspot_enabled(self): - """ Steps: - - 1. Start wifi tethering - 2. Verify wifi Ap configuration - 3. Change the SSID of the wifi hotspot while hotspot is on - 4. Verify the new SSID in wifi ap configuration - 5. Restart tethering and verify that the tethered device is able - to connect to the new SSID - """ - wutils.toggle_wifi_off_and_on(self.hotspot_device) - dut = self.hotspot_device - - # start tethering and verify the wifi ap configuration settings - self._start_wifi_tethering() - wifi_ap = dut.droid.wifiGetApConfiguration() - asserts.assert_true( - wifi_ap[wutils.WifiEnums.SSID_KEY] == \ - self.network[wutils.WifiEnums.SSID_KEY], - "Configured wifi hotspot SSID did not match with the expected SSID") - wutils.wifi_connect(self.tethered_devices[0], self.network) - - # update the wifi ap configuration with new ssid - config = {wutils.WifiEnums.SSID_KEY: self.new_ssid} - config[wutils.WifiEnums.PWD_KEY] = self.network[wutils.WifiEnums.PWD_KEY] - config[wutils.WifiEnums.APBAND_KEY] = WIFI_CONFIG_APBAND_2G - self._save_wifi_softap_configuration(dut, config) - - # start wifi tethering with new wifi ap configuration - wutils.stop_wifi_tethering(dut) - self._turn_on_wifi_hotspot(dut) - - # verify dut can connect to new wifi ap configuration - new_network = {wutils.WifiEnums.SSID_KEY: self.new_ssid, - wutils.WifiEnums.PWD_KEY: \ - self.network[wutils.WifiEnums.PWD_KEY]} - wutils.wifi_connect(self.tethered_devices[0], new_network) - wutils.stop_wifi_tethering(self.hotspot_device) - - @test_tracker_info(uuid="4cf7ab26-ca2d-46f6-9d3f-a935c7e04c97") - def test_wifi_tethering_open_network_2g(self): - """ Steps: - - 1. Start wifi tethering with open network 2G band - (Not allowed manually. b/72412729) - 2. Connect tethered device to the SSID - 3. Verify internet connectivity - """ - wutils.start_wifi_tethering( - self.hotspot_device, self.open_network[wutils.WifiEnums.SSID_KEY], - None, WIFI_CONFIG_APBAND_2G) - wutils.wifi_connect(self.tethered_devices[0], self.open_network) - wutils.stop_wifi_tethering(self.hotspot_device) - - @test_tracker_info(uuid="f407049b-1324-40ea-a8d1-f90587933310") - def test_wifi_tethering_open_network_5g(self): - """ Steps: - - 1. Start wifi tethering with open network 5G band - (Not allowed manually. b/72412729) - 2. Connect tethered device to the SSID - 3. Verify internet connectivity - """ - wutils.start_wifi_tethering( - self.hotspot_device, self.open_network[wutils.WifiEnums.SSID_KEY], - None, WIFI_CONFIG_APBAND_5G) - wutils.wifi_connect(self.tethered_devices[0], self.open_network) - wutils.stop_wifi_tethering(self.hotspot_device) - - @test_tracker_info(uuid="d964f2e6-0acb-417c-ada9-eb9fc5a470e4") - def test_wifi_tethering_open_network_2g_stress(self): - """ Steps: - - 1. Save wifi hotspot configuration with open network 2G band - (Not allowed manually. b/72412729) - 2. Turn on wifi hotspot - 3. Connect tethered device and verify internet connectivity - 4. Turn off wifi hotspot - 5. Repeat steps 2 to 4 - """ - # save open network wifi ap configuration with 2G band - config = {wutils.WifiEnums.SSID_KEY: - self.open_network[wutils.WifiEnums.SSID_KEY]} - config[wutils.WifiEnums.APBAND_KEY] = WIFI_CONFIG_APBAND_2G - self._save_wifi_softap_configuration(self.hotspot_device, config) - - # turn on/off wifi hotspot, connect device - for _ in range(9): - self._turn_on_wifi_hotspot(self.hotspot_device) - wutils.connect_to_wifi_network(self.tethered_devices[0], self.open_network) - wutils.stop_wifi_tethering(self.hotspot_device) - time.sleep(1) # wait for some time before turning on hotspot - - @test_tracker_info(uuid="c7ef840c-4003-41fc-80e3-755f9057b542") - def test_wifi_tethering_open_network_5g_stress(self): - """ Steps: - - 1. Save wifi hotspot configuration with open network 5G band - (Not allowed manually. b/72412729) - 2. Turn on wifi hotspot - 3. Connect tethered device and verify internet connectivity - 4. Turn off wifi hotspot - 5. Repeat steps 2 to 4 - """ - # save open network wifi ap configuration with 5G band - config = {wutils.WifiEnums.SSID_KEY: - self.open_network[wutils.WifiEnums.SSID_KEY]} - config[wutils.WifiEnums.APBAND_KEY] = WIFI_CONFIG_APBAND_5G - self._save_wifi_softap_configuration(self.hotspot_device, config) - - # turn on/off wifi hotspot, connect device - for _ in range(9): - self._turn_on_wifi_hotspot(self.hotspot_device) - wutils.connect_to_wifi_network(self.tethered_devices[0], self.open_network) - wutils.stop_wifi_tethering(self.hotspot_device) - time.sleep(1) # wait for some time before turning on hotspot diff --git a/acts/tests/google/wifi/WifiThroughputStabilityTest.py b/acts/tests/google/wifi/WifiThroughputStabilityTest.py deleted file mode 100644 index 7e2c3ef38a..0000000000 --- a/acts/tests/google/wifi/WifiThroughputStabilityTest.py +++ /dev/null @@ -1,613 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the 'License'); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an 'AS IS' BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import collections -import itertools -import json -import logging -import numpy -import os -import time -from acts import asserts -from acts import base_test -from acts import context -from acts import utils -from acts.controllers import iperf_server as ipf -from acts.controllers.utils_lib import ssh -from acts.metrics.loggers.blackbox import BlackboxMappedMetricLogger -from acts.test_utils.wifi import ota_chamber -from acts.test_utils.wifi import wifi_performance_test_utils as wputils -from acts.test_utils.wifi import wifi_retail_ap as retail_ap -from acts.test_utils.wifi import wifi_test_utils as wutils -from functools import partial - -TEST_TIMEOUT = 10 -SHORT_SLEEP = 1 -MED_SLEEP = 6 - - -class WifiThroughputStabilityTest(base_test.BaseTestClass): - """Class to test WiFi throughput stability. - - This class tests throughput stability and identifies cases where throughput - fluctuates over time. The class setups up the AP, configures and connects - the phone, and runs iperf throughput test at several attenuations For an - example config file to run this test class see - example_connectivity_performance_ap_sta.json. - """ - def __init__(self, controllers): - base_test.BaseTestClass.__init__(self, controllers) - # Define metrics to be uploaded to BlackBox - self.testcase_metric_logger = ( - BlackboxMappedMetricLogger.for_test_case()) - self.testclass_metric_logger = ( - BlackboxMappedMetricLogger.for_test_class()) - self.publish_testcase_metrics = True - # Generate test cases - self.tests = self.generate_test_cases([6, 36, 149], - ['VHT20', 'VHT40', 'VHT80'], - ['TCP', 'UDP'], ['DL', 'UL'], - ['high', 'low']) - - def generate_test_cases(self, channels, modes, traffic_types, - traffic_directions, signal_levels): - """Function that auto-generates test cases for a test class.""" - allowed_configs = { - 'VHT20': [ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 149, 153, - 157, 161 - ], - 'VHT40': [36, 44, 149, 157], - 'VHT80': [36, 149] - } - test_cases = [] - for channel, mode, signal_level, traffic_type, traffic_direction in itertools.product( - channels, - modes, - signal_levels, - traffic_types, - traffic_directions, - ): - if channel not in allowed_configs[mode]: - continue - testcase_params = collections.OrderedDict( - channel=channel, - mode=mode, - traffic_type=traffic_type, - traffic_direction=traffic_direction, - signal_level=signal_level) - testcase_name = ('test_tput_stability' - '_{}_{}_{}_ch{}_{}'.format( - signal_level, traffic_type, traffic_direction, - channel, mode)) - setattr(self, testcase_name, - partial(self._test_throughput_stability, testcase_params)) - test_cases.append(testcase_name) - return test_cases - - def setup_class(self): - self.dut = self.android_devices[0] - req_params = [ - 'throughput_stability_test_params', 'testbed_params', - 'main_network', 'RetailAccessPoints', 'RemoteServer' - ] - self.unpack_userparams(req_params) - self.testclass_params = self.throughput_stability_test_params - self.num_atten = self.attenuators[0].instrument.num_atten - self.remote_server = ssh.connection.SshConnection( - ssh.settings.from_config(self.RemoteServer[0]['ssh_config'])) - self.iperf_server = self.iperf_servers[0] - self.iperf_client = self.iperf_clients[0] - self.access_point = retail_ap.create(self.RetailAccessPoints)[0] - self.log_path = os.path.join(logging.log_path, 'test_results') - os.makedirs(self.log_path, exist_ok=True) - self.log.info('Access Point Configuration: {}'.format( - self.access_point.ap_settings)) - self.ref_attenuations = {} - self.testclass_results = [] - - # Turn WiFi ON - if self.testclass_params.get('airplane_mode', 1): - self.log.info('Turning on airplane mode.') - asserts.assert_true(utils.force_airplane_mode(self.dut, True), - "Can not turn on airplane mode.") - wutils.wifi_toggle_state(self.dut, True) - - def teardown_test(self): - self.iperf_server.stop() - - def pass_fail_check(self, test_result_dict): - """Check the test result and decide if it passed or failed. - - Checks the throughput stability test's PASS/FAIL criteria based on - minimum instantaneous throughput, and standard deviation. - - Args: - test_result_dict: dict containing attenuation, throughput and other - meta data - """ - avg_throughput = test_result_dict['iperf_results']['avg_throughput'] - min_throughput = test_result_dict['iperf_results']['min_throughput'] - std_dev_percent = ( - test_result_dict['iperf_results']['std_deviation'] / - test_result_dict['iperf_results']['avg_throughput']) * 100 - # Set blackbox metrics - if self.publish_testcase_metrics: - self.testcase_metric_logger.add_metric('avg_throughput', - avg_throughput) - self.testcase_metric_logger.add_metric('min_throughput', - min_throughput) - self.testcase_metric_logger.add_metric('std_dev_percent', - std_dev_percent) - # Evaluate pass/fail - min_throughput_check = ( - (min_throughput / avg_throughput) * - 100) > self.testclass_params['min_throughput_threshold'] - std_deviation_check = std_dev_percent < self.testclass_params[ - 'std_deviation_threshold'] - - test_message = ( - 'Atten: {0:.2f}dB, RSSI: {1:.2f}dB. ' - 'Throughput (Mean: {2:.2f}, Std. Dev:{3:.2f}%, Min: {4:.2f} Mbps).' - 'LLStats : {5}'.format(test_result_dict['attenuation'], - test_result_dict['rssi'], avg_throughput, - std_dev_percent, min_throughput, - test_result_dict['llstats'])) - if min_throughput_check and std_deviation_check: - asserts.explicit_pass('Test Passed.' + test_message) - asserts.fail('Test Failed. ' + test_message) - - def post_process_results(self, test_result): - """Extracts results and saves plots and JSON formatted results. - - Args: - test_result: dict containing attenuation, iPerfResult object and - other meta data - Returns: - test_result_dict: dict containing post-processed results including - avg throughput, other metrics, and other meta data - """ - # Save output as text file - test_name = self.current_test_name - results_file_path = os.path.join(self.log_path, - '{}.txt'.format(test_name)) - test_result_dict = {} - test_result_dict['ap_settings'] = test_result['ap_settings'].copy() - test_result_dict['attenuation'] = test_result['attenuation'] - test_result_dict['rssi'] = test_result['rssi_result'][ - 'signal_poll_rssi']['mean'] - test_result_dict['llstats'] = ( - 'TX MCS = {0} ({1:.1f}%). ' - 'RX MCS = {2} ({3:.1f}%)'.format( - test_result['llstats']['summary']['common_tx_mcs'], - test_result['llstats']['summary']['common_tx_mcs_freq'] * 100, - test_result['llstats']['summary']['common_rx_mcs'], - test_result['llstats']['summary']['common_rx_mcs_freq'] * 100)) - if test_result['iperf_result'].instantaneous_rates: - instantaneous_rates_Mbps = [ - rate * 8 * (1.024**2) - for rate in test_result['iperf_result'].instantaneous_rates[ - self.testclass_params['iperf_ignored_interval']:-1] - ] - tput_standard_deviation = test_result[ - 'iperf_result'].get_std_deviation( - self.testclass_params['iperf_ignored_interval']) * 8 - else: - instantaneous_rates_Mbps = float('nan') - tput_standard_deviation = float('nan') - test_result_dict['iperf_results'] = { - 'instantaneous_rates': instantaneous_rates_Mbps, - 'avg_throughput': numpy.mean(instantaneous_rates_Mbps), - 'std_deviation': tput_standard_deviation, - 'min_throughput': min(instantaneous_rates_Mbps) - } - with open(results_file_path, 'w') as results_file: - json.dump(test_result_dict, results_file) - # Plot and save - figure = wputils.BokehFigure(test_name, - x_label='Time (s)', - primary_y_label='Throughput (Mbps)') - time_data = list(range(0, len(instantaneous_rates_Mbps))) - figure.add_line(time_data, - instantaneous_rates_Mbps, - legend=self.current_test_name, - marker='circle') - output_file_path = os.path.join(self.log_path, - '{}.html'.format(test_name)) - figure.generate_figure(output_file_path) - return test_result_dict - - def setup_ap(self, testcase_params): - """Sets up the access point in the configuration required by the test. - - Args: - testcase_params: dict containing AP and other test params - """ - band = self.access_point.band_lookup_by_channel( - testcase_params['channel']) - if '2G' in band: - frequency = wutils.WifiEnums.channel_2G_to_freq[ - testcase_params['channel']] - else: - frequency = wutils.WifiEnums.channel_5G_to_freq[ - testcase_params['channel']] - if frequency in wutils.WifiEnums.DFS_5G_FREQUENCIES: - self.access_point.set_region(self.testbed_params['DFS_region']) - else: - self.access_point.set_region(self.testbed_params['default_region']) - self.access_point.set_channel(band, testcase_params['channel']) - self.access_point.set_bandwidth(band, testcase_params['mode']) - self.log.info('Access Point Configuration: {}'.format( - self.access_point.ap_settings)) - - def setup_dut(self, testcase_params): - """Sets up the DUT in the configuration required by the test. - - Args: - testcase_params: dict containing AP and other test params - """ - # Check battery level before test - if not wputils.health_check(self.dut, 10): - asserts.skip('Battery level too low. Skipping test.') - # Turn screen off to preserve battery - self.dut.go_to_sleep() - band = self.access_point.band_lookup_by_channel( - testcase_params['channel']) - if wputils.validate_network(self.dut, - testcase_params['test_network']['SSID']): - self.log.info('Already connected to desired network') - else: - wutils.wifi_toggle_state(self.dut, True) - wutils.reset_wifi(self.dut) - wutils.set_wifi_country_code(self.dut, - self.testclass_params['country_code']) - self.main_network[band]['channel'] = testcase_params['channel'] - wutils.wifi_connect(self.dut, - testcase_params['test_network'], - num_of_tries=5, - check_connectivity=False) - self.dut_ip = self.dut.droid.connectivityGetIPv4Addresses('wlan0')[0] - - def setup_throughput_stability_test(self, testcase_params): - """Function that gets devices ready for the test. - - Args: - testcase_params: dict containing test-specific parameters - """ - # Configure AP - self.setup_ap(testcase_params) - # Reset, configure, and connect DUT - self.setup_dut(testcase_params) - # Wait before running the first wifi test - first_test_delay = self.testclass_params.get('first_test_delay', 600) - if first_test_delay > 0 and len(self.testclass_results) == 0: - self.log.info('Waiting before the first test.') - time.sleep(first_test_delay) - self.setup_dut(testcase_params) - # Get and set attenuation levels for test - testcase_params['atten_level'] = self.get_target_atten(testcase_params) - self.log.info('Setting attenuation to {} dB'.format( - testcase_params['atten_level'])) - for attenuator in self.attenuators: - attenuator.set_atten(testcase_params['atten_level']) - # Configure iperf - if isinstance(self.iperf_server, ipf.IPerfServerOverAdb): - testcase_params['iperf_server_address'] = self.dut_ip - else: - testcase_params[ - 'iperf_server_address'] = wputils.get_server_address( - self.remote_server, self.dut_ip, '255.255.255.0') - - def run_throughput_stability_test(self, testcase_params): - """Main function to test throughput stability. - - The function sets up the AP in the correct channel and mode - configuration and runs an iperf test to measure throughput. - - Args: - testcase_params: dict containing test specific parameters - Returns: - test_result: dict containing test result and meta data - """ - # Run test and log result - # Start iperf session - self.log.info('Starting iperf test.') - llstats_obj = wputils.LinkLayerStats(self.dut) - llstats_obj.update_stats() - self.iperf_server.start(tag=str(testcase_params['atten_level'])) - current_rssi = wputils.get_connected_rssi_nb( - dut=self.dut, - num_measurements=self.testclass_params['iperf_duration'] - 1, - polling_frequency=1, - first_measurement_delay=1, - disconnect_warning=1, - ignore_samples=1) - client_output_path = self.iperf_client.start( - testcase_params['iperf_server_address'], - testcase_params['iperf_args'], str(testcase_params['atten_level']), - self.testclass_params['iperf_duration'] + TEST_TIMEOUT) - current_rssi = current_rssi.result() - server_output_path = self.iperf_server.stop() - # Set attenuator to 0 dB - for attenuator in self.attenuators: - attenuator.set_atten(0) - # Parse and log result - if testcase_params['use_client_output']: - iperf_file = client_output_path - else: - iperf_file = server_output_path - try: - iperf_result = ipf.IPerfResult(iperf_file) - except: - asserts.fail('Cannot get iperf result.') - llstats_obj.update_stats() - curr_llstats = llstats_obj.llstats_incremental.copy() - test_result = collections.OrderedDict() - test_result['testcase_params'] = testcase_params.copy() - test_result['ap_settings'] = self.access_point.ap_settings.copy() - test_result['attenuation'] = testcase_params['atten_level'] - test_result['iperf_result'] = iperf_result - test_result['rssi_result'] = current_rssi - test_result['llstats'] = curr_llstats - self.testclass_results.append(test_result) - return test_result - - def get_target_atten(self, testcase_params): - """Function gets attenuation used for test - - The function fetches the attenuation at which the test should be - performed. - - Args: - testcase_params: dict containing test specific parameters - Returns: - test_atten: target attenuation for test - """ - # Get attenuation from reference test if it has been run - ref_test_fields = ['channel', 'mode', 'signal_level'] - test_id = wputils.extract_sub_dict(testcase_params, ref_test_fields) - test_id = tuple(test_id.items()) - if test_id in self.ref_attenuations: - return self.ref_attenuations[test_id] - - # Get attenuation for target RSSI - if testcase_params['signal_level'] == 'low': - target_rssi = self.testclass_params['low_throughput_target'] - else: - target_rssi = self.testclass_params['high_throughput_target'] - target_atten = wputils.get_atten_for_target_rssi( - target_rssi, self.attenuators, self.dut, self.remote_server) - - self.ref_attenuations[test_id] = target_atten - return self.ref_attenuations[test_id] - - def compile_test_params(self, testcase_params): - """Function that completes setting the test case parameters.""" - band = self.access_point.band_lookup_by_channel( - testcase_params['channel']) - testcase_params['test_network'] = self.main_network[band] - - if (testcase_params['traffic_direction'] == 'DL' - and not isinstance(self.iperf_server, ipf.IPerfServerOverAdb) - ) or (testcase_params['traffic_direction'] == 'UL' - and isinstance(self.iperf_server, ipf.IPerfServerOverAdb)): - testcase_params['iperf_args'] = wputils.get_iperf_arg_string( - duration=self.testclass_params['iperf_duration'], - reverse_direction=1, - traffic_type=testcase_params['traffic_type']) - testcase_params['use_client_output'] = True - else: - testcase_params['iperf_args'] = wputils.get_iperf_arg_string( - duration=self.testclass_params['iperf_duration'], - reverse_direction=0, - traffic_type=testcase_params['traffic_type']) - testcase_params['use_client_output'] = False - - return testcase_params - - def _test_throughput_stability(self, testcase_params): - """ Function that gets called for each test case - - The function gets called in each test case. The function customizes - the test based on the test name of the test that called it - - Args: - testcase_params: dict containing test specific parameters - """ - testcase_params = self.compile_test_params(testcase_params) - self.setup_throughput_stability_test(testcase_params) - test_result = self.run_throughput_stability_test(testcase_params) - test_result_postprocessed = self.post_process_results(test_result) - self.pass_fail_check(test_result_postprocessed) - - -# Over-the air version of ping tests -class WifiOtaThroughputStabilityTest(WifiThroughputStabilityTest): - """Class to test over-the-air ping - - This class tests WiFi ping performance in an OTA chamber. It enables - setting turntable orientation and other chamber parameters to study - performance in varying channel conditions - """ - def __init__(self, controllers): - base_test.BaseTestClass.__init__(self, controllers) - # Define metrics to be uploaded to BlackBox - self.testcase_metric_logger = ( - BlackboxMappedMetricLogger.for_test_case()) - self.testclass_metric_logger = ( - BlackboxMappedMetricLogger.for_test_class()) - self.publish_testcase_metrics = False - - def setup_class(self): - WifiThroughputStabilityTest.setup_class(self) - self.ota_chamber = ota_chamber.create( - self.user_params['OTAChamber'])[0] - - def teardown_class(self): - self.ota_chamber.reset_chamber() - self.process_testclass_results() - - def extract_test_id(self, testcase_params, id_fields): - test_id = collections.OrderedDict( - (param, testcase_params[param]) for param in id_fields) - return test_id - - def process_testclass_results(self): - """Saves all test results to enable comparison.""" - testclass_data = collections.OrderedDict() - for test in self.testclass_results: - current_params = test['testcase_params'] - channel_data = testclass_data.setdefault(current_params['channel'], - collections.OrderedDict()) - test_id = tuple( - self.extract_test_id(current_params, [ - 'mode', 'traffic_type', 'traffic_direction', 'signal_level' - ]).items()) - test_data = channel_data.setdefault( - test_id, collections.OrderedDict(position=[], throughput=[])) - current_throughput = (numpy.mean( - test['iperf_result'].instantaneous_rates[ - self.testclass_params['iperf_ignored_interval']:-1]) - ) * 8 * (1.024**2) - test_data['position'].append(current_params['position']) - test_data['throughput'].append(current_throughput) - - chamber_mode = self.testclass_results[0]['testcase_params'][ - 'chamber_mode'] - if chamber_mode == 'orientation': - x_label = 'Angle (deg)' - elif chamber_mode == 'stepped stirrers': - x_label = 'Position Index' - - # Publish test class metrics - for channel, channel_data in testclass_data.items(): - for test_id, test_data in channel_data.items(): - test_id_dict = dict(test_id) - metric_tag = 'ota_summary_{}_{}_{}_ch{}_{}'.format( - test_id_dict['signal_level'], test_id_dict['traffic_type'], - test_id_dict['traffic_direction'], channel, - test_id_dict['mode']) - metric_name = metric_tag + '.avg_throughput' - metric_value = numpy.mean(test_data['throughput']) - self.testclass_metric_logger.add_metric( - metric_name, metric_value) - metric_name = metric_tag + '.min_throughput' - metric_value = min(test_data['throughput']) - self.testclass_metric_logger.add_metric( - metric_name, metric_value) - - # Plot test class results - plots = [] - for channel, channel_data in testclass_data.items(): - current_plot = wputils.BokehFigure( - title='Channel {} - Rate vs. Position'.format(channel), - x_label=x_label, - primary_y_label='Rate (Mbps)', - ) - for test_id, test_data in channel_data.items(): - test_id_dict = dict(test_id) - legend = '{}, {} {}, {} RSSI'.format( - test_id_dict['mode'], test_id_dict['traffic_type'], - test_id_dict['traffic_direction'], - test_id_dict['signal_level']) - current_plot.add_line(test_data['position'], - test_data['throughput'], legend) - current_plot.generate_figure() - plots.append(current_plot) - current_context = context.get_current_context().get_full_output_path() - plot_file_path = os.path.join(current_context, 'results.html') - wputils.BokehFigure.save_figures(plots, plot_file_path) - - def setup_throughput_stability_test(self, testcase_params): - WifiThroughputStabilityTest.setup_throughput_stability_test( - self, testcase_params) - # Setup turntable - if testcase_params['chamber_mode'] == 'orientation': - self.ota_chamber.set_orientation(testcase_params['position']) - elif testcase_params['chamber_mode'] == 'stepped stirrers': - self.ota_chamber.step_stirrers(testcase_params['total_positions']) - - def get_target_atten(self, testcase_params): - if testcase_params['signal_level'] == 'high': - test_atten = self.testclass_params['default_atten_levels'][0] - elif testcase_params['signal_level'] == 'low': - test_atten = self.testclass_params['default_atten_levels'][1] - return test_atten - - def generate_test_cases(self, channels, modes, traffic_types, - traffic_directions, signal_levels, chamber_mode, - positions): - allowed_configs = { - 'VHT20': [ - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 149, 153, - 157, 161 - ], - 'VHT40': [36, 44, 149, 157], - 'VHT80': [36, 149] - } - test_cases = [] - for channel, mode, position, traffic_type, signal_level, traffic_direction in itertools.product( - channels, modes, positions, traffic_types, signal_levels, - traffic_directions): - if channel not in allowed_configs[mode]: - continue - testcase_params = collections.OrderedDict( - channel=channel, - mode=mode, - traffic_type=traffic_type, - traffic_direction=traffic_direction, - signal_level=signal_level, - chamber_mode=chamber_mode, - total_positions=len(positions), - position=position) - testcase_name = ('test_tput_stability' - '_{}_{}_{}_ch{}_{}_pos{}'.format( - signal_level, traffic_type, traffic_direction, - channel, mode, position)) - setattr(self, testcase_name, - partial(self._test_throughput_stability, testcase_params)) - test_cases.append(testcase_name) - return test_cases - - -class WifiOtaThroughputStability_TenDegree_Test(WifiOtaThroughputStabilityTest - ): - def __init__(self, controllers): - WifiOtaThroughputStabilityTest.__init__(self, controllers) - self.tests = self.generate_test_cases([6, 36, 149], ['VHT20', 'VHT80'], - ['TCP'], ['DL', 'UL'], - ['high', 'low'], 'orientation', - list(range(0, 360, 10))) - - -class WifiOtaThroughputStability_45Degree_Test(WifiOtaThroughputStabilityTest): - def __init__(self, controllers): - WifiOtaThroughputStabilityTest.__init__(self, controllers) - self.tests = self.generate_test_cases([6, 36, 149], ['VHT20', 'VHT80'], - ['TCP'], ['DL', 'UL'], - ['high', 'low'], 'orientation', - list(range(0, 360, 45))) - - -class WifiOtaThroughputStability_SteppedStirrers_Test( - WifiOtaThroughputStabilityTest): - def __init__(self, controllers): - WifiOtaThroughputStabilityTest.__init__(self, controllers) - self.tests = self.generate_test_cases([6, 36, 149], ['VHT20', 'VHT80'], - ['TCP'], ['DL', 'UL'], - ['high', 'low'], - 'stepped stirrers', - list(range(100))) diff --git a/acts/tests/google/wifi/WifiWakeTest.py b/acts/tests/google/wifi/WifiWakeTest.py deleted file mode 100644 index 13c6b2dc0b..0000000000 --- a/acts/tests/google/wifi/WifiWakeTest.py +++ /dev/null @@ -1,363 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2018 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import time -import queue - -from acts import asserts -from acts.controllers.android_device import SL4A_APK_NAME -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest -import acts.test_utils.wifi.wifi_test_utils as wutils -import acts.utils - -CONSECUTIVE_MISSED_SCANS_REQUIRED_TO_EVICT = 5 -LAST_DISCONNECT_TIMEOUT_MILLIS = 5000 -LAST_DISCONNECT_TIMEOUT_SEC = LAST_DISCONNECT_TIMEOUT_MILLIS / 1000 -PRESCAN_DELAY_SEC = 5 - - -class WifiWakeTest(WifiBaseTest): - """ - Tests Wifi Wake. - - Test Bed Requirements: - * One Android Device - * Two APs that can be turned on and off - """ - - def setup_class(self): - super().setup_class() - - self.dut = self.android_devices[0] - wutils.wifi_test_device_init(self.dut) - # turn location back on - acts.utils.set_location_service(self.dut, True) - self.dut.droid.wifiScannerToggleAlwaysAvailable(True) - - self.unpack_userparams(req_param_names=[], - opt_param_names=["reference_networks"]) - - if "AccessPoint" in self.user_params: - self.legacy_configure_ap_and_start(mirror_ap=False, ap_count=2) - - # use 2G since Wifi Wake does not work if an AP is on a 5G DFS channel - self.ap_a = self.reference_networks[0]["2g"] - self.ap_b = self.reference_networks[1]["2g"] - - self.ap_a_atten = self.attenuators[0] - self.ap_b_atten = self.attenuators[2] - - # TODO(b/119040540): this method of disabling/re-enabling Wifi on APs is - # hacky, switch to using public methods when they are implemented - def ap_a_off(self): - ap_a_hostapd = self.access_points[0]._aps['wlan0'].hostapd - if ap_a_hostapd.is_alive(): - ap_a_hostapd.stop() - self.log.info('Turned AP A off') - - def ap_a_on(self): - ap_a_hostapd = self.access_points[0]._aps['wlan0'].hostapd - if not ap_a_hostapd.is_alive(): - ap_a_hostapd.start(ap_a_hostapd.config) - self.log.info('Turned AP A on') - - def ap_b_off(self): - ap_b_hostapd = self.access_points[1]._aps['wlan0'].hostapd - if ap_b_hostapd.is_alive(): - ap_b_hostapd.stop() - self.log.info('Turned AP B off') - - def ap_b_on(self): - ap_b_hostapd = self.access_points[1]._aps['wlan0'].hostapd - if not ap_b_hostapd.is_alive(): - ap_b_hostapd.start(ap_b_hostapd.config) - self.log.info('Turned AP B on') - - def setup_test(self): - self.dut.droid.wakeLockAcquireBright() - self.dut.droid.wakeUpNow() - self.ap_a_on() - self.ap_b_on() - self.ap_a_atten.set_atten(0) - self.ap_b_atten.set_atten(0) - wutils.reset_wifi(self.dut) - wutils.wifi_toggle_state(self.dut, new_state=True) - # clear events from event dispatcher - self.dut.droid.wifiStartTrackingStateChange() - self.dut.droid.wifiStopTrackingStateChange() - self.dut.ed.clear_all_events() - - def teardown_test(self): - self.dut.droid.wakeLockRelease() - self.dut.droid.goToSleepNow() - - def on_fail(self, test_name, begin_time): - self.dut.take_bug_report(test_name, begin_time) - self.dut.cat_adb_log(test_name, begin_time) - - def do_location_scan(self, num_times=1): - scan_settings = { - "band": wutils.WifiEnums.WIFI_BAND_BOTH, - "periodInMs": 0, - "reportEvents": wutils.WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN - } - - wifi_chs = wutils.WifiChannelUS(self.dut.model) - stime_channel = 47 # dwell time plus 2ms - leeway = 10 - - for i in range(num_times): - self.log.info("Scan count: {}".format(i)) - data = wutils.start_wifi_single_scan(self.dut, scan_settings) - idx = data["Index"] - scan_rt = data["ScanElapsedRealtime"] - self.log.debug( - "Wifi single shot scan started index: %s at real time: %s", idx, - scan_rt) - # generating event wait time from scan setting plus leeway - scan_time, scan_channels = wutils.get_scan_time_and_channels( - wifi_chs, scan_settings, stime_channel) - wait_time = int(scan_time / 1000) + leeway - # track number of result received - result_received = 0 - try: - for _ in range(1, 3): - event_name = "{}{}onResults".format("WifiScannerScan", idx) - self.log.debug("Waiting for event: %s for time %s", - event_name, wait_time) - event = self.dut.ed.pop_event(event_name, wait_time) - self.log.debug("Event received: %s", event) - result_received += 1 - except queue.Empty as error: - asserts.assert_true( - result_received >= 1, - "Event did not triggered for single shot {}".format(error)) - finally: - self.dut.droid.wifiScannerStopScan(idx) - # For single shot number of result received and length of result - # should be one - asserts.assert_true( - result_received == 1, - "Test fail because received result {}".format( - result_received)) - - @test_tracker_info(uuid="372b9b74-4241-46ce-8f18-e6a97d3a3452") - def test_no_reconnect_manual_disable_wifi(self): - """ - Tests that Wifi Wake does not reconnect to a network if the user turned - off Wifi while connected to that network and the user has not moved - (i.e. moved out of range of the AP then came back). - """ - wutils.wifi_connect(self.dut, self.ap_a, num_of_tries=5) - wutils.wifi_toggle_state(self.dut, new_state=False) - time.sleep(PRESCAN_DELAY_SEC) - self.do_location_scan( - 2 * CONSECUTIVE_MISSED_SCANS_REQUIRED_TO_EVICT + 2) - asserts.assert_false( - self.dut.droid.wifiCheckState(), - "Expect Wifi Wake to not enable Wifi, but Wifi was enabled.") - - @test_tracker_info(uuid="ec7a54a5-f293-43f5-a1dd-d41679aa1825") - def test_reconnect_wifi_saved_network(self): - """Tests that Wifi Wake re-enables Wifi for a saved network.""" - wutils.wifi_connect(self.dut, self.ap_a, num_of_tries=5) - wutils.wifi_connect(self.dut, self.ap_b, num_of_tries=5) - self.dut.ed.clear_all_events() - self.ap_a_off() - self.ap_b_off() - wutils.wait_for_disconnect(self.dut) - self.log.info("Wifi Disconnected") - time.sleep(LAST_DISCONNECT_TIMEOUT_SEC * 1.2) - wutils.wifi_toggle_state(self.dut, new_state=False) - time.sleep(PRESCAN_DELAY_SEC) - self.do_location_scan(CONSECUTIVE_MISSED_SCANS_REQUIRED_TO_EVICT + 2) - - self.ap_a_on() - self.do_location_scan() - asserts.assert_true( - self.dut.droid.wifiCheckState(), - "Expect Wifi Wake to enable Wifi, but Wifi is disabled.") - - @test_tracker_info(uuid="") - def test_reconnect_wifi_network_suggestion(self): - """Tests that Wifi Wake re-enables Wifi for app provided suggestion.""" - self.dut.log.info("Adding network suggestions"); - asserts.assert_true( - self.dut.droid.wifiAddNetworkSuggestions([self.ap_a]), - "Failed to add suggestions") - asserts.assert_true( - self.dut.droid.wifiAddNetworkSuggestions([self.ap_b]), - "Failed to add suggestions") - # Enable suggestions by the app. - self.dut.log.debug("Enabling suggestions from test"); - self.dut.adb.shell("cmd wifi network-suggestions-set-user-approved" - + " " + SL4A_APK_NAME + " yes") - # Ensure network is seen in scan results & auto-connected to. - self.do_location_scan(2) - wutils.wait_for_connect(self.dut) - self.dut.ed.clear_all_events() - self.ap_a_off() - self.ap_b_off() - wutils.wait_for_disconnect(self.dut) - self.log.info("Wifi Disconnected") - time.sleep(LAST_DISCONNECT_TIMEOUT_SEC * 1.2) - wutils.wifi_toggle_state(self.dut, new_state=False) - time.sleep(PRESCAN_DELAY_SEC) - self.do_location_scan(CONSECUTIVE_MISSED_SCANS_REQUIRED_TO_EVICT + 2) - - self.ap_a_on() - self.do_location_scan() - asserts.assert_true( - self.dut.droid.wifiCheckState(), - "Expect Wifi Wake to enable Wifi, but Wifi is disabled.") - - @test_tracker_info(uuid="6c77ca9b-ff34-4bc7-895f-cc7340e0e645") - def test_reconnect_wifi_move_back_in_range(self): - """ - Tests that Wifi Wake re-enables Wifi if the device moves out of range of - the AP then came back. - """ - wutils.wifi_connect(self.dut, self.ap_a, num_of_tries=5) - wutils.wifi_toggle_state(self.dut, new_state=False) - time.sleep(PRESCAN_DELAY_SEC) - # init Wakeup Lock with AP A - self.do_location_scan(CONSECUTIVE_MISSED_SCANS_REQUIRED_TO_EVICT + 2) - self.ap_a_off() - # evict AP A from Wakeup Lock - self.do_location_scan(CONSECUTIVE_MISSED_SCANS_REQUIRED_TO_EVICT + 2) - self.ap_a_on() - self.do_location_scan() - asserts.assert_true( - self.dut.droid.wifiCheckState(), - "Expect Wifi Wake to enable Wifi, but Wifi is disabled.") - - @test_tracker_info(uuid="08e8284a-a523-48f3-b9ea-9c6bf27d711e") - def test_no_reconnect_to_flaky_ap(self): - """ - Tests that Wifi Wake does not reconnect to flaky networks. - If a network sporadically connects and disconnects, and the user turns - off Wifi even during the disconnected phase, Wifi Wake should not - re-enable Wifi for that network. - """ - wutils.wifi_connect(self.dut, self.ap_a, num_of_tries=5) - self.ap_a_off() - time.sleep(LAST_DISCONNECT_TIMEOUT_SEC * 0.4) - wutils.wifi_toggle_state(self.dut, new_state=False) - time.sleep(PRESCAN_DELAY_SEC) - self.do_location_scan(CONSECUTIVE_MISSED_SCANS_REQUIRED_TO_EVICT + 2) - self.ap_a_on() - self.do_location_scan( - 2 * CONSECUTIVE_MISSED_SCANS_REQUIRED_TO_EVICT + 2) - asserts.assert_false( - self.dut.droid.wifiCheckState(), - "Expect Wifi Wake to not enable Wifi, but Wifi was enabled.") - - @test_tracker_info(uuid="b990a8f7-e3a0-4774-89cf-2067ccd64903") - def test_reconnect_wifi_disabled_after_disconnecting(self): - """ - Tests that Wifi Wake reconnects to a network if Wifi was disabled long - after disconnecting from a network. - """ - wutils.wifi_connect(self.dut, self.ap_a, num_of_tries=5) - self.dut.ed.clear_all_events() - self.ap_a_off() - wutils.wait_for_disconnect(self.dut) - self.log.info("Wifi Disconnected") - time.sleep(LAST_DISCONNECT_TIMEOUT_SEC * 1.2) - wutils.wifi_toggle_state(self.dut, new_state=False) - time.sleep(PRESCAN_DELAY_SEC) - self.do_location_scan(CONSECUTIVE_MISSED_SCANS_REQUIRED_TO_EVICT + 2) - self.ap_a_on() - self.do_location_scan() - asserts.assert_true( - self.dut.droid.wifiCheckState(), - "Expect Wifi Wake to enable Wifi, but Wifi is disabled.") - - @test_tracker_info(uuid="bb217794-d3ee-4fb9-87ff-7a594d0223b0") - def test_no_reconnect_if_exists_ap_in_wakeup_lock(self): - """ - 2 APs in Wakeup Lock, user moves out of range of one AP but stays in - range of the other, should not reconnect when user moves back in range - of both. - """ - wutils.wifi_connect(self.dut, self.ap_a, num_of_tries=5) - wutils.wifi_connect(self.dut, self.ap_b, num_of_tries=5) - wutils.wifi_toggle_state(self.dut, new_state=False) - time.sleep(PRESCAN_DELAY_SEC) - self.do_location_scan(CONSECUTIVE_MISSED_SCANS_REQUIRED_TO_EVICT + 2) - self.ap_b_off() - self.do_location_scan(CONSECUTIVE_MISSED_SCANS_REQUIRED_TO_EVICT + 2) - self.ap_b_on() - self.do_location_scan(CONSECUTIVE_MISSED_SCANS_REQUIRED_TO_EVICT + 2) - asserts.assert_false( - self.dut.droid.wifiCheckState(), - "Expect Wifi Wake to not enable Wifi, but Wifi was enabled.") - - @test_tracker_info(uuid="567a0663-4ce0-488d-8fe2-db79a3ebf068") - def test_reconnect_if_both_ap_evicted_from_wakeup_lock(self): - """ - 2 APs in Wakeup Lock, user moves out of range of both APs, should - reconnect when user moves back in range of either AP. - """ - wutils.wifi_connect(self.dut, self.ap_a, num_of_tries=5) - wutils.wifi_connect(self.dut, self.ap_b, num_of_tries=5) - wutils.wifi_toggle_state(self.dut, new_state=False) - time.sleep(PRESCAN_DELAY_SEC) - self.do_location_scan(CONSECUTIVE_MISSED_SCANS_REQUIRED_TO_EVICT + 2) - self.ap_a_off() - self.ap_b_off() - self.do_location_scan(CONSECUTIVE_MISSED_SCANS_REQUIRED_TO_EVICT + 2) - self.ap_a_on() - self.do_location_scan() - asserts.assert_true( - self.dut.droid.wifiCheckState(), - "Expect Wifi Wake to enable Wifi, but Wifi is disabled.") - - @test_tracker_info(uuid="d67657c8-3de3-46a6-a103-428cdab89423") - def test_reconnect_to_better_saved_network(self): - """ - 2 saved APs, one attenuated, one unattenuated, Wifi Wake should connect - to the unattenuated AP - """ - wutils.wifi_connect(self.dut, self.ap_a, num_of_tries=5) - wutils.wifi_connect(self.dut, self.ap_b, num_of_tries=5) - self.dut.ed.clear_all_events() - self.ap_a_off() - self.ap_b_off() - wutils.wait_for_disconnect(self.dut) - self.log.info("Wifi Disconnected") - time.sleep(LAST_DISCONNECT_TIMEOUT_SEC * 1.2) - wutils.wifi_toggle_state(self.dut, new_state=False) - time.sleep(PRESCAN_DELAY_SEC) - self.do_location_scan(CONSECUTIVE_MISSED_SCANS_REQUIRED_TO_EVICT + 2) - - self.ap_a_on() - self.ap_b_on() - self.ap_a_atten.set_atten(30) - self.ap_b_atten.set_atten(0) - - self.do_location_scan() - asserts.assert_true( - self.dut.droid.wifiCheckState(), - "Expect Wifi Wake to enable Wifi, but Wifi is disabled.") - expected_ssid = self.ap_b[wutils.WifiEnums.SSID_KEY] - actual_ssid = self.dut.droid.wifiGetConnectionInfo()[ - wutils.WifiEnums.SSID_KEY] - asserts.assert_equal( - expected_ssid, actual_ssid, - ("Expected to connect to SSID '{}', but actually connected to " - "'{}' instead.").format(expected_ssid, actual_ssid)) diff --git a/acts/tests/google/wifi/WifiWpa3OweTest.py b/acts/tests/google/wifi/WifiWpa3OweTest.py deleted file mode 100644 index fbe939c216..0000000000 --- a/acts/tests/google/wifi/WifiWpa3OweTest.py +++ /dev/null @@ -1,103 +0,0 @@ -#!/usr/bin/env python3.4 -# -# Copyright 2019 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import itertools -import pprint -import queue -import time - -import acts.base_test -import acts.signals as signals -import acts.test_utils.wifi.wifi_test_utils as wutils -import acts.utils - -from acts import asserts -from acts.controllers.ap_lib import hostapd_constants -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest - -WifiEnums = wutils.WifiEnums - -class WifiWpa3OweTest(WifiBaseTest): - """Tests for APIs in Android's WifiManager class. - - Test Bed Requirement: - * At least one Android device and atleast two Access Points. - * Several Wi-Fi networks visible to the device. - """ - - def setup_class(self): - super().setup_class() - - self.dut = self.android_devices[0] - self.dut_client = self.android_devices[1] - wutils.wifi_test_device_init(self.dut) - wutils.wifi_test_device_init(self.dut_client) - req_params = ["owe_networks", "wpa3_personal"] - opt_param = [] - self.unpack_userparams( - req_param_names=req_params, opt_param_names=opt_param) - wutils.wifi_toggle_state(self.dut, True) - wutils.wifi_toggle_state(self.dut_client, True) - self.owe_2g = self.owe_networks[0]["2g"] - self.owe_5g = self.owe_networks[0]["5g"] - self.wpa3_personal_2g = self.wpa3_personal[0]["2g"] - self.wpa3_personal_5g = self.wpa3_personal[0]["5g"] - - def setup_test(self): - for ad in self.android_devices: - ad.droid.wakeLockAcquireBright() - ad.droid.wakeUpNow() - wutils.wifi_toggle_state(ad, True) - - def teardown_test(self): - for ad in self.android_devices: - ad.droid.wakeLockRelease() - ad.droid.goToSleepNow() - wutils.reset_wifi(self.dut) - wutils.reset_wifi(self.dut_client) - - def on_fail(self, test_name, begin_time): - self.dut.cat_adb_log(test_name, begin_time) - self.dut.take_bug_report(test_name, begin_time) - - """Helper Functions""" - - """Tests""" - - @test_tracker_info(uuid="a7755f1f-5740-4d45-8c29-3711172b1bd7") - def test_connect_to_owe_2g(self): - wutils.start_wifi_connection_scan_and_ensure_network_found(self.dut, - self.owe_2g[WifiEnums.SSID_KEY]) - wutils.connect_to_wifi_network(self.dut, self.owe_2g ) - - @test_tracker_info(uuid="9977765e-03da-4614-ab96-4c1597101118") - def test_connect_to_owe_5g(self): - wutils.start_wifi_connection_scan_and_ensure_network_found(self.dut, - self.owe_5g[WifiEnums.SSID_KEY]) - wutils.connect_to_wifi_network(self.dut, self.owe_5g) - - @test_tracker_info(uuid="3670702a-3d78-4184-b5e1-7fcf5fa48fd8") - def test_connect_to_wpa3_personal_2g(self): - wutils.start_wifi_connection_scan_and_ensure_network_found(self.dut, - self.wpa3_personal_2g[WifiEnums.SSID_KEY]) - wutils.connect_to_wifi_network(self.dut, self.wpa3_personal_2g) - - @test_tracker_info(uuid="c4528eaf-7960-4ecd-8f11-d5439bdf1c58") - def test_connect_to_wpa3_personal_5g(self): - wutils.start_wifi_connection_scan_and_ensure_network_found(self.dut, - self.wpa3_personal_5g[WifiEnums.SSID_KEY]) - wutils.connect_to_wifi_network(self.dut, self.owe_5g) diff --git a/acts/tests/google/wifi/aware/README.md b/acts/tests/google/wifi/aware/README.md deleted file mode 100644 index 6b969141ab..0000000000 --- a/acts/tests/google/wifi/aware/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# Wi-Fi Aware Integrated (ACTS/sl4a) Test Suite - -This directory contains ACTS/sl4a test scripts to verify and characterize -the Wi-Fi Aware implementation in Android. - -There are 4 groups of tests (in 4 sub-directories): - -* functional: Functional tests that each implementation must pass. These -are pass/fail tests. -* performance: Tests which measure performance of an implementation - e.g. -latency or throughput. Some of the tests may not have pass/fail results - -they just record the measured performance. Even when tests do have a pass/ -fail criteria - that criteria may not apply to all implementations. -* stress: Tests which run through a large number of iterations to stress -test the implementation. Considering that some failures are expected, -especially in an over-the-air situation, pass/fail criteria are either -not provided or may not apply to all implementations or test environments. -* ota (over-the-air): A small number of tests which configure the device -in a particular mode and expect the tester to capture an over-the-air -sniffer trace and analyze it for validity. These tests are **not** automated. - -The tests can be executed in several ways: - -1. Individual test(s): `act.py -c <config> -tc {<test_class>|<test_class>:<test_name>}` - -Where a test file is any of the `.py` files in any of the test sub-directories. -If a test class is specified, then all tests within that test class are executed. - -2. All tests in a test group: `act.py -c <config> -tf <test_file>` - -Where `<test_file>` is a file containing a list of tests. Each of the test -group sub-directories contains a file with the same name as that of the -directory which lists all tests in the directory. E.g. to execute all functional -tests execute: - -`act.py -c <config> -tf ./tools/test/connectivity/acts_tests/tests/google/wifi/aware/functional/functional` - -## Test Configurations -The test configurations, the `<config>` in the commands above, are stored in -the *config* sub-directory. The configurations simply use all connected -devices without listing specific serial numbers. Note that some tests use a -single device while others use 2 devices. In addition, the configurations -define the following key to configure the test: - -* **aware_default_power_mode**: The power mode in which to run all tests. Options -are `INTERACTIVE` and `NON_INTERACTIVE`. - -The following configurations are provided: -* wifi_aware.json: Normal (high power/interactive) test mode. -* wifi_aware_non_interactive.json: Low power (non-interactive) test mode. diff --git a/acts/tests/google/wifi/aware/config/wifi_aware.json b/acts/tests/google/wifi/aware/config/wifi_aware.json deleted file mode 100644 index f1bd907ff1..0000000000 --- a/acts/tests/google/wifi/aware/config/wifi_aware.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "_description": "This is a test configuration file for Wi-Fi Aware tests in INTERACTIVE (high-power) mode.", - "testbed": - [ - { - "_description": "Wi-Fi Aware testbed: auto-detect all attached devices", - "name": "WifiAwareAllAttached", - "AndroidDevice": "*" - } - ], - "logpath": "~/logs", - "testpaths": ["./tools/test/connectivity/acts_tests/tests/google/wifi"], - "adb_logcat_param": "-b all", - "aware_default_power_mode": "INTERACTIVE" -} diff --git a/acts/tests/google/wifi/aware/config/wifi_aware_non_interactive.json b/acts/tests/google/wifi/aware/config/wifi_aware_non_interactive.json deleted file mode 100644 index 391775689f..0000000000 --- a/acts/tests/google/wifi/aware/config/wifi_aware_non_interactive.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "_description": "This is a test configuration file for Wi-Fi Aware tests in NON-INTERACTIVE (low-power) mode.", - "testbed": - [ - { - "_description": "Wi-Fi Aware testbed: auto-detect all attached devices", - "name": "WifiAwareAllAttached", - "AndroidDevice": "*" - } - ], - "logpath": "~/logs", - "testpaths": ["./tools/test/connectivity/acts_tests/tests/google/wifi"], - "adb_logcat_param": "-b all", - "aware_default_power_mode": "NON_INTERACTIVE" -} diff --git a/acts/tests/google/wifi/aware/functional/AttachTest.py b/acts/tests/google/wifi/aware/functional/AttachTest.py deleted file mode 100644 index 0df82a1c77..0000000000 --- a/acts/tests/google/wifi/aware/functional/AttachTest.py +++ /dev/null @@ -1,161 +0,0 @@ -#!/usr/bin/python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import time - -from acts import asserts -from acts import utils -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi import wifi_test_utils as wutils -from acts.test_utils.wifi.aware import aware_const as aconsts -from acts.test_utils.wifi.aware import aware_test_utils as autils -from acts.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest - - -class AttachTest(AwareBaseTest): - @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) - - @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) - - @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 - - 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) - - @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 - 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 - correctly, and allows it to be re-enabled when Airplane mode is then - disabled.""" - dut = self.android_devices[0] - - # 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) - - # 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) diff --git a/acts/tests/google/wifi/aware/functional/CapabilitiesTest.py b/acts/tests/google/wifi/aware/functional/CapabilitiesTest.py deleted file mode 100644 index 3bed77fdc6..0000000000 --- a/acts/tests/google/wifi/aware/functional/CapabilitiesTest.py +++ /dev/null @@ -1,275 +0,0 @@ -#!/usr/bin/python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from acts import asserts - -from acts.test_decorators import test_tracker_info -from acts.test_utils.net import connectivity_const as cconsts -from acts.test_utils.wifi.aware import aware_const as aconsts -from acts.test_utils.wifi.aware import aware_test_utils as autils -from acts.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest - - -class CapabilitiesTest(AwareBaseTest): - """Set of tests for Wi-Fi Aware Capabilities - verifying that the provided - capabilities are real (i.e. available).""" - - SERVICE_NAME = "GoogleTestXYZ" - - def create_config(self, dtype, service_name): - """Create a discovery configuration based on input parameters. - - Args: - dtype: Publish or Subscribe discovery type - service_name: Service name. - - Returns: - Discovery configuration object. - """ - 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 - - Args: - dut: Device under test - session_id: ID of the Aware session in which to start discovery - is_publish: True for a publish session, False for subscribe session - dtype: Type of the discovery session - service_name: Service name to use for the discovery session - expect_success: True if expect session to be created, False otherwise - - 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 - 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 - by its capabilities. - - Mechanics: - - Publisher on DUT (first device) - - Subscribers on all other devices - - On discovery set up NDP - - 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))) diff --git a/acts/tests/google/wifi/aware/functional/DataPathTest.py b/acts/tests/google/wifi/aware/functional/DataPathTest.py deleted file mode 100644 index 3f68376831..0000000000 --- a/acts/tests/google/wifi/aware/functional/DataPathTest.py +++ /dev/null @@ -1,2224 +0,0 @@ -#!/usr/bin/python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import time - -from acts import asserts -from acts.test_decorators import test_tracker_info -from acts.test_utils.net import connectivity_const as cconsts -from acts.test_utils.wifi import wifi_test_utils as wutils -from acts.test_utils.wifi.aware import aware_const as aconsts -from acts.test_utils.wifi.aware import aware_test_utils as autils -from acts.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest - - -class DataPathTest(AwareBaseTest): - """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 - - 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" - - # 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 - - def create_config(self, dtype): - """Create a base configuration based on input parameters. - - Args: - dtype: Publish or Subscribe discovery type - - Returns: - Discovery configuration object. - """ - 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. - - Args: - dut: Device - ns: Network specifier - Returns: the request key - """ - 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. - - Args: - ptype: Publish discovery type - stype: Subscribe discovery type - get_peer_id: Send a message across to get the peer's id - pub_on_both: If True then set up a publisher on both devices. The second - publisher isn't used (existing to test use-case). - 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. - - Args: - ptype: Publish discovery type - stype: Subscribe discovery type - encr_type: Encryption type, one of ENCR_TYPE_* - use_peer_id: On Responder (publisher): True to use peer ID, False to - accept any request - passphrase_to_use: The passphrase to use if encr_type=ENCR_TYPE_PASSPHRASE - If None then use self.PASSPHRASE - pub_on_both: If True then set up a publisher on both devices. The second - publisher isn't used (existing to test use-case). - pub_on_both_same: If True then the second publish uses an identical - service name, otherwise a different service name. - 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 - - port = 1234 - transport_protocol = 6 # TCP/IP - - # Publisher: request network - if encr_type == self.ENCR_TYPE_OPEN: - 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)) - else: - 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, port, transport_protocol)) - - # 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: expect unavailable callbacks - autils.wait_for_event_with_keys( - p_dut, cconsts.EVENT_NETWORK_CALLBACK, - autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_UNAVAILABLE)) - autils.wait_for_event_with_keys( - s_dut, cconsts.EVENT_NETWORK_CALLBACK, - autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_UNAVAILABLE)) - else: - # Publisher & Subscriber: wait for network formation - p_net_event_nc = autils.wait_for_event_with_keys( - p_dut, cconsts.EVENT_NETWORK_CALLBACK, - autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_CAPABILITIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, p_req_key)) - s_net_event_nc = autils.wait_for_event_with_keys( - s_dut, cconsts.EVENT_NETWORK_CALLBACK, - autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_CAPABILITIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, s_req_key)) - - # validate no leak of information - asserts.assert_false( - cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in p_net_event_nc[ - "data"], "Network specifier leak!") - asserts.assert_false( - cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in s_net_event_nc[ - "data"], "Network specifier leak!") - - # note that Pub <-> Sub since IPv6 are of peer's! - s_ipv6 = p_net_event_nc["data"][aconsts.NET_CAP_IPV6] - p_ipv6 = s_net_event_nc["data"][aconsts.NET_CAP_IPV6] - - self.verify_network_info( - p_net_event_nc["data"], s_net_event_nc["data"], - encr_type == self.ENCR_TYPE_OPEN, port, transport_protocol) - - p_net_event_lp = 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_lp = 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_lp["data"][ - cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - s_aware_if = s_net_event_lp["data"][ - cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - - 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) - - # open sockets to test connection - asserts.assert_true( - autils.verify_socket_connect(p_dut, s_dut, p_ipv6, s_ipv6, 0), - "Failed socket link with Pub as Server") - asserts.assert_true( - autils.verify_socket_connect(s_dut, p_dut, s_ipv6, p_ipv6, 0), - "Failed socket link with Sub as Server") - - # 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_* - use_peer_id: On Responder: True to use peer ID, False to accept any - request - setup_discovery_sessions: If True also set up a (spurious) discovery - session (pub on both sides, sub on Responder side). Validates a corner - case. - 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: expect unavailable callbacks - autils.wait_for_event_with_keys( - init_dut, cconsts.EVENT_NETWORK_CALLBACK, - autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_UNAVAILABLE)) - autils.wait_for_event_with_keys( - resp_dut, cconsts.EVENT_NETWORK_CALLBACK, - autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_UNAVAILABLE)) - else: - # Initiator & Responder: wait for network formation - init_net_event_nc = autils.wait_for_event_with_keys( - init_dut, cconsts.EVENT_NETWORK_CALLBACK, - autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_CAPABILITIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, init_req_key)) - resp_net_event_nc = autils.wait_for_event_with_keys( - resp_dut, cconsts.EVENT_NETWORK_CALLBACK, - autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_CAPABILITIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, resp_req_key)) - - # validate no leak of information - asserts.assert_false( - cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in init_net_event_nc[ - "data"], "Network specifier leak!") - asserts.assert_false( - cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in resp_net_event_nc[ - "data"], "Network specifier leak!") - - # note that Init <-> Resp since IPv6 are of peer's! - init_ipv6 = resp_net_event_nc["data"][aconsts.NET_CAP_IPV6] - resp_ipv6 = init_net_event_nc["data"][aconsts.NET_CAP_IPV6] - - init_net_event_lp = 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_lp = 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_lp["data"][ - cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - resp_aware_if = resp_net_event_lp["data"][ - cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - - 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) - - # open sockets to test connection - asserts.assert_true( - autils.verify_socket_connect(init_dut, resp_dut, init_ipv6, - resp_ipv6, 0), - "Failed socket link with Initiator as Server") - asserts.assert_true( - autils.verify_socket_connect(resp_dut, init_dut, resp_ipv6, - init_ipv6, 0), - "Failed socket link with Responder as Server") - - # 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: - # - expect unavailable callbacks on the party with the bad ID - # - also expect unavailable on the Initiator party (i.e. the - # Subscriber) if the Publisher has a bad ID - # - but a Publisher with a valid ID will keep waiting ... - autils.wait_for_event_with_keys( - s_dut, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_UNAVAILABLE)) - if pub_mismatch: - autils.wait_for_event_with_keys( - p_dut, cconsts.EVENT_NETWORK_CALLBACK, - autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_UNAVAILABLE)) - else: - 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)) - - # 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: - init_mismatch_mac: True to mismatch the Initiator MAC address - resp_mismatch_mac: True to mismatch the Responder MAC address - 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: - # - expect unavailable on the Initiator party if the - # Initiator or Responder has a bad ID - # - but a Responder will keep waiting ... - autils.wait_for_event_with_keys( - init_dut, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, cconsts.NETWORK_CB_UNAVAILABLE)) - time.sleep(autils.EVENT_NDP_TIMEOUT) - autils.fail_on_event_with_keys( - resp_dut, cconsts.EVENT_NETWORK_CALLBACK, 0, - (cconsts.NETWORK_CB_KEY_ID, init_req_key)) - - # clean-up - resp_dut.droid.connectivityUnregisterNetworkCallback(resp_req_key) - init_dut.droid.connectivityUnregisterNetworkCallback(init_req_key) - - def verify_network_info(self, p_data, s_data, open, port, - transport_protocol): - """Verify that the port and transport protocol information is correct. - - should only exist on subscriber (received from publisher) - and match transmitted values - - should only exist on an encrypted NDP - - Args: - p_data, s_data: Pub and Sub (respectively) net cap event data. - open: True if NDP unencrypted, False if encrypted. - port: Expected port value. - transport_protocol: Expected transport protocol value. - """ - asserts.assert_true(aconsts.NET_CAP_PORT not in p_data, - "port info not expected on Pub") - asserts.assert_true(aconsts.NET_CAP_TRANSPORT_PROTOCOL not in p_data, - "transport protocol info not expected on Pub") - if open: - asserts.assert_true(aconsts.NET_CAP_PORT not in s_data, - "port info not expected on Sub (open NDP)") - asserts.assert_true( - aconsts.NET_CAP_TRANSPORT_PROTOCOL not in s_data, - "transport protocol info not expected on Sub (open NDP)") - else: - asserts.assert_equal(s_data[aconsts.NET_CAP_PORT], port, - "Port info does not match on Sub (from Pub)") - asserts.assert_equal( - s_data[aconsts.NET_CAP_TRANSPORT_PROTOCOL], transport_protocol, - "Transport protocol info does not match on Sub (from Pub)") - - ####################################### - # 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) - - @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) - - @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) - - @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) - - @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) - - @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) - - @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) - - @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) - - @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) - - @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) - - @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) - - @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. - - 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. - - 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. - - 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. - - 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 - - Verifies end-to-end discovery + data-path creation. - """ - 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 - - Verifies end-to-end discovery + data-path creation. - """ - 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 - - Verifies end-to-end discovery + data-path creation. - """ - 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 - - Verifies end-to-end discovery + data-path creation. - """ - 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 - - Verifies end-to-end discovery + data-path creation. - """ - 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 - - Verifies end-to-end discovery + data-path creation. - """ - 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: - 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: - 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) - - ############################################################## - - @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) - - @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, aware_ipv6): - """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 - aware_ipv6: (out) A list into which to append the network ipv6 address - """ - num_events = 0 # looking for 2 events per NDP: link-prop + net-cap - while num_events != 2 * 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) - elif (event["data"][cconsts.NETWORK_CB_KEY_EVENT] == - cconsts.NETWORK_CB_CAPABILITIES_CHANGED): - if event["data"][cconsts.NETWORK_CB_KEY_ID] in req_keys: - num_events = num_events + 1 - aware_ipv6.append(event["data"][aconsts.NET_CAP_IPV6]) - else: - self.log.info( - "Received an unexpected connectivity, the revoked " - "network request probably went through -- %s", event) - # validate no leak of information - asserts.assert_false( - cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in event["data"], - "Network specifier leak!") - - @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 = [] - resp_aware_ipv6 = [] - init_aware_ipv6 = [] - - # 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 - # note: for IPv6 Init <--> Resp since each reports the other's IPv6 address - # in it's transport-specific network info - self.wait_for_request_responses(resp_dut, resp_req_keys, - resp_aware_ifs, init_aware_ipv6) - self.wait_for_request_responses(init_dut, init_req_keys, - init_aware_ifs, resp_aware_ipv6) - - # 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, init_aware_ipv6) - self.wait_for_request_responses(init_dut, init_req_keys[N - 1:], - init_aware_ifs, resp_aware_ipv6) - - # determine whether all interfaces and ipv6 addresses are identical - # (single NDP) - init_aware_ifs = list(set(init_aware_ifs)) - resp_aware_ifs = list(set(resp_aware_ifs)) - init_aware_ipv6 = list(set(init_aware_ipv6)) - resp_aware_ipv6 = list(set(resp_aware_ipv6)) - - self.log.info("Interface names: I=%s, R=%s", init_aware_ifs, - resp_aware_ifs) - self.log.info("Interface IPv6: I=%s, R=%s", init_aware_ipv6, - resp_aware_ipv6) - 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") - asserts.assert_equal( - len(init_aware_ipv6), 1, "Multiple initiator IPv6 addresses") - asserts.assert_equal( - len(resp_aware_ipv6), 1, "Multiple responder IPv6 addresses") - - for i in range( - init_dut.aware_capabilities[aconsts.CAP_MAX_NDI_INTERFACES]): - # note: using get_ipv6_addr (ifconfig method) since want to verify - # that interfaces which do not have any NDPs on them do not have - # an IPv6 link-local address. - 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_nc = autils.wait_for_event_with_keys( - dut2, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_CAPABILITIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, req_a_resp)) - req_a_init_event_nc = autils.wait_for_event_with_keys( - dut1, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_CAPABILITIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, req_a_init)) - - # validate no leak of information - asserts.assert_false( - cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in req_a_resp_event_nc[ - "data"], "Network specifier leak!") - asserts.assert_false( - cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in req_a_init_event_nc[ - "data"], "Network specifier leak!") - - # note that Init <-> Resp since IPv6 are of peer's! - req_a_ipv6_init = req_a_resp_event_nc["data"][aconsts.NET_CAP_IPV6] - req_a_ipv6_resp = req_a_init_event_nc["data"][aconsts.NET_CAP_IPV6] - - req_a_resp_event_lp = 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_lp = 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_lp["data"][ - cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - req_a_if_init = req_a_init_event_lp["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) - 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_nc = autils.wait_for_event_with_keys( - dut1, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_CAPABILITIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, req_b_resp)) - req_b_init_event_nc = autils.wait_for_event_with_keys( - dut2, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_CAPABILITIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, req_b_init)) - - # validate no leak of information - asserts.assert_false( - cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in req_b_resp_event_nc[ - "data"], "Network specifier leak!") - asserts.assert_false( - cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in req_b_init_event_nc[ - "data"], "Network specifier leak!") - - # note that Init <-> Resp since IPv6 are of peer's! - req_b_ipv6_init = req_b_resp_event_nc["data"][aconsts.NET_CAP_IPV6] - req_b_ipv6_resp = req_b_init_event_nc["data"][aconsts.NET_CAP_IPV6] - - req_b_resp_event_lp = 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_lp = 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_lp["data"][ - cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - req_b_if_init = req_b_init_event_lp["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) - 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 - - String: passphrase - - otherwise: PMK (byte array) - - Args: - sec_configs: list of security configurations - flip_init_resp: if True the roles of Initiator and Responder are flipped - 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_ipv6s = [] - dut1_aware_ipv6s = [] - - 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_nc = autils.wait_for_event_with_keys( - dut1, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_CAPABILITIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, dut1_req_key)) - dut2_net_event_nc = autils.wait_for_event_with_keys( - dut2, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_CAPABILITIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, dut2_req_key)) - - # validate no leak of information - asserts.assert_false( - cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in dut1_net_event_nc[ - "data"], "Network specifier leak!") - asserts.assert_false( - cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in dut2_net_event_nc[ - "data"], "Network specifier leak!") - - # Note: dut1 <--> dut2 IPv6's addresses since it is peer's info - dut2_aware_ipv6 = dut1_net_event_nc["data"][aconsts.NET_CAP_IPV6] - dut1_aware_ipv6 = dut2_net_event_nc["data"][aconsts.NET_CAP_IPV6] - - dut1_net_event_lp = 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_lp = 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_lp["data"][ - cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - dut1_aware_if = dut1_net_event_lp["data"][ - cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - - dut2_aware_ifs.append(dut2_aware_if) - dut1_aware_ifs.append(dut1_aware_if) - dut2_aware_ipv6s.append(dut2_aware_ipv6) - dut1_aware_ipv6s.append(dut1_aware_ipv6) - - 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_ipv6s = list(set(dut1_aware_ipv6s)) - dut2_aware_ipv6s = list(set(dut2_aware_ipv6s)) - - 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_ipv6s, - dut2_aware_ipv6s) - 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_ipv6s), len(sec_configs), - "Multiple DUT1 IPv6 addresses") - asserts.assert_equal( - len(dut2_aware_ipv6s), len(sec_configs), - "Multiple DUT2 IPv6 addresses") - - for i in range(len(sec_configs)): - # note: using get_ipv6_addr (ifconfig method) since want to verify - # that the system information is the same as the reported information - 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]) - - @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]) - - @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]) - - @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]) - - @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]) - - @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) - - @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) - - @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) - - @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) - - @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) - - ####################################### - - @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 - 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 - works (the result should be run in Channel 6 - but that is not tested). - - Args: - use_ib: True to use in-band discovery, False to use out-of-band discovery. - 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] - - wutils.set_wifi_country_code(init_dut, init_domain) - wutils.set_wifi_country_code(resp_dut, 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) - - @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) - - @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) - - @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) - - ######################################################################## - - 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 - expected, if True, or whether multiple NDPs on different NDIs are expected, - if False. - - Args: - same_request: Issue canonically identical requests (same NMI peer, same - passphrase) if True, if False use different passphrases. - ib_first: If True then the in-band network is requested first, otherwise - (if False) then the out-of-band network is requested first. - inits_on_same_dut: If True then the Initiators are run on the same device, - 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_nc = autils.wait_for_event_with_keys( - p_dut, cconsts.EVENT_NETWORK_CALLBACK, - autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_CAPABILITIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, p_req_key)) - s_net_event_nc = autils.wait_for_event_with_keys( - s_dut, cconsts.EVENT_NETWORK_CALLBACK, - autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_CAPABILITIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, s_req_key)) - p_net_event_lp = 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_lp = 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)) - - # validate no leak of information - asserts.assert_false( - cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in p_net_event_nc[ - "data"], "Network specifier leak!") - asserts.assert_false( - cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in s_net_event_nc[ - "data"], "Network specifier leak!") - - # 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_nc = autils.wait_for_event_with_keys( - resp_dut, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_CAPABILITIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, resp_req_key)) - init_net_event_nc = autils.wait_for_event_with_keys( - init_dut, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_CAPABILITIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, init_req_key)) - resp_net_event_lp = 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_lp = 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)) - - # validate no leak of information - asserts.assert_false( - cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in resp_net_event_nc[ - "data"], "Network specifier leak!") - asserts.assert_false( - cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in init_net_event_nc[ - "data"], "Network specifier leak!") - - 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_nc = autils.wait_for_event_with_keys( - p_dut, cconsts.EVENT_NETWORK_CALLBACK, - autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_CAPABILITIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, p_req_key)) - s_net_event_nc = autils.wait_for_event_with_keys( - s_dut, cconsts.EVENT_NETWORK_CALLBACK, - autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_CAPABILITIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, s_req_key)) - p_net_event_lp = 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_lp = 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)) - - # validate no leak of information - asserts.assert_false( - cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in p_net_event_nc[ - "data"], "Network specifier leak!") - asserts.assert_false( - cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in s_net_event_nc[ - "data"], "Network specifier leak!") - - # note that Init <-> Resp & Pub <--> Sub since IPv6 are of peer's! - init_ipv6 = resp_net_event_nc["data"][aconsts.NET_CAP_IPV6] - resp_ipv6 = init_net_event_nc["data"][aconsts.NET_CAP_IPV6] - pub_ipv6 = s_net_event_nc["data"][aconsts.NET_CAP_IPV6] - sub_ipv6 = p_net_event_nc["data"][aconsts.NET_CAP_IPV6] - - # extract net info - pub_interface = p_net_event_lp["data"][ - cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - sub_interface = s_net_event_lp["data"][ - cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - resp_interface = resp_net_event_lp["data"][ - cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - init_interface = init_net_event_lp["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) - 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) - - @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) - - @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) - - @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) - - @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) - - @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) - - @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) - - @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) - - ######################################################################## - - 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 - B - C - C - A - - 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) - reqs.append([]) - ifs.append([]) - ipv6s.append([]) - - # 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 deleted file mode 100644 index 5f01c80eb7..0000000000 --- a/acts/tests/google/wifi/aware/functional/DiscoveryTest.py +++ /dev/null @@ -1,1070 +0,0 @@ -#!/usr/bin/python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import string -import time - -from acts import asserts -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi.aware import aware_const as aconsts -from acts.test_utils.wifi.aware import aware_test_utils as autils -from acts.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest - - -class DiscoveryTest(AwareBaseTest): - """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 - - # 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 - - 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 - is_publish: True if a publish config, else False - ptype: unsolicited or solicited (used if is_publish is True) - stype: passive or active (used if is_publish is False) - payload_size: min, typical, max (PAYLOAD_SIZE_xx) - ttl: time-to-live configuration (0 - forever) - term_ind_on: is termination indication enabled - null_match: null-out the middle match filter - 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[:: - -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. - - Args: - caps: device capability dictionary - ptype: unsolicited or solicited - payload_size: min, typical, max (PAYLOAD_SIZE_xx) - ttl: time-to-live configuration (0 - forever) - term_ind_on: is termination indication enabled - null_match: null-out the middle match filter - Returns: - publish discovery configuration object. - """ - 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. - - Args: - caps: device capability dictionary - stype: passive or active - payload_size: min, typical, max (PAYLOAD_SIZE_xx) - ttl: time-to-live configuration (0 - forever) - term_ind_on: is termination indication enabled - null_match: null-out the middle match filter - Returns: - subscribe discovery configuration object. - """ - 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: - - Discovery (publish/subscribe) with TTL=0 (non-self-terminating) - - Exchange messages - - Update publish/subscribe - - Terminate - - Args: - ptype: Publish discovery type - 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") - asserts.assert_equal( - peer_id_on_sub, - discovery_event["data"][aconsts.SESSION_CB_KEY_PEER_ID], - "Peer ID changed when publish was updated!?") - - # 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: - dut: device under test - disc_id: discovery id for the existing session - config: configuration of the existing session - 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 - - Iteration 1: Verify session started with TTL - Iteration 2: Verify session started without TTL and reconfigured with TTL - Iteration 3: Verify session started with (long) TTL and reconfigured with - (short) TTL - - Args: - is_publish: True if testing publish, False if testing subscribe - ptype: Publish discovery type (used if is_publish is True) - 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 - configs. - - Args: - is_expected_to_pass: True if positive test, False if negative - p_type: Publish discovery type - s_type: Subscribe discovery type - p_service_name: Publish service name (or None to leave unchanged) - s_service_name: Subscribe service name (or None to leave unchanged) - 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: - - 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: - - 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: - - 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: - - 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: - - 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: - - 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: - - 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: - - 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: - - 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: - - 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: - - 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: - - 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: - - 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: - - 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 - - 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 - - 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 - - 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 - - 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 - - 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 - - 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: - - DUT1 & DUT2 running Publish for X - - DUT1 & DUT2 running Publish for Y - - DUT1 Subscribes for X - - DUT2 Subscribes for Y - Message exchanges. - - Note: test requires that devices support 2 publish sessions concurrently. - The test will be skipped if the devices are not capable. - - Args: - 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 & DUT2 running Publish for X - - DUT1 & DUT2 running Publish for Y - - DUT1 Subscribes for X - - DUT2 Subscribes for Y - Message exchanges. - - Both sessions are Unsolicited/Passive. - - 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. - - DUT1 & DUT2 running Publish for X - - DUT1 & DUT2 running Publish for Y - - DUT1 Subscribes for X - - DUT2 Subscribes for Y - Message exchanges. - - Both sessions are Solicited/Active. - - 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. - - DUT1 & DUT2 running Publish for X - - DUT1 & DUT2 running Publish for Y - - DUT1 Subscribes for X - - DUT2 Subscribes for Y - Message exchanges. - - Session A is Unsolicited/Passive. - Session B is Solicited/Active. - - 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 - 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) diff --git a/acts/tests/google/wifi/aware/functional/MacRandomNoLeakageTest.py b/acts/tests/google/wifi/aware/functional/MacRandomNoLeakageTest.py deleted file mode 100644 index 074ca48826..0000000000 --- a/acts/tests/google/wifi/aware/functional/MacRandomNoLeakageTest.py +++ /dev/null @@ -1,254 +0,0 @@ -#!/usr/bin/python3.4 -# -# Copyright 2019 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from acts import asserts -from acts.test_decorators import test_tracker_info -from acts.test_utils.net import connectivity_const as cconsts -from acts.test_utils.wifi.aware import aware_const as aconsts -from acts.controllers.ap_lib.hostapd_constants import BAND_2G -from acts.controllers.ap_lib.hostapd_constants import BAND_5G -from acts.test_utils.wifi.aware import aware_test_utils as autils -from acts.test_utils.wifi import wifi_test_utils as wutils -from acts.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest -from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest -from scapy.all import * - - -class MacRandomNoLeakageTest(AwareBaseTest, WifiBaseTest): - """Set of tests for Wi-Fi Aware MAC address randomization of NMI (NAN - management interface) and NDI (NAN data interface).""" - - SERVICE_NAME = "GoogleTestServiceXYZ" - ping_msg = 'PING' - - AWARE_DEFAULT_CHANNEL_5_BAND = 149 - AWARE_DEFAULT_CHANNEL_24_BAND = 6 - - ENCR_TYPE_OPEN = 0 - ENCR_TYPE_PASSPHRASE = 1 - ENCR_TYPE_PMK = 2 - - PASSPHRASE = "This is some random passphrase - very very secure!!" - PMK = "ODU0YjE3YzdmNDJiNWI4NTQ2NDJjNDI3M2VkZTQyZGU=" - - def setup_class(self): - super().setup_class() - - asserts.assert_true(hasattr(self, 'packet_capture'), - "Needs packet_capture attribute to support sniffing.") - self.configure_packet_capture(channel_5g=self.AWARE_DEFAULT_CHANNEL_5_BAND, - channel_2g=self.AWARE_DEFAULT_CHANNEL_24_BAND) - - def setup_test(self): - WifiBaseTest.setup_test(self) - AwareBaseTest.setup_test(self) - - def teardown_test(self): - WifiBaseTest.teardown_test(self) - AwareBaseTest.teardown_test(self) - - def verify_mac_no_leakage(self, pcap_procs, factory_mac_addresses, mac_addresses): - # Get 2G and 5G pcaps - pcap_fname = '%s_%s.pcap' % (pcap_procs[BAND_5G][1], BAND_5G.upper()) - pcap_5g = rdpcap(pcap_fname) - - pcap_fname = '%s_%s.pcap' % (pcap_procs[BAND_2G][1], BAND_2G.upper()) - pcap_2g = rdpcap(pcap_fname) - pcaps = pcap_5g + pcap_2g - - # Verify factory MAC is not leaked in both 2G and 5G pcaps - for mac in factory_mac_addresses: - wutils.verify_mac_not_found_in_pcap(mac, pcaps) - - # Verify random MACs are being used and in pcaps - for mac in mac_addresses: - wutils.verify_mac_is_found_in_pcap(mac, pcaps) - - def transfer_mac_format(self, mac): - """add ':' to mac String, and transfer to lower case - - Args: - mac: String of mac without ':' - @return: Lower case String of mac like "xx:xx:xx:xx:xx:xx" - """ - return re.sub(r"(?<=\w)(?=(?:\w\w)+$)", ":", mac.lower()) - - def start_aware(self, dut, is_publish): - """Start Aware attach, then start Publish/Subscribe based on role - - Args: - dut: Aware device - is_publish: True for Publisher, False for subscriber - @:return: dict with Aware discovery session info - """ - aware_id = dut.droid.wifiAwareAttach(True) - autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) - event = autils.wait_for_event(dut, aconsts.EVENT_CB_ON_IDENTITY_CHANGED) - mac = self.transfer_mac_format(event["data"]["mac"]) - dut.log.info("NMI=%s", mac) - - if is_publish: - config = autils.create_discovery_config(self.SERVICE_NAME, - aconsts.PUBLISH_TYPE_UNSOLICITED) - disc_id = dut.droid.wifiAwarePublish(aware_id, config) - autils.wait_for_event(dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED) - else: - config = autils.create_discovery_config(self.SERVICE_NAME, - aconsts.SUBSCRIBE_TYPE_PASSIVE) - disc_id = dut.droid.wifiAwareSubscribe(aware_id, config) - autils.wait_for_event(dut, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED) - aware_session = {"awareId": aware_id, "discId": disc_id, "mac": mac} - return aware_session - - def create_date_path(self, p_dut, pub_session, s_dut, sub_session, sec_type): - """Create NDP based on the security type(open, PMK, PASSPHRASE), run socket connect - - Args: - p_dut: Publish device - p_disc_id: Publisher discovery id - peer_id_on_pub: peer id on publisher - s_dut: Subscribe device - s_disc_id: Subscriber discovery id - peer_id_on_sub: peer id on subscriber - sec_type: NDP security type(open, PMK or PASSPHRASE) - @:return: dict with NDP info - """ - - passphrase = None - pmk = None - - if sec_type == self.ENCR_TYPE_PASSPHRASE: - passphrase = self.PASSPHRASE - if sec_type == self.ENCR_TYPE_PMK: - pmk = self.PMK - - p_req_key = autils.request_network( - p_dut, - p_dut.droid.wifiAwareCreateNetworkSpecifier(pub_session["discId"], - None, - passphrase, pmk)) - s_req_key = autils.request_network( - s_dut, - s_dut.droid.wifiAwareCreateNetworkSpecifier(sub_session["discId"], - sub_session["peerId"], - passphrase, pmk)) - - p_net_event_nc = autils.wait_for_event_with_keys( - p_dut, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_CAPABILITIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, p_req_key)) - s_net_event_nc = autils.wait_for_event_with_keys( - s_dut, cconsts.EVENT_NETWORK_CALLBACK, autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_CAPABILITIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, s_req_key)) - p_net_event_lp = 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_lp = 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_lp["data"][cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - s_aware_if = s_net_event_lp["data"][cconsts.NETWORK_CB_KEY_INTERFACE_NAME] - p_if_mac = self.transfer_mac_format(autils.get_mac_addr(p_dut, p_aware_if)) - p_dut.log.info("NDI %s=%s", p_aware_if, p_if_mac) - s_if_mac = self.transfer_mac_format(autils.get_mac_addr(s_dut, s_aware_if)) - s_dut.log.info("NDI %s=%s", s_aware_if, s_if_mac) - - s_ipv6 = p_net_event_nc["data"][aconsts.NET_CAP_IPV6] - p_ipv6 = s_net_event_nc["data"][aconsts.NET_CAP_IPV6] - asserts.assert_true( - autils.verify_socket_connect(p_dut, s_dut, p_ipv6, s_ipv6, 0), - "Failed socket link with Pub as Server") - asserts.assert_true( - autils.verify_socket_connect(s_dut, p_dut, s_ipv6, p_ipv6, 0), - "Failed socket link with Sub as Server") - - ndp_info = {"pubReqKey": p_req_key, "pubIfMac": p_if_mac, - "subReqKey": s_req_key, "subIfMac": s_if_mac} - return ndp_info - - @test_tracker_info(uuid="c9c66873-a8e0-4830-8baa-ada03223bcef") - def test_ib_multi_data_path_mac_random_test(self): - """Verify there is no factory MAC Address leakage during the Aware discovery, NDP creation, - socket setup and IP service connection.""" - - p_dut = self.android_devices[0] - s_dut = self.android_devices[1] - mac_addresses = [] - factory_mac_addresses = [] - sec_types = [self.ENCR_TYPE_PMK, self.ENCR_TYPE_PASSPHRASE] - - self.log.info("Starting packet capture") - pcap_procs = wutils.start_pcap( - self.packet_capture, 'dual', self.test_name) - - factory_mac_1 = p_dut.droid.wifigetFactorymacAddresses()[0] - p_dut.log.info("Factory Address: %s", factory_mac_1) - factory_mac_2 = s_dut.droid.wifigetFactorymacAddresses()[0] - s_dut.log.info("Factory Address: %s", factory_mac_2) - factory_mac_addresses.append(factory_mac_1) - factory_mac_addresses.append(factory_mac_2) - - # Start Aware and exchange messages - publish_session = self.start_aware(p_dut, True) - subscribe_session = self.start_aware(s_dut, False) - mac_addresses.append(publish_session["mac"]) - mac_addresses.append(subscribe_session["mac"]) - discovery_event = autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) - subscribe_session["peerId"] = discovery_event['data'][aconsts.SESSION_CB_KEY_PEER_ID] - - msg_id = self.get_next_msg_id() - s_dut.droid.wifiAwareSendMessage(subscribe_session["discId"], subscribe_session["peerId"], - msg_id, self.ping_msg, aconsts.MAX_TX_RETRIES) - autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_MESSAGE_SENT) - pub_rx_msg_event = autils.wait_for_event(p_dut, aconsts.SESSION_CB_ON_MESSAGE_RECEIVED) - publish_session["peerId"] = pub_rx_msg_event['data'][aconsts.SESSION_CB_KEY_PEER_ID] - - msg_id = self.get_next_msg_id() - p_dut.droid.wifiAwareSendMessage(publish_session["discId"], publish_session["peerId"], - msg_id, self.ping_msg, aconsts.MAX_TX_RETRIES) - autils.wait_for_event(p_dut, aconsts.SESSION_CB_ON_MESSAGE_SENT) - autils.wait_for_event(s_dut, aconsts.SESSION_CB_ON_MESSAGE_RECEIVED) - - # Create Aware NDP - p_req_keys = [] - s_req_keys = [] - for sec in sec_types: - ndp_info = self.create_date_path(p_dut, publish_session, s_dut, subscribe_session, sec) - p_req_keys.append(ndp_info["pubReqKey"]) - s_req_keys.append(ndp_info["subReqKey"]) - mac_addresses.append(ndp_info["pubIfMac"]) - mac_addresses.append(ndp_info["subIfMac"]) - - # clean-up - for p_req_key in p_req_keys: - p_dut.droid.connectivityUnregisterNetworkCallback(p_req_key) - for s_req_key in s_req_keys: - s_dut.droid.connectivityUnregisterNetworkCallback(s_req_key) - p_dut.droid.wifiAwareDestroyAll() - s_dut.droid.wifiAwareDestroyAll() - - self.log.info("Stopping packet capture") - wutils.stop_pcap(self.packet_capture, pcap_procs, False) - - self.verify_mac_no_leakage(pcap_procs, factory_mac_addresses, mac_addresses) diff --git a/acts/tests/google/wifi/aware/functional/MacRandomTest.py b/acts/tests/google/wifi/aware/functional/MacRandomTest.py deleted file mode 100644 index 6c8d5b1c8a..0000000000 --- a/acts/tests/google/wifi/aware/functional/MacRandomTest.py +++ /dev/null @@ -1,139 +0,0 @@ -#!/usr/bin/python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import time - -from acts import asserts -from acts.test_decorators import test_tracker_info -from acts.test_utils.net import connectivity_const as cconsts -from acts.test_utils.wifi.aware import aware_const as aconsts -from acts.test_utils.wifi.aware import aware_test_utils as autils -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 - management interface) and NDI (NAN data interface).""" - - 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 - - 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) - - ########################################################################## - - @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 - 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) diff --git a/acts/tests/google/wifi/aware/functional/MatchFilterTest.py b/acts/tests/google/wifi/aware/functional/MatchFilterTest.py deleted file mode 100644 index e008e12ae0..0000000000 --- a/acts/tests/google/wifi/aware/functional/MatchFilterTest.py +++ /dev/null @@ -1,190 +0,0 @@ -#!/usr/bin/python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import base64 -import time -import queue - -from acts import asserts -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi.aware import aware_const as aconsts -from acts.test_utils.wifi.aware import aware_test_utils as autils -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 - 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 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: - p_dut: Device to use as publisher. - s_dut: Device to use as subscriber. - p_mf: Publish's match filter. - s_mf: Subscriber's match filter. - do_unsolicited_passive: True to use an Unsolicited/Passive discovery, - False for a Solicited/Active discovery session. - 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, - 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={"data": 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) - - @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) diff --git a/acts/tests/google/wifi/aware/functional/MessageTest.py b/acts/tests/google/wifi/aware/functional/MessageTest.py deleted file mode 100644 index 9bfb932b31..0000000000 --- a/acts/tests/google/wifi/aware/functional/MessageTest.py +++ /dev/null @@ -1,459 +0,0 @@ -#!/usr/bin/python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import string -import time - -from acts import asserts -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi.aware import aware_const as aconsts -from acts.test_utils.wifi.aware import aware_test_utils as autils -from acts.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest - - -class MessageTest(AwareBaseTest): - """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 - - NUM_MSGS_NO_QUEUE = 10 - NUM_MSGS_QUEUE_DEPTH_MULT = 2 # number of messages = mult * queue depth - - def create_msg(self, caps, payload_size, id): - """Creates a message string of the specified size containing the input id. - - Args: - caps: Device capabilities. - payload_size: The size of the message to create - min (null or empty - message), typical, max (based on device capabilities). Use - the PAYLOAD_SIZE_xx constants. - id: Information to include in the generated message (or None). - - 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. - - Args: - is_publish: True for publish, False for subscribe sessions. - extra_diff: String to add to service name: allows differentiating - discovery sessions. - - 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 - service discovery - at that point the sessions are ready for message - exchange. - - Args: - 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 - 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 - received as expected. Method is called after the messages are sent into - the transmission queue. - - Note: that message can be transmitted and received out-of-order (which is - acceptable and the method handles that correctly). - - Args: - tx_msgs: dictionary of transmitted messages - tx_msg_ids: dictionary of transmitted message ids - tx_disc_id: transmitter discovery session id (None for no decoration) - rx_disc_id: receiver discovery session id (None for no decoration) - tx_dut: transmitter device - rx_dut: receiver device - are_msgs_empty: True if the messages are None or empty (changes dup detection) - - 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 - 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 - 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. - - 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 - - Minimal payload size (None or "") - """ - 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 - - Typical payload size - """ - 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 - - Max payload size (based on device capabilities) - """ - 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 - - Minimal payload size (none or "") - """ - 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 - - Typical payload size - """ - 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 - - Max payload size (based on device capabilities) - """ - 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 - - 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) diff --git a/acts/tests/google/wifi/aware/functional/NonConcurrencyTest.py b/acts/tests/google/wifi/aware/functional/NonConcurrencyTest.py deleted file mode 100644 index f0286f25a3..0000000000 --- a/acts/tests/google/wifi/aware/functional/NonConcurrencyTest.py +++ /dev/null @@ -1,184 +0,0 @@ -#!/usr/bin/python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from acts import asserts -import queue -from acts import utils -from acts.test_utils.wifi import wifi_test_utils as wutils -from acts.test_utils.wifi import wifi_constants as wconsts -from acts.test_utils.wifi.aware import aware_const as aconsts -from acts.test_utils.wifi.aware import aware_test_utils as autils -from acts.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest - -# arbitrary timeout for events -EVENT_TIMEOUT = 10 - - -class NonConcurrencyTest(AwareBaseTest): - """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" - - 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 - Aware-incompatible service is started. - - Args: - is_p2p: True for p2p, False for SoftAP - """ - dut = self.android_devices[0] - - # 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) - - # 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) - - 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] - - # 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) - - # 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) - - # 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) - - def run_aware_then_connect_to_new_ap(self): - """Validate interaction of Wi-Fi Aware and infra (STA) association with randomized MAC - address. Such an association may trigger interface down and up - possibly disrupting a Wi-Fi - Aware session. - - Test behavior: - - Start Aware - - Associate STA - - Check if an Aware state change Broadcast received - - If necessary (Broadcast received) restart Aware - - Start publish - - Start Subscribe on peer - - Verify discovery - """ - dut = self.android_devices[0] - dut_ap = self.android_devices[1] - wutils.reset_wifi(dut) - wutils.reset_wifi(dut_ap) - 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) - - # create random SSID and start softAp on dut_ap - ap_ssid = self.TETHER_SSID + utils.rand_ascii_str(8) - ap_password = utils.rand_ascii_str(8) - config = {wutils.WifiEnums.SSID_KEY: ap_ssid, wutils.WifiEnums.PWD_KEY: ap_password} - wutils.start_wifi_tethering(dut_ap, ap_ssid, ap_password) - asserts.assert_true(dut_ap.droid.wifiIsApEnabled(), - "SoftAp is not reported as running") - - # dut start Aware attach and connect to softAp on dut_ap - p_id = dut.droid.wifiAwareAttach() - autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) - - wutils.wifi_connect(dut, config, check_connectivity=False) - autils.wait_for_event(dut, wconsts.WIFI_STATE_CHANGED) - - # Check if the WifiAwareState changes then restart the Aware - try: - dut.ed.pop_event(aconsts.BROADCAST_WIFI_AWARE_AVAILABLE, EVENT_TIMEOUT) - dut.log.info(aconsts.BROADCAST_WIFI_AWARE_AVAILABLE) - p_id = dut.droid.wifiAwareAttach() - autils.wait_for_event(dut, aconsts.EVENT_CB_ON_ATTACHED) - except queue.Empty: - dut.log.info('WifiAware state was not changed') - - # dut start Publish - p_disc_id = dut.droid.wifiAwarePublish(p_id, p_config) - autils.wait_for_event(dut, aconsts.SESSION_CB_ON_PUBLISH_STARTED) - - # dut_ap stop softAp and start Subscribe - wutils.stop_wifi_tethering(dut_ap) - autils.wait_for_event(dut_ap, aconsts.BROADCAST_WIFI_AWARE_AVAILABLE) - s_id = dut_ap.droid.wifiAwareAttach() - autils.wait_for_event(dut_ap, aconsts.EVENT_CB_ON_ATTACHED) - s_disc_id = dut_ap.droid.wifiAwareSubscribe(s_id, s_config) - autils.wait_for_event(dut_ap, aconsts.SESSION_CB_ON_SUBSCRIBE_STARTED) - - # Check discovery session - autils.wait_for_event(dut_ap, aconsts.SESSION_CB_ON_SERVICE_DISCOVERED) - - ########################################################################## - - 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_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 - started""" - self.run_aware_then_incompat_service(is_p2p=False) - - def test_run_aware_then_connect_new_ap(self): - """Validate connect new ap during Aware session""" - self.run_aware_then_connect_to_new_ap() diff --git a/acts/tests/google/wifi/aware/functional/ProtocolsTest.py b/acts/tests/google/wifi/aware/functional/ProtocolsTest.py deleted file mode 100644 index 15e84ff1f6..0000000000 --- a/acts/tests/google/wifi/aware/functional/ProtocolsTest.py +++ /dev/null @@ -1,266 +0,0 @@ -#!/usr/bin/python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from acts import asserts -from acts.test_decorators import test_tracker_info -from acts.test_utils.net import nsd_const as nconsts -from acts.test_utils.wifi.aware import aware_const as aconsts -from acts.test_utils.wifi.aware import aware_test_utils as autils -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 - top of a data-path""" - - SERVICE_NAME = "GoogleTestServiceXY" - - def run_ping6(self, dut, peer_ipv6): - """Run a ping6 over the specified device/link - - Args: - dut: Device on which to execute ping6 - peer_ipv6: Scoped IPv6 address of the peer to ping - """ - cmd = "ping6 -c 3 -W 5 %s" % peer_ipv6 - 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 - 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) - self.run_ping6(resp_dut, init_ipv6) - - # 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) - self.run_ping6(s_dut, p_ipv6) - - # 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) - self.run_ping6(s_dut, p_ipv6) - - # 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]) - self.run_ping6(self.android_devices[i + 1], dut_ipv6) - - # 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:] - - # mDNS doesn't seem to return a scoped host so strip it out of the - # local result (for now) - scope_index = init_ipv6.find("%") - if scope_index != -1: - init_ipv6 = init_ipv6[:scope_index] - - 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/functional/functional b/acts/tests/google/wifi/aware/functional/functional deleted file mode 100644 index e13a4705e6..0000000000 --- a/acts/tests/google/wifi/aware/functional/functional +++ /dev/null @@ -1,9 +0,0 @@ -AttachTest -DiscoveryTest -MessageTest -DataPathTest -MacRandomTest -CapabilitiesTest -ProtocolsTest -NonConcurrencyTest -MatchFilterTest
\ No newline at end of file diff --git a/acts/tests/google/wifi/aware/ota/ServiceIdsTest.py b/acts/tests/google/wifi/aware/ota/ServiceIdsTest.py deleted file mode 100644 index e29cd713f4..0000000000 --- a/acts/tests/google/wifi/aware/ota/ServiceIdsTest.py +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import time - -from acts import asserts -from acts.test_utils.wifi.aware import aware_const as aconsts -from acts.test_utils.wifi.aware import aware_test_utils as autils -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 - for discovery. - - Note: this test is an OTA (over-the-air) and requires a Sniffer. - """ - - def start_discovery_session(self, dut, session_id, is_publish, dtype, - service_name): - """Start a discovery session - - Args: - dut: Device under test - session_id: ID of the Aware session in which to start discovery - is_publish: True for a publish session, False for subscribe session - dtype: Type of the discovery session - service_name: Service name to use for the discovery session - - 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 - - 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 - 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") diff --git a/acts/tests/google/wifi/aware/ota/ota b/acts/tests/google/wifi/aware/ota/ota deleted file mode 100644 index 27f6724681..0000000000 --- a/acts/tests/google/wifi/aware/ota/ota +++ /dev/null @@ -1 +0,0 @@ -ServiceIdsTest
\ No newline at end of file diff --git a/acts/tests/google/wifi/aware/performance/LatencyTest.py b/acts/tests/google/wifi/aware/performance/LatencyTest.py deleted file mode 100644 index 8ebff89ab6..0000000000 --- a/acts/tests/google/wifi/aware/performance/LatencyTest.py +++ /dev/null @@ -1,825 +0,0 @@ -#!/usr/bin/python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import queue -import time - -from acts import asserts -from acts.test_utils.net import connectivity_const as cconsts -from acts.test_utils.wifi.aware import aware_const as aconsts -from acts.test_utils.wifi.aware import aware_test_utils as autils -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" - - # 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 start_discovery_session(self, dut, session_id, is_publish, dtype): - """Start a discovery session - - Args: - dut: Device under test - session_id: ID of the Aware session in which to start discovery - is_publish: True for a publish session, False for subscribe session - dtype: Type of the discovery session - - 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. - 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 - accurate). - - Args: - results: Result array to be populated - will add results (not erase it) - do_unsolicited_passive: True for unsolicited/passive, False for - solicited/active. - dw_24ghz: DW interval in the 2.4GHz band. - dw_5ghz: DW interval in the 5GHz band. - 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. - - Args: - results: Result array to be populated - will add results (not erase it) - do_unsolicited_passive: True for unsolicited/passive, False for - solicited/active. - 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. - - 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. - - 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: - - Start Aware - - Discovery - - Message from Sub -> Pub - - Message from Pub -> Sub - - NDP setup - - 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. - startup_offset: The start-up gap (in seconds) between the two devices - 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( - 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, - 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 - 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 - 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 = {} - 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 - 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 - 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 - 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 - 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: - - 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 - the initial synchronization: - - Start Aware & synchronize initially - - Loop: - - 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=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 deleted file mode 100644 index a90734d7d7..0000000000 --- a/acts/tests/google/wifi/aware/performance/ThroughputTest.py +++ /dev/null @@ -1,408 +0,0 @@ -#!/usr/bin/python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import json -import pprint -import queue -import threading -import time - -from acts import asserts -from acts.test_utils.net import connectivity_const as cconsts -from acts.test_utils.wifi.aware import aware_const as aconsts -from acts.test_utils.wifi.aware import aware_test_utils as autils -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.""" - - SERVICE_NAME = "GoogleTestServiceXYZ" - - PASSPHRASE = "This is some random passphrase - very very secure!!" - PASSPHRASE2 = "This is some random passphrase - very very secure - but diff!!" - - 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) - - 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" % init_ipv6, "-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 - dut: The DUT on which to run the iperf server command. - peer_dut: The DUT on which to run the iperf client command. - peer_aware_if: The interface on the DUT. - 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 = peer_dut.run_iperf_client("%s" % dut_ipv6, - "-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 - Aware enabled and no infrastructure connection - i.e. device is not - associated to an AP. - - Note: the test requires MAX_NDP + 1 devices to be validated. If these are - not available the test will fail. - - 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 - 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) - - 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) - - 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) - - ######################################################################## - - 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. - - The security configuration can be: - - None: open - - String: passphrase - - otherwise: PMK (byte array) - - Args: - 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_nc = autils.wait_for_event_with_keys( - init_dut, cconsts.EVENT_NETWORK_CALLBACK, - autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_CAPABILITIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, init_req_key)) - resp_net_event_nc = autils.wait_for_event_with_keys( - resp_dut, cconsts.EVENT_NETWORK_CALLBACK, - autils.EVENT_NDP_TIMEOUT, - (cconsts.NETWORK_CB_KEY_EVENT, - cconsts.NETWORK_CB_CAPABILITIES_CHANGED), - (cconsts.NETWORK_CB_KEY_ID, resp_req_key)) - - # validate no leak of information - asserts.assert_false( - cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in init_net_event_nc[ - "data"], "Network specifier leak!") - asserts.assert_false( - cconsts.NETWORK_CB_KEY_NETWORK_SPECIFIER in resp_net_event_nc[ - "data"], "Network specifier leak!") - - # note that Init <-> Resp since IPv6 are of peer's! - resp_ipv6 = init_net_event_nc["data"][aconsts.NET_CAP_IPV6] - init_ipv6 = resp_net_event_nc["data"][aconsts.NET_CAP_IPV6] - - init_net_event_lp = 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_lp = 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_lp["data"][ - cconsts.NETWORK_CB_KEY_INTERFACE_NAME]) - init_aware_ifs.append(init_net_event_lp["data"][ - cconsts.NETWORK_CB_KEY_INTERFACE_NAME]) - - resp_aware_ipv6s.append(resp_ipv6) - init_aware_ipv6s.append(init_ipv6) - - 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) diff --git a/acts/tests/google/wifi/aware/performance/performance b/acts/tests/google/wifi/aware/performance/performance deleted file mode 100644 index 17e39639ed..0000000000 --- a/acts/tests/google/wifi/aware/performance/performance +++ /dev/null @@ -1,2 +0,0 @@ -LatencyTest -ThroughputTest
\ No newline at end of file diff --git a/acts/tests/google/wifi/aware/stress/DataPathStressTest.py b/acts/tests/google/wifi/aware/stress/DataPathStressTest.py deleted file mode 100644 index d2e95df561..0000000000 --- a/acts/tests/google/wifi/aware/stress/DataPathStressTest.py +++ /dev/null @@ -1,243 +0,0 @@ -#!/usr/bin/python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import queue -import time - -from acts import asserts -from acts.test_decorators import test_tracker_info -from acts.test_utils.net import connectivity_const as cconsts -from acts.test_utils.wifi.aware import aware_const as aconsts -from acts.test_utils.wifi.aware import aware_test_utils as autils -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 NDP in each discovery session. - NDP_ITERATIONS = 50 - - # Maximum percentage of NDP setup failures over all iterations - MAX_FAILURE_PERCENTAGE = 1 - - ################################################################ - - 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: - attach_iterations: Number of attach sessions. - ndp_iterations: Number of NDP to be attempted per attach session. - trigger_failure_on_index: Trigger a failure on this NDP iteration (the - mechanism is to request NDP on Initiator - 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 - ndp_full_socket_success = 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)) - - init_ipv6 = None - resp_ipv6 = None - - # Initiator: wait for network formation - got_on_available = False - got_on_link_props = False - got_on_net_cap = False - while not got_on_available or not got_on_link_props or not got_on_net_cap: - 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 - elif (nc_event['data'][cconsts.NETWORK_CB_KEY_EVENT] == - cconsts.NETWORK_CB_CAPABILITIES_CHANGED): - got_on_net_cap = True - if aconsts.NET_CAP_IPV6 in nc_event["data"]: - resp_ipv6 = nc_event["data"][ - aconsts.NET_CAP_IPV6] - 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 and got_on_net_cap: - ndp_init_setup_success = ndp_init_setup_success + 1 - - # Responder: wait for network formation - got_on_available = False - got_on_link_props = False - got_on_net_cap = False - while not got_on_available or not got_on_link_props or not got_on_net_cap: - 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 - elif (nc_event['data'][cconsts.NETWORK_CB_KEY_EVENT] == - cconsts.NETWORK_CB_CAPABILITIES_CHANGED): - got_on_net_cap = True - if aconsts.NET_CAP_IPV6 in nc_event["data"]: - init_ipv6 = nc_event["data"][ - aconsts.NET_CAP_IPV6] - 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 and got_on_net_cap: - ndp_resp_setup_success = ndp_resp_setup_success + 1 - - # open sockets to test connection - if autils.verify_socket_connect(init_dut, resp_dut, init_ipv6, - resp_ipv6, 0): - if autils.verify_socket_connect(resp_dut, init_dut, - resp_ipv6, init_ipv6, 0): - ndp_full_socket_success = ndp_full_socket_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 - results['ndp_full_socket_success'] = ndp_full_socket_success - 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) - - @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) diff --git a/acts/tests/google/wifi/aware/stress/DiscoveryStressTest.py b/acts/tests/google/wifi/aware/stress/DiscoveryStressTest.py deleted file mode 100644 index 55545ea654..0000000000 --- a/acts/tests/google/wifi/aware/stress/DiscoveryStressTest.py +++ /dev/null @@ -1,113 +0,0 @@ -#!/usr/bin/python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import queue - -from acts import asserts -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi.aware import aware_const as aconsts -from acts.test_utils.wifi.aware import aware_test_utils as autils -from acts.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest - - -class DiscoveryStressTest(AwareBaseTest): - """Stress tests for Discovery sessions""" - - # Number of iterations on create/destroy Attach sessions. - ATTACH_ITERATIONS = 2 - - # Number of iterations on create/destroy Discovery sessions - DISCOVERY_ITERATIONS = 40 - - #################################################################### - - @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) diff --git a/acts/tests/google/wifi/aware/stress/InfraAssociationStressTest.py b/acts/tests/google/wifi/aware/stress/InfraAssociationStressTest.py deleted file mode 100644 index 58e2c84e07..0000000000 --- a/acts/tests/google/wifi/aware/stress/InfraAssociationStressTest.py +++ /dev/null @@ -1,160 +0,0 @@ -#!/usr/bin/python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import queue -import threading - -from acts import asserts -from acts.test_utils.wifi import wifi_constants as wconsts -from acts.test_utils.wifi.aware import aware_const as aconsts -from acts.test_utils.wifi.aware import aware_test_utils as autils -from acts.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest - - -class InfraAssociationStressTest(AwareBaseTest): - # Length of test in seconds - TEST_DURATION_SECONDS = 300 - - # Service name - SERVICE_NAME = "GoogleTestServiceXYXYXY" - - 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" - - 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. - - Args: - 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 - (AP) association. - - Test assumes (and verifies) that device is already associated to an AP. - - 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 - 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 - 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) diff --git a/acts/tests/google/wifi/aware/stress/MessagesStressTest.py b/acts/tests/google/wifi/aware/stress/MessagesStressTest.py deleted file mode 100644 index fbe95d4df5..0000000000 --- a/acts/tests/google/wifi/aware/stress/MessagesStressTest.py +++ /dev/null @@ -1,308 +0,0 @@ -#!/usr/bin/python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import queue - -from acts import asserts -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi.aware import aware_const as aconsts -from acts.test_utils.wifi.aware import aware_test_utils as autils -from acts.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest - -KEY_ID = "id" -KEY_TX_OK_COUNT = "tx_ok_count" -KEY_TX_FAIL_COUNT = "tx_fail_count" -KEY_RX_COUNT = "rx_count" - - -class MessagesStressTest(AwareBaseTest): - """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 - - # 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 - - SERVICE_NAME = "GoogleTestServiceXY" - - def init_info(self, msg, id, messages_by_msg, messages_by_id): - """Initialize the message data structures. - - Args: - msg: message text - id: message id - 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 - - 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 - num_msgs: number of expected message tx - 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 - - 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 - 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) diff --git a/acts/tests/google/wifi/aware/stress/stress b/acts/tests/google/wifi/aware/stress/stress deleted file mode 100644 index f79b15885c..0000000000 --- a/acts/tests/google/wifi/aware/stress/stress +++ /dev/null @@ -1,4 +0,0 @@ -MessagesStressTest -DataPathStressTest -DiscoveryStressTest -InfraAssociationStressTest
\ No newline at end of file diff --git a/acts/tests/google/wifi/example_config_iot.json b/acts/tests/google/wifi/example_config_iot.json deleted file mode 100644 index 133cbe3625..0000000000 --- a/acts/tests/google/wifi/example_config_iot.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "_description": "This and example IOT WiFi testbed.", - "testbed": [ - { - "_description": "WiFi testbed with 1 devices", - "name": "<test station name>", - "AndroidDevice": [ - "<device serial>" - ], - "IPerfServer": [ - 5005 - ] - } - ], - "logpath": "/tmp/ACTS_logs", - "testpaths": [ - "<path to acts root>/tools/test/connectivity/acts_tests/tests/google/wifi" - ], - "iot_networks": [ - { - "SSID": "<your SSID 2G>", - "password": "<your password>" - }, - { - "SSID": "<your SSID 5G>", - "password": "<your password>" - }, - { - "SSID": "<your SSID 2G 2>", - "password": "<your password>" - }, - { - "SSID": "<your SSID 5G 2>", - "password": "<your password>" - } - ], - "iperf_server_address": "<your IP address>" -}
\ No newline at end of file diff --git a/acts/tests/google/wifi/example_config_sanity.json b/acts/tests/google/wifi/example_config_sanity.json deleted file mode 100644 index b23d3bff83..0000000000 --- a/acts/tests/google/wifi/example_config_sanity.json +++ /dev/null @@ -1,207 +0,0 @@ -{ - "testbed": [ - { - "name": "test_station_name", - "AndroidDevice": [ - "<serial number 1>", - "<serial number 2 if necessary and 3 etc>" - ], - "AccessPoint": [ - { "ssh_config" : - { - "user" : "root", - "host" : "<ip 1, e.g. 192.168.1.2>" - } - }, - { "ssh_config" : - { - "user" : "root", - "host" : "<ip 2 (if necessary) and ip 3 ...>" - } - } - ], - "Attenuator": [ - { - "Address": "<attenuator ip address>", - "InstrumentCount": 4, - "Model": "<model, e.g. minicircuits>", - "Paths": [ - "AP1-2G", - "AP1-5G", - "AP2-2G", - "AP2-5G" - ], - "Port": 22 - } - ], - "IPerfServer": [ - 5004 - ], - "bssid_2g": { - "BSSID": "<bssid, e.g. 00:01:02:03:04:05>", - "high": "-10", - "low": "-85" - }, - "bssid_5g": { - "BSSID": "<bssid>", - "high": "-10", - "low": "-85" - }, - "bssid_dfs": { - "BSSID": "<bssid>", - "high": "-10", - "low": "-85" - }, - "iperf_server_address": "100.107.126.31" - } - ], - "atten_val": { - "Ap1_2g": [ - 10, - 95, - 95, - 95 - ], - "Ap1_2gto5g": [ - 45, - 10, - 95, - 95 - ], - "Ap1_5gto2g": [ - 10, - 80, - 95, - 95 - ], - "Ap2_2g": [ - 75, - 75, - 10, - 75 - ], - "Ap2_2gto5g": [ - 75, - 75, - 75, - 10 - ], - "Ap2_5gto2g": [ - 75, - 75, - 10, - 75 - ], - "Back_from_blacklist": [ - 40, - 95, - 95 - ], - "In_AP1_5gto2g": [ - 10, - 75, - 95, - 95 - ], - "In_Ap2_5gto2g": [ - 75, - 75, - 10, - 75 - ], - "In_blacklist": [ - 95, - 95, - 0 - ], - "Swtich_AP1toAp2": [ - 70, - 70, - 2, - 70 - ], - "Swtich_AP2toAp1": [ - 10, - 70, - 75, - 75 - ], - "Swtich_to_blacklist": [ - 60, - 90, - 40 - ] - }, - "attenuator_id": 0, - "roaming_attn": { - "AP1_on_AP2_off": [ - 0, - 0, - 95, - 95 - ], - "AP1_off_AP2_on": [ - 95, - 95, - 0, - 0 - ], - "default": [ - 0, - 0, - 0, - 0 - ] - }, - "attn_vals": { - "a_b_on": [ - 0, - 0 - ], - "a_on_b_off": [ - 0, - 95 - ], - "b_on_a_off": [ - 95, - 0 - ], - "default": [ - 0, - 0 - ] - }, - "device_password": "hahahaha", - "eap_password": "password", - "fqdn": "red.com", - "max_bugreports": 5, - "other_network": { - "SSID": "wh_ap3_2g", - "password": "hahahaha" - }, - "ping_addr": "https://www.google.com/robots.txt", - "pno_interval": 120, - "provider_friendly_name": "red", - "realm": "red.com", - "roam_interval": 60, - "run_extended_test": false, - "two_ap_testbed": true, - "aware_default_power_mode": "INTERACTIVE", - "stress_count": 100, - "stress_hours": 5, - "dbs_supported_models": ["<product name 1>", "<product name 2>"], - "lci_reference": [], - "lcr_reference": [], - "rtt_reference_distance_mm": 4600, - "stress_test_min_iteration_count": 100, - "stress_test_target_run_time_sec" : 30, - "energy_info_models": [ - "<product name 1 (adb shell getprop ro.build.product)>", - "<product name 2>" - ], - "tdls_models": [ - "<product name 1>", - "<product name 2>" - ] -} - diff --git a/acts/tests/google/wifi/example_connectivity_performance_ap_sta.json b/acts/tests/google/wifi/example_connectivity_performance_ap_sta.json deleted file mode 100644 index 6ec05017a5..0000000000 --- a/acts/tests/google/wifi/example_connectivity_performance_ap_sta.json +++ /dev/null @@ -1,89 +0,0 @@ -{ - "testbed": [{ - "name": "<your testbed name>", - "AndroidDevice": ["<your device serial number>"], - "bug_report": 1, - "RetailAccessPoints": ["<your ap configuration. see class definition in wifi_retail_ap.py>"], - "Attenuator": ["<your attenuator configuration. see attenuator class definition>"], - "main_network": { - "<your network name>": { - "SSID": "<your SSID>", - "password": "<your key>", - "BSSID": "<your BSSID>" - }, - "<your other network names>": { - "SSID": "<your SSID>", - "password": "<your key>", - "BSSID": "<your BSSID>" - } - }, - "IPerfServer": ["<your iperf server configuation. see class definition in iperf_server>"], - "testbed_params": { - "default_region": "<default access point region to run tests in. This will be used for all non DFS channels>", - "DFS_region": "<access point region to run DFS tests in>", - "iperf_server_address": "<ip address of iperf server generating or accepting test traffic>", - "fixed_attenuation": {"<your channel number 1>": "<your testbed attenuation on this channel>", "<your channel number 2>": "<your testbed attenuation on this channel>"}, - "dut_front_end_loss": {"<your channel number 1>": "<your DUT front end loss on this channel>", "<your channel number 2>": "<your DUT front end loss on this channel>"}, - "ap_tx_power": {"<your channel number 1>": "<your access point transmit power on this channel>", "<your channel number 2>": "<your access point transmit power on this channel>"}, - "golden_results_path": "<your full path to golden results used for pass fail check>" - } - } - ], - "rvr_test_params":{ - "country_code": "<device country code to set during rvr tests>", - "iperf_duration": 30, - "iperf_ignored_interval": 2, - "UDP_rates": {"VHT20": "<throughput to transmit in this mode>", "VHT40": "<throughput to transmit in this mode>", "VHT80": "<throughput to transmit in this mode>"}, - "rvr_atten_start": 20, - "rvr_atten_stop": 30, - "rvr_atten_step": 5, - "pct_tolerance": 5, - "abs_tolerance": 5, - "failure_count_tolerance": 1 - }, - "rssi_test_params":{ - "country_code": "<device country code to set during rvr tests>", - "rssi_vs_atten_start": 20, - "rssi_vs_atten_stop": 80, - "rssi_vs_atten_step": 1, - "rssi_vs_atten_connected_measurements": 10, - "rssi_vs_atten_scan_measurements": 0, - "rssi_vs_atten_metrics": ["signal_poll_rssi", "scan_rssi", "chain_0_rssi", "chain_1_rssi"], - "rssi_stability_atten": [20, 55], - "rssi_stability_duration": 10, - "rssi_tracking_waveforms": [{"atten_levels": [40, 61, 40], "step_size": 1, "step_duration": 1, "repetitions":1}], - "polling_frequency": 0.25, - "abs_tolerance": 2.5, - "stdev_tolerance": 1 - }, - "throughput_stability_test_params":{ - "country_code": "<device country code to set during rvr tests>", - "iperf_duration": 30, - "iperf_ignored_interval": 5, - "UDP_rates": {"VHT20": "200M", "VHT40": "400M", "VHT80": "700M"}, - "low_rssi_backoff_from_range": 10, - "min_throughput_threshold": 75, - "std_deviation_threshold": 5 - - }, - "ping_test_params":{ - "country_code": "<device country code to set during rvr tests>", - "ping_size": 64, - "range_ping_duration": 1, - "range_ping_interval": 0.002, - "range_atten_start": 60, - "range_atten_step": 1, - "range_atten_stop": 70, - "range_ping_loss_threshold": 25, - "range_gap_threshold": 2, - "rtt_ping_duration": 30, - "rtt_ping_interval": {"fast": 0.002, "slow": 0.5}, - "rtt_ignored_interval": 0.15, - "rtt_test_attenuation": [20, 50], - "rtt_test_percentile": 5, - "rtt_threshold": 0.2, - "rtt_std_deviation_threshold": 5 - }, - "logpath": "<path to logs>", - "testpaths": ["<path to ACTS root folder>/tools/test/connectivity/acts_tests/tests/google/wifi"] -} diff --git a/acts/tests/google/wifi/p2p/config/wifi_p2p.json b/acts/tests/google/wifi/p2p/config/wifi_p2p.json deleted file mode 100644 index 9a8c841ed6..0000000000 --- a/acts/tests/google/wifi/p2p/config/wifi_p2p.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "_description": "This is a test configuration file for Wi-Fi P2p tests.", - "testbed": - [ - { - "_description": "Wi-Fi P2P testbed: auto-detect all attached devices", - "name": "WifiP2pAllAttached", - "AndroidDevice": "*" - } - ], - "logpath": "~/logs", - "testpaths": ["./tools/test/connectivity/acts_tests/tests/google/wifi/p2p"], - "adb_logcat_param": "-b all" -} diff --git a/acts/tests/google/wifi/p2p/config/wifi_p2p_group.json b/acts/tests/google/wifi/p2p/config/wifi_p2p_group.json deleted file mode 100644 index e4f7d8b3a7..0000000000 --- a/acts/tests/google/wifi/p2p/config/wifi_p2p_group.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "_description": "This is a test configuration file for Wi-Fi P2p group tests.", - "testbed": - [ - { - "_description": "Wi-Fi P2P testbed: auto-detect all attached devices", - "name": "WifiP2pAllAttached", - "AndroidDevice": "*" - } - ], - "network_name": "DIRECT-xy-Hello", - "passphrase": "P2pWorld1234", - "group_band": "2", - "logpath": "~/logs", - "testpaths": ["./tools/test/connectivity/acts_tests/tests/google/wifi/p2p"], - "adb_logcat_param": "-b all" -} diff --git a/acts/tests/google/wifi/p2p/functional/WifiP2pGroupTest.py b/acts/tests/google/wifi/p2p/functional/WifiP2pGroupTest.py deleted file mode 100644 index 165391fe35..0000000000 --- a/acts/tests/google/wifi/p2p/functional/WifiP2pGroupTest.py +++ /dev/null @@ -1,132 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2018 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import acts.test_utils.wifi.wifi_test_utils as wutils -import acts.utils -import time - -from acts import asserts -from acts import utils - -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi.p2p.WifiP2pBaseTest import WifiP2pBaseTest -from acts.test_utils.wifi.p2p import wifi_p2p_test_utils as wp2putils -from acts.test_utils.wifi.p2p import wifi_p2p_const as p2pconsts - -WPS_PBC = wp2putils.WifiP2PEnums.WpsInfo.WIFI_WPS_INFO_PBC -WPS_DISPLAY = wp2putils.WifiP2PEnums.WpsInfo.WIFI_WPS_INFO_DISPLAY -WPS_KEYPAD = wp2putils.WifiP2PEnums.WpsInfo.WIFI_WPS_INFO_KEYPAD - -class WifiP2pGroupTest(WifiP2pBaseTest): - """Tests for APIs in Android's WifiP2pManager class. - - Test Bed Requirement: - * At least two Android devices - """ - - def __init__(self, controllers): - WifiP2pBaseTest.__init__(self, controllers) - - def setup_class(self): - super().setup_class() - if not "network_name" in self.user_params.keys(): - self.log.error("Missing mandatory user config \"network_name\"!") - self.network_name = self.user_params["network_name"] - if not "passphrase" in self.user_params.keys(): - self.log.error("Missing mandatory user config \"passphrase\"!") - self.passphrase = self.user_params["passphrase"] - if not "group_band" in self.user_params.keys(): - self.log.error("Missing mandatory user config \"group_band\"!") - self.group_band = self.user_params["group_band"] - - def setup_test(self): - super().setup_test() - self.dut1.droid.wifiP2pRemoveGroup() - self.dut2.droid.wifiP2pRemoveGroup() - time.sleep(p2pconsts.DEFAULT_FUNCTION_SWITCH_TIME) - - def teardown_test(self): - self.dut1.droid.wifiP2pRemoveGroup() - self.dut2.droid.wifiP2pRemoveGroup() - time.sleep(p2pconsts.DEFAULT_FUNCTION_SWITCH_TIME) - super().teardown_test() - - def p2p_group_join(self, wps_type): - """ General flow for p2p group join - - Steps: - 1. GO creates a group. - 2. GC joins the group. - 3. connection check via ping from GC to GO - """ - go_dut = self.dut1 - gc_dut = self.dut2 - # Create a group - wp2putils.p2p_create_group(go_dut) - go_dut.ed.pop_event(p2pconsts.CONNECTED_EVENT, p2pconsts.DEFAULT_TIMEOUT) - time.sleep(p2pconsts.DEFAULT_FUNCTION_SWITCH_TIME) - # Request the connection - wp2putils.p2p_connect(gc_dut, go_dut, False, wps_type, True) - - go_ip = wp2putils.p2p_go_ip(gc_dut) - wp2putils.p2p_connection_ping_test(gc_dut, go_ip) - # trigger disconnect - wp2putils.p2p_disconnect(go_dut) - wp2putils.check_disconnect(gc_dut) - time.sleep(p2pconsts.DEFAULT_FUNCTION_SWITCH_TIME) - - - """Test Cases""" - @test_tracker_info(uuid="c41f8293-5225-430d-917e-c294ddff7c2a") - def test_p2p_group_join_via_pbc(self): - """Verify the p2p creates a group and join this group via WPS PBC method. - """ - self.p2p_group_join(WPS_PBC) - - @test_tracker_info(uuid="56eb339f-d7e4-44f0-9802-6094e9255957") - def test_p2p_group_join_via_display(self): - """Verify the p2p creates a group and join this group via WPS DISPLAY method. - """ - self.p2p_group_join(WPS_DISPLAY) - - @test_tracker_info(uuid="27075cab-7859-49a7-afe9-b6cc6e8faddb") - def test_p2p_group_with_config(self): - """Verify the p2p creates a group and join an this group with config. - - Steps: - 1. GO creates a group with config. - 2. GC joins the group with config. - 3. connection check via ping from GC to GO - """ - go_dut = self.dut1 - gc_dut = self.dut2 - # Create a group - wp2putils.p2p_create_group_with_config(go_dut, - self.network_name, - self.passphrase, - self.group_band) - time.sleep(p2pconsts.DEFAULT_FUNCTION_SWITCH_TIME) - # Request the connection. Since config is known, this is reconnection. - wp2putils.p2p_connect_with_config(gc_dut, go_dut, - self.network_name, self.passphrase, - self.group_band) - - go_ip = wp2putils.p2p_go_ip(gc_dut) - wp2putils.p2p_connection_ping_test(gc_dut, go_ip) - # trigger disconnect - wp2putils.p2p_disconnect(go_dut) - wp2putils.check_disconnect(gc_dut) - time.sleep(p2pconsts.DEFAULT_FUNCTION_SWITCH_TIME) diff --git a/acts/tests/google/wifi/p2p/functional/WifiP2pLocalServiceTest.py b/acts/tests/google/wifi/p2p/functional/WifiP2pLocalServiceTest.py deleted file mode 100644 index baa21847b8..0000000000 --- a/acts/tests/google/wifi/p2p/functional/WifiP2pLocalServiceTest.py +++ /dev/null @@ -1,95 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2018 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import time - -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi.p2p.WifiP2pBaseTest import WifiP2pBaseTest -from acts.test_utils.wifi.p2p import wifi_p2p_test_utils as wp2putils -from acts.test_utils.wifi.p2p import wifi_p2p_const as p2pconsts - -class WifiP2pLocalServiceTest(WifiP2pBaseTest): - """Tests for APIs in Android's WifiP2pManager and p2p local service class. - - Test Bed Requirement: - * At least two Android devices - * 3 Android devices for WifiP2pMultiPeersTest.py - """ - - def __init__(self, controllers): - WifiP2pBaseTest.__init__(self, controllers) - - """Test Cases""" - @test_tracker_info(uuid="ba879c8d-0fbd-41fb-805c-5cd1cd312090") - def test_p2p_upnp_service(self): - """Verify the p2p discovery functionality - Steps: - 1. dut1 add local Upnp service - 2. dut2 register Upnp Service listener - 3. Check dut2 peer list if it only included dut1 - 4. Setup p2p upnp local service request with different query string - 5. Check p2p upnp local servier query result is expect or not - 6. Test different query string and check query result - Note: Step 2 - Step 5 should reference function requestServiceAndCheckResult - """ - self.log.info("Add local Upnp Service") - wp2putils.createP2pLocalService(self.dut1, p2pconsts.P2P_LOCAL_SERVICE_UPNP) - - wp2putils.requestServiceAndCheckResult(self.dut1, self.dut2, - wp2putils.WifiP2PEnums.WifiP2pServiceInfo.WIFI_P2P_SERVICE_TYPE_UPNP, - None, None) - time.sleep(p2pconsts.DEFAULT_FUNCTION_SWITCH_TIME) - wp2putils.requestServiceAndCheckResult(self.dut1, self.dut2, - wp2putils.WifiP2PEnums.WifiP2pServiceInfo.WIFI_P2P_SERVICE_TYPE_UPNP, - "ssdp:all", None) - time.sleep(p2pconsts.DEFAULT_FUNCTION_SWITCH_TIME) - wp2putils.requestServiceAndCheckResult(self.dut1, self.dut2, - wp2putils.WifiP2PEnums.WifiP2pServiceInfo.WIFI_P2P_SERVICE_TYPE_UPNP, - "upnp:rootdevice", None) - time.sleep(p2pconsts.DEFAULT_FUNCTION_SWITCH_TIME) - - """Test Cases""" - @test_tracker_info(uuid="470306fa-5c46-4258-ade2-9c0834bb04f9") - def test_p2p_bonjour_service(self): - """Verify the p2p discovery functionality - Steps: - 1. dut1 add local bonjour service - IPP and AFP - 2. dut2 register bonjour Service listener - dnssd and dnssd_txrecord - 3. Check dut2 peer list if it only included dut1 - 4. Setup p2p bonjour local service request with different query string - 5. Check p2p bonjour local servier query result is expect or not - 6. Test different query string and check query result - Note: Step 2 - Step 5 should reference function requestServiceAndCheckResult - """ - self.log.info("Add local bonjour service to %s" % (self.dut1.name)) - wp2putils.createP2pLocalService(self.dut1, p2pconsts.P2P_LOCAL_SERVICE_IPP) - wp2putils.createP2pLocalService(self.dut1, p2pconsts.P2P_LOCAL_SERVICE_AFP) - - wp2putils.requestServiceAndCheckResultWithRetry(self.dut1, self.dut2, - wp2putils.WifiP2PEnums.WifiP2pServiceInfo.WIFI_P2P_SERVICE_TYPE_BONJOUR, - None, None) - time.sleep(p2pconsts.DEFAULT_FUNCTION_SWITCH_TIME) - wp2putils.requestServiceAndCheckResultWithRetry(self.dut1,self.dut2, - wp2putils.WifiP2PEnums.WifiP2pServiceInfo.WIFI_P2P_SERVICE_TYPE_BONJOUR, - "_ipp._tcp", None) - time.sleep(p2pconsts.DEFAULT_FUNCTION_SWITCH_TIME) - wp2putils.requestServiceAndCheckResultWithRetry(self.dut1, self.dut2, - wp2putils.WifiP2PEnums.WifiP2pServiceInfo.WIFI_P2P_SERVICE_TYPE_BONJOUR, - "_ipp._tcp", "MyPrinter") - time.sleep(p2pconsts.DEFAULT_FUNCTION_SWITCH_TIME) - wp2putils.requestServiceAndCheckResultWithRetry(self.dut1, self.dut2, - wp2putils.WifiP2PEnums.WifiP2pServiceInfo.WIFI_P2P_SERVICE_TYPE_BONJOUR, - "_afpovertcp._tcp", "Example") diff --git a/acts/tests/google/wifi/p2p/functional/WifiP2pManagerTest.py b/acts/tests/google/wifi/p2p/functional/WifiP2pManagerTest.py deleted file mode 100644 index 1f5a8628bd..0000000000 --- a/acts/tests/google/wifi/p2p/functional/WifiP2pManagerTest.py +++ /dev/null @@ -1,204 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2018 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import acts.test_utils.wifi.wifi_test_utils as wutils -import acts.utils -import time - -from acts import asserts -from acts import utils - -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi.p2p.WifiP2pBaseTest import WifiP2pBaseTest -from acts.test_utils.wifi.p2p import wifi_p2p_test_utils as wp2putils -from acts.test_utils.wifi.p2p import wifi_p2p_const as p2pconsts - -WPS_PBC = wp2putils.WifiP2PEnums.WpsInfo.WIFI_WPS_INFO_PBC -WPS_DISPLAY = wp2putils.WifiP2PEnums.WpsInfo.WIFI_WPS_INFO_DISPLAY -WPS_KEYPAD = wp2putils.WifiP2PEnums.WpsInfo.WIFI_WPS_INFO_KEYPAD - -class WifiP2pManagerTest(WifiP2pBaseTest): - """Tests for APIs in Android's WifiP2pManager class. - - Test Bed Requirement: - * At least two Android devices - * 3 Android devices for WifiP2pMultiPeersTest.py - """ - - def __init__(self, controllers): - WifiP2pBaseTest.__init__(self, controllers) - - """Test Cases""" - @test_tracker_info(uuid="28ddb16c-2ce4-44da-92f9-701d0dacc321") - def test_p2p_discovery(self): - """Verify the p2p discovery functionality - Steps: - 1. Discover the target device - 2. Check the target device in peer list - """ - self.log.info("Device discovery") - wp2putils.find_p2p_device(self.dut1, self.dut2) - wp2putils.find_p2p_device(self.dut2, self.dut1) - - @test_tracker_info(uuid="0016e6db-9b46-44fb-a53e-10a81eee955e") - def test_p2p_connect_via_pbc_and_ping_and_reconnect(self): - """Verify the p2p connect via pbc functionality - - Steps: - 1. Request the connection which include discover the target device - 2. check which dut is GO and which dut is GC - 3. connection check via ping from GC to GO - 4. disconnect - 5. Trigger connect again from GO for reconnect test. - 6. GO trigger disconnect - 7. Trigger connect again from GC for reconnect test. - 8. GC trigger disconnect - """ - # Request the connection - wp2putils.p2p_connect(self.dut1, self.dut2, False, WPS_PBC) - - if wp2putils.is_go(self.dut1): - go_dut = self.dut1 - gc_dut = self.dut2 - elif wp2putils.is_go(self.dut2): - go_dut = self.dut2 - gc_dut = self.dut1 - - go_ip = wp2putils.p2p_go_ip(gc_dut) - wp2putils.p2p_connection_ping_test(gc_dut, go_ip) - - # trigger disconnect - wp2putils.p2p_disconnect(self.dut1) - wp2putils.check_disconnect(self.dut2) - time.sleep(p2pconsts.DEFAULT_FUNCTION_SWITCH_TIME) - - self.log.info("Reconnect test, triggered by GO") - # trigger reconnect from GO - go_dut.ed.clear_all_events() - gc_dut.ed.clear_all_events() - wp2putils.p2p_connect(go_dut, gc_dut, True, WPS_PBC) - wp2putils.p2p_disconnect(go_dut) - wp2putils.check_disconnect(gc_dut) - time.sleep(p2pconsts.DEFAULT_FUNCTION_SWITCH_TIME) - - # trigger reconnect from GC - self.log.info("Reconnect test, triggered by GC") - go_dut.ed.clear_all_events() - gc_dut.ed.clear_all_events() - wp2putils.p2p_connect(gc_dut, go_dut, True, WPS_PBC) - wp2putils.p2p_disconnect(gc_dut) - wp2putils.check_disconnect(go_dut) - time.sleep(p2pconsts.DEFAULT_FUNCTION_SWITCH_TIME) - - @test_tracker_info(uuid="12bbe73a-5a6c-4307-9797-c77c7efdc4b5") - def test_p2p_connect_via_display_and_ping_and_reconnect(self): - """Verify the p2p connect via display functionality - - Steps: - 1. Request the connection which include discover the target device - 2. check which dut is GO and which dut is GC - 3. connection check via ping from GC to GO - 4. disconnect - 5. Trigger connect again from GO for reconnect test. - 6. GO trigger disconnect - 7. Trigger connect again from GC for reconnect test. - 8. GC trigger disconnect - """ - # Request the connection - wp2putils.p2p_connect(self.dut1, self.dut2, False, WPS_DISPLAY) - - if wp2putils.is_go(self.dut1): - go_dut = self.dut1 - gc_dut = self.dut2 - elif wp2putils.is_go(self.dut2): - go_dut = self.dut2 - gc_dut = self.dut1 - - go_ip = wp2putils.p2p_go_ip(gc_dut) - wp2putils.p2p_connection_ping_test(gc_dut, go_ip) - - # trigger disconnect - wp2putils.p2p_disconnect(self.dut1) - wp2putils.check_disconnect(self.dut2) - time.sleep(p2pconsts.DEFAULT_FUNCTION_SWITCH_TIME) - - self.log.info("Reconnect test, triggered by GO") - # trigger reconnect from GO - go_dut.ed.clear_all_events() - gc_dut.ed.clear_all_events() - wp2putils.p2p_connect(go_dut, gc_dut, True, WPS_DISPLAY) - wp2putils.p2p_disconnect(go_dut) - wp2putils.check_disconnect(gc_dut) - time.sleep(p2pconsts.DEFAULT_FUNCTION_SWITCH_TIME) - - # trigger reconnect from GC - self.log.info("Reconnect test, triggered by GC") - go_dut.ed.clear_all_events() - gc_dut.ed.clear_all_events() - wp2putils.p2p_connect(gc_dut, go_dut, True, WPS_DISPLAY) - wp2putils.p2p_disconnect(gc_dut) - wp2putils.check_disconnect(go_dut) - time.sleep(p2pconsts.DEFAULT_FUNCTION_SWITCH_TIME) - - @test_tracker_info(uuid="efe88f57-5a08-4195-9592-2f6945a9d18a") - def test_p2p_connect_via_keypad_and_ping_and_reconnect(self): - """Verify the p2p connect via keypad functionality - - Steps: - 1. Request the connection which include discover the target device - 2. check which dut is GO and which dut is GC - 3. connection check via ping from GC to GO - 4. disconnect - 5. Trigger connect again from GO for reconnect test. - 6. GO trigger disconnect - 7. Trigger connect again from GC for reconnect test. - 8. GC trigger disconnect - """ - # Request the connection - wp2putils.p2p_connect(self.dut1, self.dut2, False, WPS_KEYPAD) - - if wp2putils.is_go(self.dut1): - go_dut = self.dut1 - gc_dut = self.dut2 - elif wp2putils.is_go(self.dut2): - go_dut = self.dut2 - gc_dut = self.dut1 - - go_ip = wp2putils.p2p_go_ip(gc_dut) - wp2putils.p2p_connection_ping_test(gc_dut, go_ip) - - # trigger disconnect - wp2putils.p2p_disconnect(self.dut1) - wp2putils.check_disconnect(self.dut2) - time.sleep(p2pconsts.DEFAULT_FUNCTION_SWITCH_TIME) - - self.log.info("Reconnect test, triggered by GO") - # trigger reconnect from GO - go_dut.ed.clear_all_events() - gc_dut.ed.clear_all_events() - wp2putils.p2p_connect(go_dut, gc_dut, True, WPS_KEYPAD) - wp2putils.p2p_disconnect(go_dut) - wp2putils.check_disconnect(gc_dut) - time.sleep(p2pconsts.DEFAULT_FUNCTION_SWITCH_TIME) - - # trigger reconnect from GC - self.log.info("Reconnect test, triggered by GC") - go_dut.ed.clear_all_events() - gc_dut.ed.clear_all_events() - wp2putils.p2p_connect(gc_dut, go_dut, True, WPS_KEYPAD) - wp2putils.p2p_disconnect(gc_dut) - wp2putils.check_disconnect(go_dut) - time.sleep(p2pconsts.DEFAULT_FUNCTION_SWITCH_TIME) diff --git a/acts/tests/google/wifi/p2p/functional/WifiP2pSnifferTest.py b/acts/tests/google/wifi/p2p/functional/WifiP2pSnifferTest.py deleted file mode 100644 index 310eab2b50..0000000000 --- a/acts/tests/google/wifi/p2p/functional/WifiP2pSnifferTest.py +++ /dev/null @@ -1,140 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright 2019 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import acts.test_utils.wifi.wifi_test_utils as wutils -import acts.utils -import time - -from acts import asserts -from acts import utils - -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi.p2p.WifiP2pBaseTest import WifiP2pBaseTest -from acts.test_utils.wifi.p2p import wifi_p2p_test_utils as wp2putils -from acts.test_utils.wifi.p2p import wifi_p2p_const as p2pconsts -from acts.controllers.ap_lib.hostapd_constants import BAND_2G -from scapy.all import * - -WPS_PBC = wp2putils.WifiP2PEnums.WpsInfo.WIFI_WPS_INFO_PBC -WPS_DISPLAY = wp2putils.WifiP2PEnums.WpsInfo.WIFI_WPS_INFO_DISPLAY -WPS_KEYPAD = wp2putils.WifiP2PEnums.WpsInfo.WIFI_WPS_INFO_KEYPAD -DEFAULT_TIMEOUT = 10 - -class WifiP2pSnifferTest(WifiP2pBaseTest): - """Tests factory MAC is not leaked for p2p discovery and associated cases. - - Test Bed Requirement: - * At least two Android devices - * An access point as sniffer - """ - - def __init__(self, controllers): - WifiP2pBaseTest.__init__(self, controllers) - - def setup_class(self): - super(WifiP2pSnifferTest, self).setup_class() - wp2putils.wifi_p2p_set_channels_for_current_group(self.dut1, 6, 6) - wp2putils.wifi_p2p_set_channels_for_current_group(self.dut2, 6, 6) - self.configure_packet_capture() - - def setup_test(self): - super(WifiP2pSnifferTest, self).setup_test() - self.pcap_procs = wutils.start_pcap( - self.packet_capture, '2g', self.test_name) - - def teardown_test(self): - self.verify_mac_no_leakage() - super(WifiP2pSnifferTest, self).teardown_test() - - def configure_packet_capture(self): - """Configure packet capture on the social channels.""" - self.packet_capture = self.packet_capture[0] - result = self.packet_capture.configure_monitor_mode(BAND_2G, 6) - if not result: - raise ValueError("Failed to configure channel for 2G band") - - def verify_mac_no_leakage(self): - time.sleep(DEFAULT_TIMEOUT) - self.log.info("Stopping packet capture") - wutils.stop_pcap(self.packet_capture, self.pcap_procs, False) - # Verify factory MAC is not leaked in 2G pcaps - pcap_fname = '%s_%s.pcap' % (self.pcap_procs[BAND_2G][1], - BAND_2G.upper()) - packets = rdpcap(pcap_fname) - wutils.verify_mac_not_found_in_pcap(self.dut1_mac, packets) - wutils.verify_mac_not_found_in_pcap(self.dut2_mac, packets) - - """Test Cases""" - @test_tracker_info(uuid=" d04e62dc-e1ef-4cea-86e6-39f0dd08fb6b") - def test_p2p_discovery_sniffer(self): - """Verify the p2p discovery functionality - Steps: - 1. Discover the target device - 2. Check the target device in peer list - """ - self.log.info("Device discovery") - wp2putils.find_p2p_device(self.dut1, self.dut2) - wp2putils.find_p2p_device(self.dut2, self.dut1) - - @test_tracker_info(uuid="6a02be84-912d-4b5b-8dfa-fd80d2554c55") - def test_p2p_connect_via_pbc_and_ping_and_reconnect_sniffer(self): - """Verify the p2p connect via pbc functionality - - Steps: - 1. Request the connection which include discover the target device - 2. check which dut is GO and which dut is GC - 3. connection check via ping from GC to GO - 4. disconnect - 5. Trigger connect again from GO for reconnect test. - 6. GO trigger disconnect - 7. Trigger connect again from GC for reconnect test. - 8. GC trigger disconnect - """ - # Request the connection - wp2putils.p2p_connect(self.dut1, self.dut2, False, WPS_PBC) - - if wp2putils.is_go(self.dut1): - go_dut = self.dut1 - gc_dut = self.dut2 - elif wp2putils.is_go(self.dut2): - go_dut = self.dut2 - gc_dut = self.dut1 - - go_ip = wp2putils.p2p_go_ip(gc_dut) - wp2putils.p2p_connection_ping_test(gc_dut, go_ip) - - # trigger disconnect - wp2putils.p2p_disconnect(self.dut1) - wp2putils.check_disconnect(self.dut2) - time.sleep(p2pconsts.DEFAULT_FUNCTION_SWITCH_TIME) - - self.log.info("Reconnect test, triggered by GO") - # trigger reconnect from GO - go_dut.ed.clear_all_events() - gc_dut.ed.clear_all_events() - wp2putils.p2p_connect(go_dut, gc_dut, True, WPS_PBC) - wp2putils.p2p_disconnect(go_dut) - wp2putils.check_disconnect(gc_dut) - time.sleep(p2pconsts.DEFAULT_FUNCTION_SWITCH_TIME) - - # trigger reconnect from GC - self.log.info("Reconnect test, triggered by GC") - go_dut.ed.clear_all_events() - gc_dut.ed.clear_all_events() - wp2putils.p2p_connect(gc_dut, go_dut, True, WPS_PBC) - wp2putils.p2p_disconnect(gc_dut) - wp2putils.check_disconnect(go_dut) - time.sleep(p2pconsts.DEFAULT_FUNCTION_SWITCH_TIME) diff --git a/acts/tests/google/wifi/rtt/README.md b/acts/tests/google/wifi/rtt/README.md deleted file mode 100644 index 1e435eb379..0000000000 --- a/acts/tests/google/wifi/rtt/README.md +++ /dev/null @@ -1,59 +0,0 @@ -# Wi-Fi RTT (IEEE 802.11mc) Integrated (ACTS/sl4a) Test Suite - -This directory contains ACTS/sl4a test scripts to verify and characterize -the Wi-Fi RTT (IEEE 802.11mc) implementation in Android. - -There are 2 groups of tests (in 2 sub-directories): - -* functional: Functional tests that each implementation must pass. These -are pass/fail tests. -* stress: Tests which run through a large number of iterations to stress -test the implementation. Considering that some failures are expected, -especially in an over-the-air situation, pass/fail criteria are either -not provided or may not apply to all implementations or test environments. - -The tests can be executed using: - -`act.py -c <config> -tc {<test_class>|<test_class>:<test_name>}` - -Where a test file is any of the `.py` files in any of the test sub-directories. -If a test class is specified, then all tests within that test class are executed. - -## Test Beds -The Wi-Fi RTT tests support several different test scenarios which require different test bed -configuration. The test beds and their corresponding test files are: - -* Device Under Test + AP which supports IEEE 802.11mc - * functional/RangeApSupporting11McTest.py - * functional/RttRequestManagementTest.py - * functional/RttDisableTest.py - * stress/StressRangeApTest.py -* Device Under Test + AP which does **not** support IEEE 802.11mc - * functional/RangeApNonSupporting11McTest.py -* 2 Devices Under Test - * functional/RangeAwareTest.py - * functional/AwareDiscoveryWithRangingTest.py - * functional/RangeSoftApTest.py - * stress/StressRangeAwareTest.py - -## Test Configurations -The test configuration, the `<config>` in the commands above, is stored in -the *config* sub-directory. The configuration simply uses all connected -devices without listing specific serial numbers. Note that some tests use a -single device while others use 2 devices. - -The only provided configuration is *wifi_rtt.json*. - -The configuration defines the following keys to configure the test: - -* **lci_reference**, **lcr_reference**: Arrays of bytes used to validate that the *correct* LCI and -LCR were received from the AP. These are empty by default and should be configured to match the -configuration of the AP used in the test. -* **rtt_reference_distance_mm**: The reference distance, in mm, between the test device and the test -AP or between the two test devices (for Aware ranging tests). -* **stress_test_min_iteration_count**, **stress_test_target_run_time_sec**: Parameters used to -control the length and duration of the stress tests. The stress test runs for the specified number -of iterations or for the specified duration - whichever is longer. -* **dbs_supported_models**: A list of device models which support DBS. Used to determine whether -RTT will run while a SoftAP (SAP) is enabled. The model name corresponds to the value returned by -*android_device.model*. diff --git a/acts/tests/google/wifi/rtt/config/wifi_rtt.json b/acts/tests/google/wifi/rtt/config/wifi_rtt.json deleted file mode 100644 index 1870fe97f2..0000000000 --- a/acts/tests/google/wifi/rtt/config/wifi_rtt.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "_description": "This is a test configuration file for Wi-Fi RTT tests.", - "testbed": - [ - { - "_description": "Wi-Fi RTT testbed: auto-detect all attached devices", - "name": "WifiRttAllAttached", - "AndroidDevice": "*" - } - ], - "logpath": "~/logs", - "testpaths": ["./tools/test/connectivity/acts_tests/tests/google/wifi"], - "adb_logcat_param": "-b all", - "aware_default_power_mode": "INTERACTIVE", - "lci_reference": [], - "lcr_reference": [], - "rtt_reference_distance_mm": 100, - "stress_test_min_iteration_count": 100, - "stress_test_target_run_time_sec" : 30, - "dbs_supported_models" : [] -} diff --git a/acts/tests/google/wifi/rtt/functional/AwareDiscoveryWithRangingTest.py b/acts/tests/google/wifi/rtt/functional/AwareDiscoveryWithRangingTest.py deleted file mode 100644 index e19993db13..0000000000 --- a/acts/tests/google/wifi/rtt/functional/AwareDiscoveryWithRangingTest.py +++ /dev/null @@ -1,1928 +0,0 @@ -#!/usr/bin/python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import sys -import time - -from acts import asserts -from acts.test_decorators import test_tracker_info -from acts.test_utils.net import connectivity_const as cconsts -from acts.test_utils.wifi.aware import aware_const as aconsts -from acts.test_utils.wifi.aware import aware_test_utils as autils -from acts.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest -from acts.test_utils.wifi.rtt import rtt_const as rconsts -from acts.test_utils.wifi.rtt import rtt_test_utils as rutils -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).""" - - 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) - # for both Initiators and Responders. Only the first mode works. - RANGING_INITIATOR_RESPONDER_CONCURRENCY_LIMITATION = True - - 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) - - 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) - - ######################################################################### - - 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. - expect_discovery: True or False indicating whether discovery is expected - with the specified configurations. - expect_range: True if we expect distance results (i.e. ranging to happen). - Only relevant if expect_discovery is True. - Returns: - 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 - configurations. I.e. update the existing discovery sessions with the - configurations. - - Args: - p_dut, s_dut: Publisher/Subscriber DUTs. - p_disc_id, s_disc_id: Publisher/Subscriber discovery session IDs. - p_config, s_config: Publisher and Subscriber discovery configuration. - expect_discovery: True or False indicating whether discovery is expected - with the specified configurations. - expect_range: True if we expect distance results (i.e. ranging to happen). - 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: - - Publisher enables ranging - - Subscriber enables ranging with min/max such that out of range (min=large, - max=large+1) - - Expected: no discovery - - This is a baseline test for the update-configuration tests. - - Args: - is_unsolicited_passive: True for Unsolicited/Passive, False for - 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. - - 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: - - 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: - - 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: - - Unsolicited Publish/Passive Subscribe - - Publisher disables ranging - - Subscriber enables ranging with max such that always within range (large - max) - - 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: - - Solicited Publish/Active Subscribe - - Publisher disables ranging - - Subscriber enables ranging with max such that always within range (large - max) - - 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: - - Unsolicited Publish/Passive Subscribe - - Publisher disables ranging - - Subscriber enables ranging with min such that always out of range (large - min) - - 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: - - Solicited Publish/Active Subscribe - - Publisher disables ranging - - Subscriber enables ranging with min such that always out of range (large - min) - - 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: - - 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: - - 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: - - Unsolicited Publish/Passive Subscribe - - Publisher enables ranging - - Subscriber enables ranging with min/max such that in range (min=0, - 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=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: - - 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: - - Solicited Publish/Active Subscribe - - Publisher enables ranging - - Subscriber enables ranging with min/max such that in range (min=0, - 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=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: - - 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: - - Unsolicited Publish/Passive Subscribe - - Publisher enables ranging - - Subscriber enables ranging with min/max such that out of range (min=large, - max=large+1) - - 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: - - 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: - - 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: - - Solicited Publish/Active Subscribe - - Publisher enables ranging - - Subscriber enables ranging with min/max such that out of range (min=large, - max=large+1) - - 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: - - Unsolicited Publish/Passive Subscribe - - Publisher enables ranging - - Subscriber: - - Starts: Ranging enabled, min/max such that out of range (min=large, - max=large+1) - - Reconfigured to: Ranging enabled, min/max such that in range (min=0, - max=large) - - 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: - - Unsolicited Publish/Passive Subscribe - - Publisher enables ranging - - Subscriber: Ranging enabled, min/max such that out of range (min=large, - max=large+1) - - Reconfigured to: Publisher disables ranging - - 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: - - Unsolicited Publish/Passive Subscribe - - Publisher enables ranging - - Subscriber: - - Starts: Ranging enabled, min/max such that out of range (min=large, - max=large+1) - - Reconfigured to: Ranging disabled - - 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: - - Unsolicited Publish/Passive Subscribe - - Publisher enables ranging - - Subscriber: - - Starts: Ranging enabled, min/max such that out of range (min=large, - max=large+1) - - Reconfigured to: different out-of-range setting - - 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: - - Unsolicited Publish/Passive Subscribe - - Publisher enables ranging - - Subscriber: Ranging enabled, min/max such that out of range (min=large, - max=large+1) - - Reconfigured to: Publisher with same settings (ranging enabled) - - 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: - - Unsolicited Publish/Passive Subscribe - - Publisher enables ranging - - Subscriber: Ranging enabled, min/max such that out of range (min=large, - max=large+1) - - Expect: no discovery - - Reconfigured to: Ranging enabled, min/max such that in-range (min=0) - - Expect: discovery with ranging - - Reconfigured to: Ranging enabled, min/max such that out-of-range - (min=large) - - Expect: no discovery - - 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 - 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) - 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=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()), - 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: - - Solicited Publish/Active Subscribe - - Publisher enables ranging - - Subscriber: - - Starts: Ranging enabled, min/max such that out of range (min=large, - max=large+1) - - Reconfigured to: Ranging enabled, min/max such that in range (min=0, - max=large) - - 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: - - Solicited Publish/Active Subscribe - - Publisher enables ranging - - Subscriber: Ranging enabled, min/max such that out of range (min=large, - max=large+1) - - Reconfigured to: Publisher disables ranging - - 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: - - Solicited Publish/Active Subscribe - - Publisher enables ranging - - Subscriber: - - Starts: Ranging enabled, min/max such that out of range (min=large, - max=large+1) - - Reconfigured to: Ranging disabled - - 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: - - Solicited Publish/Active Subscribe - - Publisher enables ranging - - Subscriber: - - Starts: Ranging enabled, min/max such that out of range (min=large, - max=large+1) - - Reconfigured to: different out-of-range setting - - 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: - - Solicited Publish/Active Subscribe - - Publisher enables ranging - - Subscriber: Ranging enabled, min/max such that out of range (min=large, - max=large+1) - - Reconfigured to: Publisher with same settings (ranging enabled) - - 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: - - Unsolicited Publish/Passive Subscribe - - Publisher enables ranging - - Subscriber: Ranging enabled, min/max such that out of range (min=large, - max=large+1) - - Expect: no discovery - - Reconfigured to: Ranging enabled, min/max such that in-range (min=0) - - Expect: discovery with ranging - - Reconfigured to: Ranging enabled, min/max such that out-of-range - (min=large) - - Expect: no discovery - - 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 - 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) - 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=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()), - 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 - configurations: - - Device A (Publisher): - Publisher AA: ranging enabled - Publisher BB: ranging enabled - Publisher CC: ranging enabled - Publisher DD: ranging disabled - Device B (Subscriber): - Subscriber AA: ranging out-of-range -> no match - Subscriber BB: ranging in-range -> match w/range - 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 - - for those devices that have a concurrency limitation that does not allow - Aware Ranging, whether direct or as part of discovery. - - Publisher: start 3 services - AA w/o ranging - BB w/ ranging - CC w/ ranging - DD w/ ranging - Subscriber: start 2 services - AA w/o ranging - BB w/ ranging out-of-range - (do not start CC!) - DD w/ ranging in-range - Expect AA discovery, DD discovery w/range, but no BB - Start NDP in context of AA - IF NDP_CONCURRENCY_LIMITATION: - Verify discovery on BB w/o range - Start EE w/ranging out-of-range - Start FF w/ranging in-range - IF NDP_CONCURRENCY_LIMITATION: - Verify discovery on EE w/o range - Verify discovery on FF w/o range - Else: - Verify discovery on FF w/ range - Tear down NDP - Subscriber - Start CC w/ ranging out-of-range - Wait to verify that do not get match - 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) - 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 - is restored whenever the concurrency constraints are removed. - - Note: all Subscribers are in-range. - - DUT1: start multiple services - Publish AA w/ ranging (unsolicited) - Subscribe BB w/ ranging (active) - Publish CC w/ ranging (unsolicited) - Publish DD w/o ranging (solicited) - Subscribe EE w/ ranging (passive) - Subscribe FF w/ ranging (active) - DUT2: start multiple services - Subscribe AA w/ ranging (passive) - Publish BB w/ ranging (solicited) - Subscribe DD w/o ranging (active) - Expect - DUT2: AA match w/ range information - DUT1: BB match w/o range information (concurrency disables ranging) - DUT2: DD match w/o range information - DUT1: Terminate AA - DUT2: - Terminate AA - Start Publish EE w/ ranging (unsolicited) - DUT1: expect EE w/o ranging - DUT1: Terminate CC - 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 - as direct ranging to a peer device. - - Process: - - Start YYY service with ranging in-range - - Start XXX service with ranging out-of-range - - Start performing direct Ranging - - While above going on update XXX to be in-range - - 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={"data": stats}) diff --git a/acts/tests/google/wifi/rtt/functional/RangeApMiscTest.py b/acts/tests/google/wifi/rtt/functional/RangeApMiscTest.py deleted file mode 100644 index c68ca92f9f..0000000000 --- a/acts/tests/google/wifi/rtt/functional/RangeApMiscTest.py +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from acts import asserts -from acts.test_utils.wifi import wifi_test_utils as wutils -from acts.test_utils.wifi.rtt import rtt_const as rconsts -from acts.test_utils.wifi.rtt import rtt_test_utils as rutils -from acts.test_utils.wifi.rtt.RttBaseTest import RttBaseTest - - -class RangeApMiscTest(RttBaseTest): - """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 - - # Time gap (in seconds) between iterations - TIME_BETWEEN_ITERATIONS = 0 - - ############################################################################# - - def test_rtt_mixed_80211mc_supporting_aps_wo_privilege(self): - """Scan for APs and perform RTT on one supporting and one non-supporting - IEEE 802.11mc APs with the device not having privilege access (expect - failures).""" - dut = self.android_devices[0] - rutils.config_privilege_override(dut, True) - rtt_aps = rutils.scan_with_rtt_support_constraint(dut, True) - non_rtt_aps = rutils.scan_with_rtt_support_constraint(dut, False) - mix_list = [rtt_aps[0], non_rtt_aps[0]] - dut.log.debug("Visible non-IEEE 802.11mc APs=%s", mix_list) - events = rutils.run_ranging(dut, mix_list, self.NUM_ITER, - self.TIME_BETWEEN_ITERATIONS) - stats = rutils.analyze_results(events, self.rtt_reference_distance_mm, - self.rtt_reference_distance_margin_mm, - self.rtt_min_expected_rssi_dbm, - self.lci_reference, self.lcr_reference) - dut.log.debug("Stats=%s", stats) - - for bssid, stat in stats.items(): - asserts.assert_true( - stat['num_no_results'] == 0, - "Missing (timed-out) results", - extras=stats) - if bssid == rtt_aps[0][wutils.WifiEnums.BSSID_KEY]: - asserts.assert_false( - stat['any_lci_mismatch'], "LCI mismatch", extras=stats) - asserts.assert_false( - stat['any_lcr_mismatch'], "LCR mismatch", extras=stats) - asserts.assert_equal( - stat['num_invalid_rssi'], 0, "Invalid RSSI", extras=stats) - asserts.assert_true( - stat['num_failures'] <= - self.rtt_max_failure_rate_two_sided_rtt_percentage * - stat['num_results'] / 100, - "Failure rate is too high", - extras=stats) - asserts.assert_true( - stat['num_range_out_of_margin'] <= - self.rtt_max_margin_exceeded_rate_two_sided_rtt_percentage - * stat['num_success_results'] / 100, - "Results exceeding error margin rate is too high", - extras=stats) - else: - asserts.assert_true( - stat['num_failures'] == self.NUM_ITER, - "All one-sided RTT requests must fail when executed without privilege", - extras=stats) - for code in stat['status_codes']: - asserts.assert_true( - code == rconsts. - EVENT_CB_RANGING_STATUS_RESPONDER_DOES_NOT_SUPPORT_IEEE80211MC, - "Expected non-support error code", - extras=stats) - asserts.explicit_pass("RTT test done", extras=stats) diff --git a/acts/tests/google/wifi/rtt/functional/RangeApNonSupporting11McTest.py b/acts/tests/google/wifi/rtt/functional/RangeApNonSupporting11McTest.py deleted file mode 100644 index 1ffbb0278d..0000000000 --- a/acts/tests/google/wifi/rtt/functional/RangeApNonSupporting11McTest.py +++ /dev/null @@ -1,177 +0,0 @@ -#!/usr/bin/python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from acts import asserts -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest -from acts.test_utils.wifi.rtt import rtt_const as rconsts -from acts.test_utils.wifi.rtt import rtt_test_utils as rutils -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 - 802.11mc - """ - - # Number of RTT iterations - NUM_ITER = 10 - - # Time gap (in seconds) between iterations - TIME_BETWEEN_ITERATIONS = 0 - - def setup_class(self): - super().setup_class() - if "AccessPoint" in self.user_params: - self.legacy_configure_ap_and_start() - - def run_test_rtt_non_80211mc_supporting_aps(self, dut, accuracy_evaluation=False): - """Scan for APs and perform RTT on non-IEEE 802.11mc supporting APs - Args: - dut: test device - accuracy_evaluation: False - only evaluate success rate. - True - evaluate both success rate and accuracy - default is False. - """ - asserts.skip_if( - not dut.rtt_capabilities[rconsts.CAP_RTT_ONE_SIDED_SUPPORTED], - "Device does not support one-sided RTT") - - non_rtt_aps = rutils.select_best_scan_results( - rutils.scan_with_rtt_support_constraint(dut, False), - select_count=1) - dut.log.debug("Visible non-IEEE 802.11mc APs=%s", non_rtt_aps) - asserts.assert_true(len(non_rtt_aps) > 0, "Need at least one AP!") - events = rutils.run_ranging(dut, non_rtt_aps, self.NUM_ITER, - self.TIME_BETWEEN_ITERATIONS) - stats = rutils.analyze_results(events, self.rtt_reference_distance_mm, - self.rtt_reference_distance_margin_mm, - self.rtt_min_expected_rssi_dbm, - [], []) - dut.log.debug("Stats=%s", stats) - - for bssid, stat in stats.items(): - asserts.assert_true( - stat['num_no_results'] == 0, - "Missing (timed-out) results", - extras=stats) - asserts.assert_false( - stat['any_lci_mismatch'], "LCI mismatch", extras=stats) - asserts.assert_false( - stat['any_lcr_mismatch'], "LCR mismatch", extras=stats) - asserts.assert_equal( - stat['num_invalid_rssi'], 0, "Invalid RSSI", extras=stats) - asserts.assert_true( - stat['num_failures'] <= - self.rtt_max_failure_rate_one_sided_rtt_percentage * - stat['num_results'] / 100, - "Failure rate is too high", - extras=stats) - if accuracy_evaluation: - asserts.assert_true( - stat['num_range_out_of_margin'] <= - self.rtt_max_margin_exceeded_rate_one_sided_rtt_percentage * - stat['num_success_results'] / 100, - "Results exceeding error margin rate is too high", - extras=stats) - asserts.explicit_pass("RTT test done", extras=stats) - - @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, - Functionality test: Only evaluate success rate. - """ - dut = self.android_devices[0] - self.run_test_rtt_non_80211mc_supporting_aps(dut) - - @test_tracker_info(uuid="8fea37f7-0499-4b02-bd33-5ae4d697a4b7") - def test_rtt_non_80211mc_supporting_aps_with_accuracy_evaluation(self): - """Scan for APs and perform RTT on non-IEEE 802.11mc supporting APs, - Performance test: evaluate success rate and accuracy. - """ - dut = self.android_devices[0] - self.run_test_rtt_non_80211mc_supporting_aps(dut, accuracy_evaluation=True) - - @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) - - 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 - Responder config to indicate support and pass-through to service. Verify - that get an error result. - """ - dut = self.android_devices[0] - non_rtt_aps = rutils.select_best_scan_results( - rutils.scan_with_rtt_support_constraint(dut, False), - select_count=1) - dut.log.debug("Visible non-IEEE 802.11mc APs=%s", non_rtt_aps) - asserts.assert_true(len(non_rtt_aps) > 0, "Need at least one AP!") - non_rtt_aps = non_rtt_aps[0:1] # pick first - non_rtt_aps[0][rconsts.SCAN_RESULT_KEY_RTT_RESPONDER] = True # falsify - dut.log.debug("Visible non-IEEE 802.11mc APs=%s", non_rtt_aps) - events = rutils.run_ranging(dut, non_rtt_aps, self.NUM_ITER, - self.TIME_BETWEEN_ITERATIONS) - stats = rutils.analyze_results(events, self.rtt_reference_distance_mm, - self.rtt_reference_distance_margin_mm, - self.rtt_min_expected_rssi_dbm, - self.lci_reference, self.lcr_reference) - dut.log.debug("Stats=%s", stats) - - for bssid, stat in stats.items(): - asserts.assert_true( - stat['num_no_results'] == 0, - "Missing (timed-out) results", - extras=stats) - asserts.assert_true( - stat['num_failures'] == self.NUM_ITER, - "Failures expected for falsified responder config", - extras=stats) - asserts.explicit_pass("RTT test done", extras=stats) diff --git a/acts/tests/google/wifi/rtt/functional/RangeApSupporting11McTest.py b/acts/tests/google/wifi/rtt/functional/RangeApSupporting11McTest.py deleted file mode 100644 index c218898fba..0000000000 --- a/acts/tests/google/wifi/rtt/functional/RangeApSupporting11McTest.py +++ /dev/null @@ -1,329 +0,0 @@ -#!/usr/bin/python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import queue -import time - -from acts import asserts -from acts.test_decorators import test_tracker_info -from acts.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_5G -from acts.test_utils.wifi import wifi_test_utils as wutils -from acts.test_utils.wifi.rtt import rtt_const as rconsts -from acts.test_utils.wifi.rtt import rtt_test_utils as rutils -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 - - # Soft AP SSID - SOFT_AP_SSID = "RTT_TEST_SSID" - - # Soft AP Password (irrelevant) - SOFT_AP_PASSWORD = "ABCDEFGH" - - # Time to wait before configuration changes - WAIT_FOR_CONFIG_CHANGES_SEC = 1 - - def run_test_rtt_80211mc_supporting_aps(self, dut, accuracy_evaluation=False): - """Scan for APs and perform RTT only to those which support 802.11mc - Args: - dut: test device - accuracy_evaluation: False - only evaluate success rate. - True - evaluate both success rate and accuracy - default is False. - """ - rtt_supporting_aps = rutils.select_best_scan_results( - rutils.scan_with_rtt_support_constraint(dut, True, repeat=10), - select_count=2) - dut.log.debug("RTT Supporting APs=%s", rtt_supporting_aps) - events = rutils.run_ranging(dut, rtt_supporting_aps, self.NUM_ITER, - self.TIME_BETWEEN_ITERATIONS) - stats = rutils.analyze_results(events, self.rtt_reference_distance_mm, - self.rtt_reference_distance_margin_mm, - self.rtt_min_expected_rssi_dbm, - self.lci_reference, self.lcr_reference) - dut.log.debug("Stats=%s", stats) - - for bssid, stat in stats.items(): - asserts.assert_true( - stat['num_no_results'] == 0, - "Missing (timed-out) results", - extras=stats) - asserts.assert_false( - stat['any_lci_mismatch'], "LCI mismatch", extras=stats) - asserts.assert_false( - stat['any_lcr_mismatch'], "LCR mismatch", extras=stats) - asserts.assert_false( - stat['invalid_num_attempted'], - "Invalid (0) number of attempts", - extras=stats) - asserts.assert_false( - stat['invalid_num_successful'], - "Invalid (0) number of successes", - extras=stats) - asserts.assert_equal( - stat['num_invalid_rssi'], 0, "Invalid RSSI", extras=stats) - asserts.assert_true( - stat['num_failures'] <= - self.rtt_max_failure_rate_two_sided_rtt_percentage * - stat['num_results'] / 100, - "Failure rate is too high", - extras=stats) - if accuracy_evaluation: - asserts.assert_true( - stat['num_range_out_of_margin'] <= - self.rtt_max_margin_exceeded_rate_two_sided_rtt_percentage * - stat['num_success_results'] / 100, - "Results exceeding error margin rate is too high", - extras=stats) - asserts.explicit_pass("RTT test done", extras=stats) - - @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, - Functionality test: Only evaluate success rate.""" - dut = self.android_devices[0] - self.run_test_rtt_80211mc_supporting_aps(dut) - - @test_tracker_info(uuid="56a8ca4c-b69d-436e-aa80-e86adb6f57d8") - def test_rtt_80211mc_supporting_aps_with_accuracy_evaluation(self): - """Scan for APs and perform RTT only to those which support 802.11mc, - Performance test: evaluate success rate and accuracy.""" - dut = self.android_devices[0] - self.run_test_rtt_80211mc_supporting_aps(dut, accuracy_evaluation=True) - - @test_tracker_info(uuid="eb3fc9f5-ae15-47f5-8468-697bb9aa9ddf") - def test_rtt_in_and_after_softap_mode(self): - """Verify behavior when a SoftAP is enabled and then disabled on the - device: - - - SAP Enabled: depending on device characteristics RTT may succeed or - fail. - - SAP Disabled: RTT must now succeed. - """ - supp_required_params = ("dbs_supported_models", ) - self.unpack_userparams(supp_required_params) - - dut = self.android_devices[0] - - rtt_supporting_aps = rutils.select_best_scan_results( - rutils.scan_with_rtt_support_constraint(dut, True, repeat=10), - select_count=1) - dut.log.debug("RTT Supporting APs=%s", rtt_supporting_aps) - - # phase 1 (pre-SAP) - events = rutils.run_ranging(dut, rtt_supporting_aps, self.NUM_ITER, - self.TIME_BETWEEN_ITERATIONS) - stats = rutils.analyze_results(events, self.rtt_reference_distance_mm, - self.rtt_reference_distance_margin_mm, - self.rtt_min_expected_rssi_dbm, - self.lci_reference, self.lcr_reference) - dut.log.debug("Stats Phase 1 (pre-SAP)=%s", stats) - - for bssid, stat in stats.items(): - asserts.assert_true( - stat['num_no_results'] == 0, - "Phase 1 (pre-SAP) missing (timed-out) results", - extras=stats) - - # phase 2 (SAP) - wutils.start_wifi_tethering( - dut, - self.SOFT_AP_SSID, - self.SOFT_AP_PASSWORD, - band=WIFI_CONFIG_APBAND_5G, - hidden=False) - time.sleep(self.WAIT_FOR_CONFIG_CHANGES_SEC) - - if dut.model not in self.dbs_supported_models: - rutils.wait_for_event(dut, rconsts.BROADCAST_WIFI_RTT_NOT_AVAILABLE) - asserts.assert_false(dut.droid.wifiIsRttAvailable(), - "RTT is available") - - events = rutils.run_ranging(dut, rtt_supporting_aps, self.NUM_ITER, - self.TIME_BETWEEN_ITERATIONS) - stats = rutils.analyze_results(events, self.rtt_reference_distance_mm, - self.rtt_reference_distance_margin_mm, - self.rtt_min_expected_rssi_dbm, - self.lci_reference, self.lcr_reference) - dut.log.debug("Stats Phase 2 (SAP)=%s", stats) - - for bssid, stat in stats.items(): - if dut.model in self.dbs_supported_models: - asserts.assert_true( - stat['num_no_results'] == 0, - "Phase 2 (SAP) missing (timed-out) results", - extras=stats) - else: - asserts.assert_true( - stat['num_success_results'] == 0, - "Phase 2 (SAP) valid results - but unexpected in SAP!?", - extras=stats) - - # phase 3 (post-SAP) - - # enabling Wi-Fi first: on some devices this will also disable SAP - # (that's the scenario we're primarily testing). Additionally, - # explicitly disable SAP (which may be a NOP on some devices). - wutils.wifi_toggle_state(dut, True) - time.sleep(self.WAIT_FOR_CONFIG_CHANGES_SEC) - wutils.stop_wifi_tethering(dut) - - if dut.model not in self.dbs_supported_models: - rutils.wait_for_event(dut, rconsts.BROADCAST_WIFI_RTT_AVAILABLE) - asserts.assert_true(dut.droid.wifiIsRttAvailable(), - "RTT is not available") - - events = rutils.run_ranging(dut, rtt_supporting_aps, self.NUM_ITER, - self.TIME_BETWEEN_ITERATIONS) - stats = rutils.analyze_results(events, self.rtt_reference_distance_mm, - self.rtt_reference_distance_margin_mm, - self.rtt_min_expected_rssi_dbm, - self.lci_reference, self.lcr_reference) - dut.log.debug("Stats Phase 3 (post-SAP)=%s", stats) - - for bssid, stat in stats.items(): - asserts.assert_true( - stat['num_no_results'] == 0, - "Phase 3 (post-SAP) missing (timed-out) results", - extras=stats) - - ######################################################################### - # - # 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. - """ - 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 deleted file mode 100644 index 2e53c6db6a..0000000000 --- a/acts/tests/google/wifi/rtt/functional/RangeAwareTest.py +++ /dev/null @@ -1,499 +0,0 @@ -#!/usr/bin/python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import queue -import time - -from acts import asserts -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi.aware import aware_const as aconsts -from acts.test_utils.wifi.aware import aware_test_utils as autils -from acts.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest -from acts.test_utils.wifi.rtt import rtt_const as rconsts -from acts.test_utils.wifi.rtt import rtt_test_utils as rutils -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" - - # Number of RTT iterations - NUM_ITER = 10 - - # Time gap (in seconds) between iterations - TIME_BETWEEN_ITERATIONS = 0 - - # Time gap (in seconds) when switching between Initiator and Responder - TIME_BETWEEN_ROLES = 4 - - 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) - - 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) - - ############################################################################# - - 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). - - Args: - init_dut: RTT Initiator device - 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) - event_name = rutils.decorate_event(rconsts.EVENT_CB_RANGING_ON_RESULT, - id) - try: - event = init_dut.ed.pop_event(event_name, 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: - self.log.warning("Timed-out waiting for %s", event_name) - 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, - True - perform 2 measurements one in both directions. - iter_count: Number of measurements to perform. - time_between_iterations: Number of seconds to wait between iterations. - time_between_roles: Number of seconds to wait when switching between - Initiator and Responder roles (only matters if - do_both_directions=True). - - Returns: a list of the events containing the RTT results (or None for a - 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. - - Args: - do_both_directions: False - perform all measurements in one direction, - True - perform 2 measurements one in both directions. - iter_count: Number of measurements to perform. - time_between_iterations: Number of seconds to wait between iterations. - time_between_roles: Number of seconds to wait when switching between - Initiator and Responder roles (only matters if - do_both_directions=True). - enable_ranging: True to enable Ranging, False to disable. - - Returns: a list of the events containing the RTT results (or None for a - 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, accuracy_evaluation=False): - """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. - accuracy_evaluation: False - only evaluate success rate. - True - evaluate both success rate and accuracy - default is False. - """ - 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) - if accuracy_evaluation: - 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_reverse_direction['any_lci_mismatch'], "LCI mismatch", extras=extras) - asserts.assert_false( - stats_reverse_direction['any_lcr_mismatch'], "LCR mismatch", extras=extras) - asserts.assert_equal( - stats_reverse_direction['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_reverse_direction['num_results'] / 100, - "Failure rate is too high", - extras=extras) - if accuracy_evaluation: - asserts.assert_true( - stats_reverse_direction['num_range_out_of_margin'] <= - self.rtt_max_margin_exceeded_rate_two_sided_rtt_percentage * - stats_reverse_direction['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. - Functionality test: Only evaluate success rate. - """ - 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. - Functionality test: Only evaluate success rate. - """ - 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. - Functionality test: Only evaluate success rate. - """ - 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. - Functionality test: Only evaluate success rate. - """ - 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="3a1d19a2-7241-49e0-aaf2-0a1da4c29783") - def test_rtt_oob_discovery_one_way_with_accuracy_evaluation(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. - Performance test: evaluate success rate and accuracy. - """ - 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, accuracy_evaluation=True) - - @test_tracker_info(uuid="82f954a5-c0ec-4bc6-8940-3b72199328ac") - def test_rtt_oob_discovery_both_ways_with_accuracy_evaluation(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. - Performance test: evaluate success rate and accuracy. - """ - 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, accuracy_evaluation=True) - - @test_tracker_info(uuid="4194e00c-ea49-488e-b67f-ad9360daa5fa") - def test_rtt_ib_discovery_one_way_with_accuracy_evaluation(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. - Performance test: evaluate success rate and accuracy. - """ - 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, accuracy_evaluation=True) - - @test_tracker_info(uuid="bea3ac8b-756d-4cd8-8936-b8bfe64676c9") - def test_rtt_ib_discovery_both_ways_with_accuracy_evaluation(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. - Performance test: evaluate success rate and accuracy. - """ - 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, accuracy_evaluation=True) - - @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 - 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}) diff --git a/acts/tests/google/wifi/rtt/functional/RangeSoftApTest.py b/acts/tests/google/wifi/rtt/functional/RangeSoftApTest.py deleted file mode 100644 index c23b5b0ed5..0000000000 --- a/acts/tests/google/wifi/rtt/functional/RangeSoftApTest.py +++ /dev/null @@ -1,103 +0,0 @@ -#!/usr/bin/python3.4 -# -# Copyright 2018 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from acts import asserts -from acts.test_decorators import test_tracker_info -from acts.test_utils.tel.tel_test_utils import WIFI_CONFIG_APBAND_5G -from acts.test_utils.wifi import wifi_test_utils as wutils -from acts.test_utils.wifi.rtt import rtt_const as rconsts -from acts.test_utils.wifi.rtt import rtt_test_utils as rutils -from acts.test_utils.wifi.rtt.RttBaseTest import RttBaseTest - - -class RangeSoftApTest(RttBaseTest): - """Test class for RTT ranging to an Android Soft AP.""" - - # Soft AP SSID - SOFT_AP_SSID = "RTT_TEST_SSID" - - # Soft AP Password (irrelevant) - SOFT_AP_PASSWORD = "ABCDEFGH" - - # Number of RTT iterations - NUM_ITER = 10 - - ######################################################################### - - @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) diff --git a/acts/tests/google/wifi/rtt/functional/RttDisableTest.py b/acts/tests/google/wifi/rtt/functional/RttDisableTest.py deleted file mode 100644 index 635837c950..0000000000 --- a/acts/tests/google/wifi/rtt/functional/RttDisableTest.py +++ /dev/null @@ -1,113 +0,0 @@ -#!/usr/bin/python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from acts import asserts -from acts import utils -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi.rtt import rtt_const as rconsts -from acts.test_utils.wifi.rtt import rtt_test_utils as rutils -from acts.test_utils.wifi.rtt.RttBaseTest import RttBaseTest -from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest - - -class RttDisableTest(WifiBaseTest, RttBaseTest): - """Test class for RTT ranging enable/disable flows.""" - - MODE_DISABLE_WIFI = 0 - MODE_ENABLE_DOZE = 1 - MODE_DISABLE_LOCATIONING = 2 - - def setup_class(self): - super().setup_class() - 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 - 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 - any range requests are rejected.""" - 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 - mode and that any range requests are rejected.""" - 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 - that any range requests are rejected.""" - 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 deleted file mode 100644 index c91521df0d..0000000000 --- a/acts/tests/google/wifi/rtt/functional/RttRequestManagementTest.py +++ /dev/null @@ -1,146 +0,0 @@ -#!/usr/bin/python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import random -import time - -from acts import asserts -from acts.test_decorators import test_tracker_info -from acts.test_utils.wifi.rtt import rtt_const as rconsts -from acts.test_utils.wifi.rtt import rtt_test_utils as rutils -from acts.test_utils.wifi.rtt.RttBaseTest import RttBaseTest - - -class RttRequestManagementTest(RttBaseTest): - """Test class for RTT request management flows.""" - - SPAMMING_LIMIT = 20 - - ############################################################################# - - @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 - was already finished and it's results dispatched back. The test therefore - stacks the request queue. The sequence is: - - - Request: - - 50 tests @ UIDs = {uid1, uid2, uid3} - - 2 tests @ UIDs = {uid2, uid3} - - 1 test2 @ UIDs = {uid1, uid2, uid3} - - Cancel UIDs = {uid2, uid3} - - Expect to receive only 51 results. - """ - dut = self.android_devices[0] - max_peers = dut.droid.wifiRttMaxPeersInRequest() - - all_uids = [1000, 20, - 30] # 1000 = System Server (makes requests foreground) - some_uids = [20, 30] - - aps = rutils.select_best_scan_results( - rutils.scan_with_rtt_support_constraint(dut, True, repeat=10), - select_count=1) - dut.log.info("RTT Supporting APs=%s", aps) - - asserts.assert_true( - len(aps) > 0, "Need at least one AP which supports 802.11mc!") - if len(aps) > max_peers: - aps = aps[0:max_peers] - - group1_ids = [] - group2_ids = [] - group3_ids = [] - - # step 1: request <spam_limit> ranging operations on [uid1, uid2, uid3] - for i in range(self.SPAMMING_LIMIT): - group1_ids.append( - dut.droid.wifiRttStartRangingToAccessPoints(aps, all_uids)) - - # step 2: request 2 ranging operations on [uid2, uid3] - for i in range(2): - group2_ids.append( - dut.droid.wifiRttStartRangingToAccessPoints(aps, some_uids)) - - # step 3: request 1 ranging operation on [uid1, uid2, uid3] - for i in range(1): - group3_ids.append( - dut.droid.wifiRttStartRangingToAccessPoints(aps, all_uids)) - - # step 4: cancel ranging requests on [uid2, uid3] - dut.droid.wifiRttCancelRanging(some_uids) - - # collect results - for i in range(len(group1_ids)): - rutils.wait_for_event( - dut, - rutils.decorate_event(rconsts.EVENT_CB_RANGING_ON_RESULT, - group1_ids[i])) - time.sleep( - rutils.EVENT_TIMEOUT) # optimize time-outs below to single one - for i in range(len(group2_ids)): - rutils.fail_on_event( - dut, - rutils.decorate_event(rconsts.EVENT_CB_RANGING_ON_RESULT, - group2_ids[i]), 0) - for i in range(len(group3_ids)): - rutils.wait_for_event( - dut, - rutils.decorate_event(rconsts.EVENT_CB_RANGING_ON_RESULT, - group3_ids[i])) - - @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)) diff --git a/acts/tests/google/wifi/rtt/stress/StressRangeApTest.py b/acts/tests/google/wifi/rtt/stress/StressRangeApTest.py deleted file mode 100644 index d0e9fe9bb6..0000000000 --- a/acts/tests/google/wifi/rtt/stress/StressRangeApTest.py +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/python3.4 -# -# Copyright 2017 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from acts import asserts -from acts.base_test import BaseTestClass -from acts.test_utils.wifi.rtt import rtt_test_utils as rutils -from acts.test_utils.wifi.rtt.RttBaseTest import RttBaseTest - - -class StressRangeApTest(RttBaseTest): - """Test class for stress testing of RTT ranging to Access Points""" - - ############################################################################# - - def test_rtt_supporting_ap_only(self): - """Scan for APs and perform RTT only to those which support 802.11mc. - - Stress test: repeat ranging to the same AP. Verify rate of success and - stability of results. - """ - dut = self.android_devices[0] - rtt_supporting_aps = rutils.scan_with_rtt_support_constraint( - dut, True, repeat=10) - dut.log.debug("RTT Supporting APs=%s", rtt_supporting_aps) - - num_iter = self.stress_test_min_iteration_count - - max_peers = dut.droid.wifiRttMaxPeersInRequest() - asserts.assert_true( - len(rtt_supporting_aps) > 0, - "Need at least one AP which supports 802.11mc!") - if len(rtt_supporting_aps) > max_peers: - rtt_supporting_aps = rtt_supporting_aps[0:max_peers] - - events = rutils.run_ranging(dut, rtt_supporting_aps, num_iter, 0, - self.stress_test_target_run_time_sec) - stats = rutils.analyze_results( - events, - self.rtt_reference_distance_mm, - self.rtt_reference_distance_margin_mm, - self.rtt_min_expected_rssi_dbm, - self.lci_reference, - self.lcr_reference, - summary_only=True) - dut.log.debug("Stats=%s", stats) - - for bssid, stat in stats.items(): - asserts.assert_true( - stat['num_no_results'] == 0, - "Missing (timed-out) results", - extras=stats) - asserts.assert_false( - stat['any_lci_mismatch'], "LCI mismatch", extras=stats) - asserts.assert_false( - stat['any_lcr_mismatch'], "LCR mismatch", extras=stats) - asserts.assert_equal( - stat['num_invalid_rssi'], 0, "Invalid RSSI", extras=stats) - asserts.assert_true( - stat['num_failures'] <= - self.rtt_max_failure_rate_two_sided_rtt_percentage * - stat['num_results'] / 100, - "Failure rate is too high", - extras=stats) - asserts.assert_true( - stat['num_range_out_of_margin'] <= - self.rtt_max_margin_exceeded_rate_two_sided_rtt_percentage * - stat['num_success_results'] / 100, - "Results exceeding error margin rate is too high", - extras=stats) - asserts.explicit_pass("RTT test done", extras=stats) diff --git a/acts/tests/google/wifi/rtt/stress/StressRangeAwareTest.py b/acts/tests/google/wifi/rtt/stress/StressRangeAwareTest.py deleted file mode 100644 index ccf8b9d0c5..0000000000 --- a/acts/tests/google/wifi/rtt/stress/StressRangeAwareTest.py +++ /dev/null @@ -1,147 +0,0 @@ -#!/usr/bin/python3.4 -# -# Copyright 2018 - The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import queue -import time - -from acts import asserts -from acts.test_utils.wifi.aware import aware_const as aconsts -from acts.test_utils.wifi.aware import aware_test_utils as autils -from acts.test_utils.wifi.aware.AwareBaseTest import AwareBaseTest -from acts.test_utils.wifi.rtt import rtt_const as rconsts -from acts.test_utils.wifi.rtt import rtt_test_utils as rutils -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" - - 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) - - 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) - - ############################################################################# - - 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). - - Args: - init_dut: RTT Initiator device - 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 - 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) |